class Take::Unit::Scanner
Attributes
tokens[R]
Public Class Methods
new(input)
click to toggle source
# File lib/take/unit/scanner.rb, line 9 def initialize(input) @input = "\n" << input @scanner = StringScanner.new(input) end
Public Instance Methods
scan()
click to toggle source
# File lib/take/unit/scanner.rb, line 14 def scan @tokens ||= begin @tokens = [] until @scanner.eos? scan_group_body { error! } end @tokens end end
scan_body()
click to toggle source
# File lib/take/unit/scanner.rb, line 64 def scan_body if @scanner.check(/\s*\{/) emit :block, _scan_block end end
scan_group(scan = /macro|test|before|after|prefix/)
click to toggle source
# File lib/take/unit/scanner.rb, line 50 def scan_group(scan = /macro|test|before|after|prefix/) if @scanner.scan(scan) group_type = @scanner[0] @scanner.scan(/ ([A-Za-z0-9_.-]+)\(/) or error! group_name = @scanner[1] @scanner.scan(/\s*\;/) emit group_type.intern, group_name, _scan_arguments(/\s*\)/, /,\s+/) end end
scan_group_body() { || ... }
click to toggle source
# File lib/take/unit/scanner.rb, line 24 def scan_group_body pre_scan scan_nested or scan_group or scan_body or scan_whitespace or yield end
scan_nested()
click to toggle source
# File lib/take/unit/scanner.rb, line 33 def scan_nested if scan_group(/group/) scan_whitespace @scanner.scan(/\{/) or error! loop do scan_group_body do if @scanner.scan(/\}/) pre_scan return emit(:group_end) else error! end end end end end
scan_whitespace(newlines = true)
click to toggle source
# File lib/take/unit/scanner.rb, line 70 def scan_whitespace(newlines = true) if newlines @scanner.scan(/\s+/) else @scanner.scan(/[ \t]+/) end end
Private Instance Methods
_scan_arguments(ending, seperator)
click to toggle source
# File lib/take/unit/scanner.rb, line 132 def _scan_arguments(ending, seperator) arguments = [] until @scanner.scan(ending) @scanner.scan(/(&?[A-Za-z0-9_-]+)/) arguments << @scanner[1] @scanner.scan(seperator) or @scanner.check(ending) or error! end arguments end
_scan_block()
click to toggle source
# File lib/take/unit/scanner.rb, line 98 def _scan_block brack = 1 body = @scanner.scan(/\s*\{/) scan_for = %r{ ( (?: " ( \\\\ | \\" | [^"] )* "? ) | (?: ' ( \\\\ | \\' | [^'] )* '? ) | (?: // .*? \n ) | (?: \# .*? \n ) | (?: /\* [\s\S]+? \*/ ) | (?: \} ) | (?: \{ ) ) }x until brack.zero? if part = @scanner.scan_until(scan_for) body << part if @scanner[1] == "}" brack -= 1 elsif @scanner[1] == "{" brack += 1 end else @scanner.scan(/(.+)/m) error! end end body.gsub(/\A\n*/, "").gsub(/\A\s*\{([\s\S]*)\}\z/, "\\1") end
column()
click to toggle source
# File lib/take/unit/scanner.rb, line 88 def column last_newline = @input[0..@pos].rindex("\n") || 0 @pos - last_newline end
emit(*args)
click to toggle source
# File lib/take/unit/scanner.rb, line 93 def emit(*args) @tokens << args.concat([line, column]) true end
error!()
click to toggle source
# File lib/take/unit/scanner.rb, line 143 def error! p @tokens raise SyntaxError, "Unexpected `#{@scanner.check(/./)}' on line #{line} (column #{column})" end
line()
click to toggle source
# File lib/take/unit/scanner.rb, line 84 def line @input[0..@pos].count("\n") end
pre_scan()
click to toggle source
# File lib/take/unit/scanner.rb, line 80 def pre_scan @pos = @scanner.pos end