class PegLite
Constants
- VERSION
Attributes
debug[RW]
got[RW]
input[RW]
wrap[RW]
Public Class Methods
new(attrs={}) { |self| ... }
click to toggle source
# File lib/peglite.rb, line 53 def initialize attrs={} @got = nil @wrap = false @debug = false @input = nil attrs.each { |k,v| self.send "#{k}=", v } @pos = 0 @far = 0 yield self if block_given? end
rule(args)
click to toggle source
# File lib/peglite.rb, line 12 def self.rule args name, rule = args.first name = name.to_s $PegLiteTopRule ||= name if rule.kind_of? Regexp regex = Regexp.new(rule.to_s.sub(/:/, ':\\A')) rule = { 'type' => 'rgx', 'rule' => regex, 'min' => 1, 'max' => 1, } elsif rule.kind_of? String rule = PegLite::Compiler.new(rule).compile else fail "Don't know how to make rule '#{name}' from '#{rule}'" end self.send :define_method, "rule_#{name}" do match rule end end
Public Instance Methods
failure()
click to toggle source
# File lib/peglite.rb, line 173 def failure msg = "Parse failed for some reason" raise PegexParseError, format_error(msg) end
format_error(msg)
click to toggle source
# File lib/peglite.rb, line 179 def format_error msg buffer = @input position = @far real_pos = @pos line = buffer[0, position].scan(/\n/).size + 1 column = position - (buffer.rindex("\n", position) || -1) pretext = @input[ position < 50 ? 0 : position - 50, position < 50 ? position : 50 ] context = @input[position, 50] pretext.gsub! /.*\n/m, '' context.gsub! /\n/, "\\n" return <<"..." Error parsing Pegex document: message: #{msg} line: #{line} column: #{column} position: #{position} context: #{pretext}#{context} #{' ' * (pretext.length + 10)}^ ... end
match(rule=nil)
click to toggle source
# File lib/peglite.rb, line 75 def match rule=nil if not rule.kind_of? Hash rule ||= caller.first.scan(/(\w+)/).last.first method_name = "rule_#{rule}" return send method_name if respond_to? method_name fail "Can't find rule for '#{rule}'" end pos, count, matched, type, child, min, max = @pos, 0, [], *(rule.values_at *%w(type rule min max)) while (result = self.method("match_#{type}").call(child)) pos = @pos count += 1 if result.kind_of? Array matched.concat result else matched << result end break if max == 1 end if count >= min and (max == 0 or count <= max) return matched else @pos = pos return end end
match_all(all)
click to toggle source
# File lib/peglite.rb, line 105 def match_all all pos, set, count = @pos, [], 0 all.each do |elem| if (m = match elem) set.concat m count += 1 else if (@pos = pos) > @far @far = pos end return end end set = [ set ] if count > 1 return set end
match_any(any)
click to toggle source
# File lib/peglite.rb, line 122 def match_any any any.each do |elem| if (m = match elem) return m end end return end
match_ref(ref)
click to toggle source
TODO move trace/debug out of default match_ref
method
# File lib/peglite.rb, line 132 def match_ref ref trace "Try #{ref}" if @debug method = [ ref, "rule_#{ref}" ].find{|e| respond_to? e} fail "No rule defined for '#{ref}'" unless method m = send method if m m = (@wrap and not m.empty?) ? [{ref => m}] : m trace "Got #{ref}" if @debug else trace "Not #{ref}" if @debug end return m end
match_rgx(regex)
click to toggle source
# File lib/peglite.rb, line 146 def match_rgx regex m = @input[@pos..-1].match(regex) return unless m @pos += m[0].length match = m.captures # XXX not sure about this: match = [ match ] if m.length > 2 @far = @pos if @pos > @far return match end
parse(input=@input, top=($PegLiteTopRule || 'top'))
click to toggle source
# File lib/peglite.rb, line 66 def parse input=@input, top=($PegLiteTopRule || 'top') fail "PegLite parse() method requires an input string" \ unless input.kind_of? String @input = input got = match_ref top failure if @pos < @input.length return @got || got[0] end
trace(action)
click to toggle source
# File lib/peglite.rb, line 160 def trace action indent = !!action.match(/^Try /) @indent ||= 0 @indent -= 1 unless indent $stderr.print ' ' * @indent @indent += 1 if indent snippet = @input[@pos..-1] snippet = snippet[0..30] + '...' if snippet.length > 30; snippet.gsub! /\n/, "\\n" $stderr.printf "%-30s", action $stderr.print indent ? " >#{snippet}<\n" : "\n" end