lib/liquidscript/scanner/base/lexer.rb
module Liquidscript
module Scanner
class Base
module Lexer
def perform_with_context(context, scanner = @scanner)
key, value = context.find_matcher(scanner)
if value.nil? && scanner.rest?
error scanner, context
end
normalize_action key, value, scanner if scanner.rest?
end
def lex(*args)
args.flatten!
to_lex = args.pop
context, body = if to_lex.is_a? Hash
to_lex.to_a.first
else
[to_lex, nil]
end
scanner = if body
StringScanner.new(body)
else
@scanner
end
out = []
context = find_context(context)
instance_exec(*args, &context.init)
while scanner.rest? && out.last != EXIT
out << perform_with_context(context, scanner)
end
out
end
def error(scanner = @scanner, context = @context,
file = @metadata[:file])
raise SyntaxError, "Unexpected " +
"#{scanner.matched}#{scanner.peek(2)}".inspect +
" (line: #{line}, column: #{column}, file: #{file})"
end
private
def find_context(name)
context = contexts.dup.keep_if { |c|
c.name == name
}.to_a.first
if context.nil?
raise NoContextError.new(name)
end
context
end
def exit
EXIT
end
def normalize_action(key, value, scanner)
body = scanner.scan(key)
case value
when Proc
instance_exec(*body.match(key), &value)
when Symbol
lex(*body.match(key), value)
when EXIT
EXIT
end
end
end
end
end
end