class Citrus::Input

An Input is a scanner that is responsible for executing rules at different positions in the input string and persisting event streams.

Attributes

max_offset[R]

The maximum offset in the input that was successfully parsed.

source[R]

The initial source passed at construction. Typically a String or a Pathname.

Public Class Methods

new(source) click to toggle source
Calls superclass method
# File lib/citrus.rb, line 172
def initialize(source)
  super(source_text(source))
  @source = source
  @max_offset = 0
end

Public Instance Methods

exec(rule, events=[]) click to toggle source

Returns an array of events for the given rule at the current pointer position. Objects in this array may be one of three types: a Rule, Citrus::CLOSE, or a length (integer).

# File lib/citrus.rb, line 245
def exec(rule, events=[])
  position = pos
  index = events.size

  if apply_rule(rule, position, events).size > index
    @max_offset = pos if pos > @max_offset
  else
    self.pos = position
  end

  events
end
line(pos=pos()) click to toggle source

Returns the text of the line that contains the character at the given pos. pos defaults to the current pointer position.

# File lib/citrus.rb, line 233
def line(pos=pos())
  lines[line_index(pos)]
end
line_index(pos=pos()) click to toggle source

Returns the 0-based number of the line that contains the character at the given pos. pos defaults to the current pointer position.

# File lib/citrus.rb, line 213
def line_index(pos=pos())
  p = n = 0
  string.each_line do |line|
    p += line.length
    return n if p >= pos
    n += 1
  end
  0
end
line_number(pos=pos()) click to toggle source

Returns the 1-based number of the line that contains the character at the given pos. pos defaults to the current pointer position.

# File lib/citrus.rb, line 225
def line_number(pos=pos())
  line_index(pos) + 1
end
Also aliased as: lineno
line_offset(pos=pos()) click to toggle source

Returns the 0-based offset of the given pos in the input on the line on which it is found. pos defaults to the current pointer position.

# File lib/citrus.rb, line 201
def line_offset(pos=pos())
  p = 0
  string.each_line do |line|
    len = line.length
    return (pos - p) if p + len >= pos
    p += len
  end
  0
end
lineno(pos=pos())
Alias for: line_number
lines() click to toggle source

Returns an array containing the lines of text in the input.

# File lib/citrus.rb, line 191
def lines
  if string.respond_to?(:lines)
    string.lines.to_a
  else
    string.to_a
  end
end
memoized?() click to toggle source

Returns true when using memoization to cache match results.

# File lib/citrus.rb, line 238
def memoized?
  false
end
test(rule) click to toggle source

Returns the length of a match for the given rule at the current pointer position, nil if none can be made.

# File lib/citrus.rb, line 260
def test(rule)
  position = pos
  events = apply_rule(rule, position, [])
  self.pos = position
  events[-1]
end

Private Instance Methods

apply_rule(rule, position, events) click to toggle source

Appends all events for rule at the given position to events.

# File lib/citrus.rb, line 286
def apply_rule(rule, position, events)
  rule.exec(self, events)
end
source_text(source) click to toggle source

Returns the text to parse from source.

# File lib/citrus.rb, line 273
def source_text(source)
  if source.respond_to?(:to_path)
    ::File.read(source.to_path)
  elsif source.respond_to?(:read)
    source.read
  elsif source.respond_to?(:to_str)
    source.to_str
  else
    raise ArgumentError, "Unable to parse from #{source}", caller
  end
end