Created
May 5, 2011 15:29
-
-
Save matthewd/957252 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/lib/kpeg/code_generator.rb b/lib/kpeg/code_generator.rb | |
index 55376d6..bcdddcd 100644 | |
--- a/lib/kpeg/code_generator.rb | |
+++ b/lib/kpeg/code_generator.rb | |
@@ -263,7 +263,11 @@ module KPeg | |
code << indentify("_tmp = _tmp ? nil : true\n", indent) | |
code << indentify("self.pos = #{ss}\n", indent) | |
when RuleReference | |
- code << indentify("_tmp = apply(:#{method_name op.rule_name})\n", indent) | |
+ if op.arguments | |
+ code << indentify("_tmp = apply(:#{method_name op.rule_name}, #{op.arguments[1..-2]})\n", indent) | |
+ else | |
+ code << indentify("_tmp = apply(:#{method_name op.rule_name})\n", indent) | |
+ end | |
when InvokeRule | |
if op.arguments | |
code << indentify("_tmp = #{method_name op.rule_name}#{op.arguments}\n", indent) | |
diff --git a/lib/kpeg/compiled_parser.rb b/lib/kpeg/compiled_parser.rb | |
index 01acada..115770d 100644 | |
--- a/lib/kpeg/compiled_parser.rb | |
+++ b/lib/kpeg/compiled_parser.rb | |
@@ -229,8 +229,9 @@ module KPeg | |
end | |
end | |
- def apply(rule) | |
- if m = @memoizations[rule][@pos] | |
+ def apply(rule, *args) | |
+ k = args.empty? ? rule : [rule, *args] | |
+ if m = @memoizations[k][@pos] | |
m.inc! | |
prev = @pos | |
@@ -246,17 +247,17 @@ module KPeg | |
else | |
lr = LeftRecursive.new(false) | |
m = MemoEntry.new(lr, @pos) | |
- @memoizations[rule][@pos] = m | |
+ @memoizations[k][@pos] = m | |
start_pos = @pos | |
- ans = __send__ rule | |
+ ans = __send__ rule, *args | |
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.detected | |
- return grow_lr(rule, start_pos, m) | |
+ return grow_lr(rule, args, start_pos, m) | |
else | |
return ans | |
end | |
@@ -265,12 +266,12 @@ module KPeg | |
end | |
end | |
- def grow_lr(rule, start_pos, m) | |
+ def grow_lr(rule, args, start_pos, m) | |
while true | |
@pos = start_pos | |
@result = m.result | |
- ans = __send__ rule | |
+ ans = __send__ rule, *args | |
return nil unless ans | |
break if @pos <= m.pos | |
diff --git a/lib/kpeg/format.kpeg b/lib/kpeg/format.kpeg | |
index bf017d1..611e638 100644 | |
--- a/lib/kpeg/format.kpeg | |
+++ b/lib/kpeg/format.kpeg | |
@@ -81,13 +81,14 @@ sgl_escape_quote = "\\'" { "'" } | |
| "~" method:m < nested_paren? > | |
{ @g.action("#{m}#{text}") } | |
| "." { @g.dot } | |
- | "@" var:name !(- "=") { @g.invoke(name) } | |
+ | "@" var:name < nested_paren? > !(- "=") | |
+ { @g.invoke(name, text.empty? ? nil : text) } | |
| "^" var:name < nested_paren? > | |
{ @g.foreign_invoke("parent", name, text) } | |
| "%" var:gram "." var:name < nested_paren? > | |
{ @g.foreign_invoke(gram, name, text) } | |
| var:name < nested_paren? > !(- "=") | |
- { text.empty? ? @g.ref(name) : @g.invoke(name, text) } | |
+ { @g.ref(name, nil, text.empty? ? nil : text) } | |
| char_range | |
| regexp | |
| string | |
diff --git a/lib/kpeg/grammar.rb b/lib/kpeg/grammar.rb | |
index 40e4107..0a8185b 100644 | |
--- a/lib/kpeg/grammar.rb | |
+++ b/lib/kpeg/grammar.rb | |
@@ -396,13 +396,14 @@ module KPeg | |
end | |
class RuleReference < Operator | |
- def initialize(name, grammar=nil) | |
+ def initialize(name, grammar=nil, args=nil) | |
super() | |
@rule_name = name | |
@grammar = grammar | |
+ @arguments = args | |
end | |
- attr_reader :rule_name | |
+ attr_reader :rule_name, :arguments | |
def match(x) | |
if @grammar and @grammar != x.grammar | |
@@ -421,14 +422,19 @@ module KPeg | |
def ==(obj) | |
case obj | |
when RuleReference | |
- @rule_name == obj.rule_name | |
+ @rule_name == obj.rule_name and @arguments == obj.arguments | |
else | |
super | |
end | |
end | |
def inspect | |
- inspect_type "ref", @rule_name | |
+ if @arguments | |
+ body = "#{@rule_name} #{@arguments}" | |
+ else | |
+ body = @rule_name | |
+ end | |
+ inspect_type "ref", body | |
end | |
end | |
@@ -807,8 +813,8 @@ module KPeg | |
NotPredicate.new Grammar.resolve(node) | |
end | |
- def ref(name, other_grammar=nil) | |
- RuleReference.new name.to_s, other_grammar | |
+ def ref(name, other_grammar=nil, args=nil) | |
+ RuleReference.new name.to_s, other_grammar, args | |
end | |
def invoke(name, args=nil) | |
diff --git a/lib/kpeg/grammar_renderer.rb b/lib/kpeg/grammar_renderer.rb | |
index 9883d1c..de43f06 100644 | |
--- a/lib/kpeg/grammar_renderer.rb | |
+++ b/lib/kpeg/grammar_renderer.rb | |
@@ -132,11 +132,15 @@ module KPeg | |
render_op io, op.op | |
end | |
when RuleReference | |
- io.print op.rule_name | |
- when InvokeRule | |
if op.arguments | |
io.print "#{op.rule_name}#{op.arguments}" | |
else | |
+ io.print "#{op.rule_name}" | |
+ end | |
+ when InvokeRule | |
+ if op.arguments | |
+ io.print "@#{op.rule_name}#{op.arguments}" | |
+ else | |
io.print "@#{op.rule_name}" | |
end | |
when ForeignInvokeRule |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment