class KPeg::CompiledParser
Attributes
failed_rule[R]
failing_rule_offset[R]
pos[RW]
result[RW]
string[R]
Public Class Methods
new(str, debug=false)
click to toggle source
This is distinct from setup_parser
so that a standalone parser can redefine initialize and still have access to the proper parser setup code.
# File lib/kpeg/compiled_parser.rb, line 19 def initialize(str, debug=false) setup_parser(str, debug) end
rule_info(name, rendered)
click to toggle source
# File lib/kpeg/compiled_parser.rb, line 327 def self.rule_info(name, rendered) RuleInfo.new(name, rendered) end
Public Instance Methods
apply(rule)
click to toggle source
# File lib/kpeg/compiled_parser.rb, line 263 def apply(rule) @result = nil if m = @memoizations[rule][@pos] @pos = m.pos if !m.set m.left_rec = true return nil end @result = m.result return m.ans else m = MemoEntry.new(nil, @pos) @memoizations[rule][@pos] = m start_pos = @pos ans = __send__ rule lr = m.left_rec m.move! ans, @pos, @result # Don't bother trying to grow the left recursion # if it's failing straight away (thus there is no seed) if ans and lr return grow_lr(rule, nil, start_pos, m) else return ans end end end
apply_with_args(rule, *args)
click to toggle source
# File lib/kpeg/compiled_parser.rb, line 229 def apply_with_args(rule, *args) @result = nil memo_key = [rule, args] if m = @memoizations[memo_key][@pos] @pos = m.pos if !m.set m.left_rec = true return nil end @result = m.result return m.ans else m = MemoEntry.new(nil, @pos) @memoizations[memo_key][@pos] = m start_pos = @pos ans = __send__ rule, *args lr = m.left_rec m.move! ans, @pos, @result # Don't bother trying to grow the left recursion # if it's failing straight away (thus there is no seed) if ans and lr return grow_lr(rule, args, start_pos, m) else return ans end end end
external_invoke(other, rule, *args)
click to toggle source
# File lib/kpeg/compiled_parser.rb, line 210 def external_invoke(other, rule, *args) old_pos = @pos old_string = @string set_string other.string, other.pos begin if val = __send__(rule, *args) other.pos = @pos other.result = @result else other.set_failed_rule "#{self.class}##{rule}" end val ensure set_string old_string, old_pos end end
failure_caret()
click to toggle source
# File lib/kpeg/compiled_parser.rb, line 79 def failure_caret p = current_pos_info @failing_rule_offset "#{p.line.chomp}\n#{' ' * (p.col - 1)}^" end
failure_character()
click to toggle source
# File lib/kpeg/compiled_parser.rb, line 84 def failure_character current_character @failing_rule_offset end
failure_info()
click to toggle source
# File lib/kpeg/compiled_parser.rb, line 67 def failure_info l = current_line @failing_rule_offset c = current_column @failing_rule_offset if @failed_rule.kind_of? Symbol info = self.class::Rules[@failed_rule] "line #{l}, column #{c}: failed rule '#{info.name}' = '#{info.rendered}'" else "line #{l}, column #{c}: failed rule '#{@failed_rule}'" end end
failure_oneline()
click to toggle source
# File lib/kpeg/compiled_parser.rb, line 88 def failure_oneline p = current_pos_info @failing_rule_offset if @failed_rule.kind_of? Symbol info = self.class::Rules[@failed_rule] "@#{p.lno}:#{p.col} failed rule '#{info.name}', got '#{p.char}'" else "@#{p.lno}:#{p.col} failed rule '#{@failed_rule}', got '#{p.char}'" end end
get_byte()
click to toggle source
# File lib/kpeg/compiled_parser.rb, line 154 def get_byte if @pos >= @string_size return nil end s = @string[@pos].ord @pos += 1 s end
get_text(start)
click to toggle source
# File lib/kpeg/compiled_parser.rb, line 46 def get_text(start) @string[start..@pos-1] end
grow_lr(rule, args, start_pos, m)
click to toggle source
# File lib/kpeg/compiled_parser.rb, line 296 def grow_lr(rule, args, start_pos, m) while true @pos = start_pos @result = m.result if args ans = __send__ rule, *args else ans = __send__ rule end return nil unless ans break if @pos <= m.pos m.move! ans, @pos, @result end @result = m.result @pos = m.pos return m.ans end
match_string(str)
click to toggle source
# File lib/kpeg/compiled_parser.rb, line 134 def match_string(str) len = str.size if @string[pos,len] == str @pos += len return str end return nil end
parse(rule=nil)
click to toggle source
# File lib/kpeg/compiled_parser.rb, line 175 def parse(rule=nil) # We invoke the rules indirectly via apply # instead of by just calling them as methods because # if the rules use left recursion, apply needs to # manage that. if !rule apply(:_root) else method = rule.gsub("-","_hyphen_") apply :"_#{method}" end end
raise_error()
click to toggle source
# File lib/kpeg/compiled_parser.rb, line 102 def raise_error raise ParseError, failure_oneline end
scan(reg)
click to toggle source
# File lib/kpeg/compiled_parser.rb, line 144 def scan(reg) if m = reg.match(@string, @pos) @pos = m.end(0) return true end return nil end
set_failed_rule(name)
click to toggle source
# File lib/kpeg/compiled_parser.rb, line 125 def set_failed_rule(name) if @pos > @failing_rule_offset @failed_rule = name @failing_rule_offset = @pos end end
set_string(string, pos)
click to toggle source
Sets the string and current parsing position for the parser.
# File lib/kpeg/compiled_parser.rb, line 51 def set_string string, pos @string = string @string_size = string ? string.size : 0 @pos = pos @position_line_offsets = nil end
setup_foreign_grammar()
click to toggle source
Must be outside the STANDALONE block because a standalone parser always injects it’s own version of this method.
# File lib/kpeg/compiled_parser.rb, line 8 def setup_foreign_grammar end
setup_parser(str, debug=false)
click to toggle source
Prepares for parsing str
. If you define a custom initialize you must call this method before parse
# File lib/kpeg/compiled_parser.rb, line 29 def setup_parser(str, debug=false) set_string str, 0 @memoizations = Hash.new { |h,k| h[k] = {} } @result = nil @failed_rule = nil @failing_rule_offset = -1 @line_offsets = nil setup_foreign_grammar end
show_error(io=STDOUT)
click to toggle source
# File lib/kpeg/compiled_parser.rb, line 106 def show_error(io=STDOUT) error_pos = @failing_rule_offset p = current_pos_info(error_pos) io.puts "On line #{p.lno}, column #{p.col}:" if @failed_rule.kind_of? Symbol info = self.class::Rules[@failed_rule] io.puts "Failed to match '#{info.rendered}' (rule '#{info.name}')" else io.puts "Failed to match rule '#{@failed_rule}'" end io.puts "Got: #{p.char.inspect}" io.puts "=> #{p.line}" io.print(" " * (p.col + 2)) io.puts "^" end
show_pos()
click to toggle source
# File lib/kpeg/compiled_parser.rb, line 58 def show_pos width = 10 if @pos < width "#{@pos} (\"#{@string[0,@pos]}\" @ \"#{@string[@pos,width]}\")" else "#{@pos} (\"... #{@string[@pos - width, width]}\" @ \"#{@string[@pos,width]}\")" end end