class KPeg::Parser
Attributes
failing_offset[R]
failing_op[RW]
grammar[R]
memoizations[R]
Public Class Methods
new(str, grammar, log=false)
click to toggle source
Calls superclass method
# File lib/kpeg/parser.rb, line 5 def initialize(str, grammar, log=false) super str @grammar = grammar # A 2 level hash. @memoizations = Hash.new { |h,k| h[k] = {} } @failing_offset = nil @failing_op = nil @log = log end
Public Instance Methods
apply(rule)
click to toggle source
# File lib/kpeg/parser.rb, line 81 def apply(rule) ans = nil if m = @memoizations[rule][pos] m.inc! self.pos = m.pos if m.ans.kind_of? LeftRecursive m.ans.detected = true if @log puts "LR #{rule.name} @ #{self.inspect}" end return nil end ans = m.ans else lr = LeftRecursive.new(false) m = MemoEntry.new(lr, pos) @memoizations[rule][pos] = m start_pos = pos if @log puts "START #{rule.name} @ #{self.inspect}" end ans = rule.op.match(self) m.move! ans, pos # Don't bother trying to grow the left recursion # if it's failing straight away (thus there is no seed) if ans and lr.detected ans = grow_lr(rule, start_pos, m) end end if @log if ans puts " OK #{rule.name} @ #{self.inspect}" else puts " FAIL #{rule.name} @ #{self.inspect}" end end return ans end
expectation()
click to toggle source
# File lib/kpeg/parser.rb, line 165 def expectation error_pos = @failing_offset line_no = current_line(error_pos) col_no = current_column(error_pos) expected = expected_string() prefix = nil case expected when String prefix = expected.inspect when Range prefix = "to be between #{expected.begin} and #{expected.end}" when Array prefix = "to be one of #{expected.inspect}" when nil prefix = "anything (no more input)" else prefix = "unknown" end return "Expected #{prefix} at line #{line_no}, column #{col_no} (offset #{error_pos})" end
expected_string()
click to toggle source
# File lib/kpeg/parser.rb, line 38 def expected_string case @failing_op when Choice return Range.new(@failing_op.start, @failing_op.fin) when Dot return nil else @failing_op.string end end
fail(op)
click to toggle source
# File lib/kpeg/parser.rb, line 32 def fail(op) @failing_offset = pos @failing_op = op return nil end
failed?()
click to toggle source
# File lib/kpeg/parser.rb, line 142 def failed? !!@failing_op end
grow_lr(rule, start_pos, m)
click to toggle source
# File lib/kpeg/parser.rb, line 127 def grow_lr(rule, start_pos, m) while true self.pos = start_pos ans = rule.op.match(self) return nil unless ans break if pos <= m.pos m.move! ans, pos end self.pos = m.pos return m.ans end
invoke(rule)
click to toggle source
Call a rule without memoization
# File lib/kpeg/parser.rb, line 77 def invoke(rule) rule.op.match(self) end
parse(name=nil)
click to toggle source
# File lib/kpeg/parser.rb, line 146 def parse(name=nil) if name rule = @grammar.find(name) unless rule raise "Unknown rule - #{name}" end else rule = @grammar.root end match = apply rule if pos == string.size @failing_op = nil end return match end
switch_grammar(gram) { || ... }
click to toggle source
# File lib/kpeg/parser.rb, line 22 def switch_grammar(gram) begin old = @grammar @grammar = gram yield ensure @grammar = old end end