Using this relatively simple parser:
module Dragon
class Parser < Parslet::Parser
rule(:lower) { match["a-z"] }
rule(:upper) { match["A-Z"] }
rule(:space) { str("\s").repeat }
rule(:space?) { space.maybe }
rule(:eol) { str("\n").repeat }
rule(:eol?) { eol.maybe }
rule(:digit) { match "[0-9]" }
rule(:zero) { str "0" }
rule(:integer) { match "[1-9]" }
rule(:comma) { str "," }
rule(:comma?) { comma.maybe }
rule(:colon) { str ":" }
rule(:open) { str "(" }
rule(:close) { str ")" }
rule(:atom) { match["a-zA-Z0-9"] }
rule(:number) { ( zero | integer >> digit.repeat.maybe).as :number }
rule(:word) { lower >> atom.repeat }
rule(:arguments) { space? >> (token >> comma?).repeat >> space? }
rule(:method) { word.as(:method) >> open >>
arguments.maybe.as(:arguments) >> close }
rule(:token) { method | word | number }
rule(:expression) { (token >> space?).as :expression }
rule(:expressions) { expression.repeat.maybe.as(:expressions) >> eol? }
root(:expressions)
end
end
I'm able to parse this code:
8 divide(2) divide(2)
Into this tree:
{:expressions=>
[{:expression=>{:number=>"8"@0}},
{:expression=>{:method=>"divide"@2, :arguments=>[{:number=>"2"@9}]}},
{:expression=>{:method=>"divide"@12, :arguments=>[{:number=>"2"@19}]}}]}
However what I want is sequence of expressions (delimited by \n):
8 divide(2) divide(2)
4 divide(2)
My first thoughts are to do thusly:
``` diff
- rule(:expressions) { expression.repeat.maybe.as(:expressions) >> eol? }
- root(:expressions)
+ rule(:expressions) { expression.repeat.maybe.as(:expressions) >> eol? }
+ rule(:line) { expressions.repeat.as :line }
+ root(:line)
```
However this results in an infinite loop. I'm not sure I can figure
out what's going wrong here.
Anyone with any ideas?
--
Kurtis Rainbolt-Greene, Hacker
Difference Engineers, LLC
1631 8th Street
New Orleans, LA 70115