Skip to content

Instantly share code, notes, and snippets.

@matthewd
Created May 5, 2011 15:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matthewd/957252 to your computer and use it in GitHub Desktop.
Save matthewd/957252 to your computer and use it in GitHub Desktop.
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