Class: PegLite
- Inherits:
-
Object
- Object
- PegLite
- Defined in:
- lib/peglite.rb,
lib/peglite/compiler.rb
Overview
Defined Under Namespace
Classes: Compiler, PegexParseError
Constant Summary collapse
- VERSION =
'0.0.3'
Instance Attribute Summary collapse
-
#debug ⇒ Object
Returns the value of attribute debug.
-
#got ⇒ Object
Returns the value of attribute got.
-
#input ⇒ Object
Returns the value of attribute input.
-
#wrap ⇒ Object
Returns the value of attribute wrap.
Class Method Summary collapse
Instance Method Summary collapse
- #failure ⇒ Object
- #format_error(msg) ⇒ Object
-
#initialize(attrs = {}) {|_self| ... } ⇒ PegLite
constructor
A new instance of PegLite.
- #match(rule = nil) ⇒ Object
- #match_all(all) ⇒ Object
- #match_any(any) ⇒ Object
-
#match_ref(ref) ⇒ Object
TODO move trace/debug out of default match_ref method.
- #match_rgx(regex) ⇒ Object
- #parse(input = @input, top = ($PegLiteTopRule || 'top')) ⇒ Object
-
#trace(action) ⇒ Object
—————————————————————————- Debugging and error reporting support methods —————————————————————————-.
Constructor Details
#initialize(attrs = {}) {|_self| ... } ⇒ PegLite
Returns a new instance of PegLite.
53 54 55 56 57 58 59 60 61 62 63 64 |
# 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 |
Instance Attribute Details
#debug ⇒ Object
Returns the value of attribute debug.
51 52 53 |
# File 'lib/peglite.rb', line 51 def debug @debug end |
#got ⇒ Object
Returns the value of attribute got.
49 50 51 |
# File 'lib/peglite.rb', line 49 def got @got end |
#input ⇒ Object
Returns the value of attribute input.
52 53 54 |
# File 'lib/peglite.rb', line 52 def input @input end |
#wrap ⇒ Object
Returns the value of attribute wrap.
50 51 52 |
# File 'lib/peglite.rb', line 50 def wrap @wrap end |
Class Method Details
.rule(args) ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# 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 |
Instance Method Details
#failure ⇒ Object
173 174 175 176 |
# File 'lib/peglite.rb', line 173 def failure msg = "Parse failed for some reason" raise PegexParseError, format_error(msg) end |
#format_error(msg) ⇒ Object
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# 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) ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# 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) ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# 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) ⇒ Object
122 123 124 125 126 127 128 129 |
# 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) ⇒ Object
TODO move trace/debug out of default match_ref method
132 133 134 135 136 137 138 139 140 141 142 143 144 |
# 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) ⇒ Object
146 147 148 149 150 151 152 153 154 155 |
# 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')) ⇒ Object
66 67 68 69 70 71 72 73 |
# 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) ⇒ Object
Debugging and error reporting support methods
160 161 162 163 164 165 166 167 168 169 170 171 |
# 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 |