62 lines
1.7 KiB
Ruby
62 lines
1.7 KiB
Ruby
|
|
||
|
# @api private
|
||
|
module Parslet::Accelerator
|
||
|
class Application
|
||
|
def initialize atom, rules
|
||
|
@atom = atom
|
||
|
@rules = rules
|
||
|
end
|
||
|
|
||
|
def call
|
||
|
@atom.accept(self)
|
||
|
end
|
||
|
|
||
|
def visit_parser(root)
|
||
|
transform root.accept(self)
|
||
|
end
|
||
|
def visit_entity(name, block)
|
||
|
transform Parslet::Atoms::Entity.new(name) { block.call.accept(self) }
|
||
|
end
|
||
|
def visit_named(name, atom)
|
||
|
transform Parslet::Atoms::Named.new(atom.accept(self), name)
|
||
|
end
|
||
|
def visit_repetition(tag, min, max, atom)
|
||
|
transform Parslet::Atoms::Repetition.new(atom.accept(self), min, max, tag)
|
||
|
end
|
||
|
def visit_alternative(alternatives)
|
||
|
transform Parslet::Atoms::Alternative.new(
|
||
|
*alternatives.map { |atom| atom.accept(self) })
|
||
|
end
|
||
|
def visit_sequence(sequence)
|
||
|
transform Parslet::Atoms::Sequence.new(
|
||
|
*sequence.map { |atom| atom.accept(self) })
|
||
|
end
|
||
|
def visit_lookahead(positive, atom)
|
||
|
transform Parslet::Atoms::Lookahead.new(atom, positive)
|
||
|
end
|
||
|
def visit_re(regexp)
|
||
|
transform Parslet::Atoms::Re.new(regexp)
|
||
|
end
|
||
|
def visit_str(str)
|
||
|
transform Parslet::Atoms::Str.new(str)
|
||
|
end
|
||
|
|
||
|
def transform atom
|
||
|
@rules.each do |expr, action|
|
||
|
# Try and match each rule in turn
|
||
|
binding = Parslet::Accelerator.match(atom, expr)
|
||
|
if binding
|
||
|
# On a successful match, allow the rule action to transform the
|
||
|
# parslet into something new.
|
||
|
ctx = Parslet::Context.new(binding)
|
||
|
return ctx.instance_eval(&action)
|
||
|
end
|
||
|
end # rules.each
|
||
|
|
||
|
# If no rule matches, this is the fallback - a clean new parslet atom.
|
||
|
return atom
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
require 'parslet/context'
|