Class: EBNF::LL1::Scanner

Inherits:
StringScanner
  • Object
show all
Defined in:
lib/ebnf/ll1/scanner.rb

Overview

Overload StringScanner with file operations

  • Reloads scanner as required until EOF.

  • Loads to a high-water and reloads when remaining size reaches a low-water.

FIXME: Only implements the subset required by the Lexer for now.

Constant Summary collapse

HIGH_WATER =
10240
LOW_WATER =

Hopefully large enough to deal with long multi-line comments

2048

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(input, options = {}) ⇒ Scanner

Create a scanner, from an IO or String

Parameters:

  • input (String, IO, #read)
  • options (Hash{Symbol => Object}) (defaults to: {})
  • options[Integer] (Hash)

    a customizable set of options



27
28
29
30
31
32
33
34
35
36
37
# File 'lib/ebnf/ll1/scanner.rb', line 27

def initialize(input, options = {})
  @options = options.merge(:high_water => HIGH_WATER, :low_water => LOW_WATER)

  if input.respond_to?(:read)
    @input = input
    super("")
    feed_me
  else
    super(input.to_s)
  end
end

Instance Attribute Details

#inputIO, StringIO (readonly)

Returns:

  • (IO, StringIO)


17
18
19
# File 'lib/ebnf/ll1/scanner.rb', line 17

def input
  @input
end

Instance Method Details

#restString

Returns the “rest” of the line, or the next line if at EOL (i.e. everything after the scan pointer). If there is no more data (eos? = true), it returns “”.

Returns:

  • (String)


44
45
46
47
# File 'lib/ebnf/ll1/scanner.rb', line 44

def rest
  feed_me
  encode_utf8 super
end

#scan(pattern) ⇒ String

Tries to match with pattern at the current position.

If there is a match, the scanner advances the “scan pointer” and returns the matched string. Otherwise, the scanner returns nil.

If the scanner begins with the multi-line start expression

Examples:

s = StringScanner.new('test string')
p s.scan(/\w+/)   # -> "test"
p s.scan(/\w+/)   # -> nil
p s.scan(/\s+/)   # -> " "
p s.scan(/\w+/)   # -> "string"
p s.scan(/./)     # -> nil

Parameters:

  • pattern (Regexp)

Returns:

  • (String)


78
79
80
81
# File 'lib/ebnf/ll1/scanner.rb', line 78

def scan(pattern)
  feed_me
  encode_utf8 super
end

#skip(pattern) ⇒ Object

Attempts to skip over the given pattern beginning with the scan pointer. If it matches, the scan pointer is advanced to the end of the match, and the length of the match is returned. Otherwise, nil is returned.

similar to scan, but without returning the matched string.

Parameters:

  • pattern (Regexp)


56
57
58
59
# File 'lib/ebnf/ll1/scanner.rb', line 56

def skip(pattern)
  feed_me
  super
end