Hi Ant,
Thanks for your comment. I changed the rule(:term) as you suggested and
my "1 + 2 " expression was parsed. Unfortunately, the parser did not
generate the plus-operator.
Then I added the .as(:plus) in the rule and the parser showed the
plus-operator.
My lesson learned is that I have to experiment with Parslet as like a
game just to discover the parsing rules and the (hidden?) features.
Anyhow, I'm glad that this forum provides me the answers I needed.
Cheers,
Thiel
Op 2-5-2011 17:27, Ant Skelton schreef:
On Mon, May 2, 2011 at 4:02 PM, Thiel Chang <[email protected]
<mailto:[email protected]>> wrote:
Hi Anton,
Anton?! ;)
Many thanks for your advice. I have enclosed my grammar rules:
*snip*
Your 'term' rule contains factor, which will insert (:integer => '1')
when it matches. But the 'term' rule also includes 'term_acc', which
includes 'term'....which will insert (:integer => '2') when it
matches.....but you've already got one of those, which is why Parslet
complains. If you investigate the ".as(:foo)" stuff, you'll be able to
get some hierarchy into your parse tree. For example changing your
term rule to:
rule(:term) { factor >> space? >> term_acc.as
<http://term_acc.as>('foo') }
will cause the parse to succeed.
Actually, this should be a simple grammar for parsing arithmetic
expressions.
Haha, that's never easy in a PEG ;) I've just done something very
similar to a C expression parser, I ended up with a big chain of rules
that follow this format:
rule(:logicalOrExpression) { logicalAndExpression >>
logicalOrExpressionTail.repeat }
rule(:logicalOrExpressionTail) { space? >>
logicalOrOperator.as(:binop) >> space? >> logicalAndExpression.as(:op) }
rule(:logicalOrOperator) { str('||') }
rule(:logicalAndExpression) { inclusiveOrExpression >>
logicalAndExpressionTail.repeat }
rule(:logicalAndExpressionTail) { space? >>
logicalAndOperator.as(:binop) >> space? >> inclusiveOrExpression.as(:op) }
rule(:logicalAndOperator) { str('&&') }
etc etc
This is a common idiom for refactoring to avoid left recursion (which
is a big no-no in PEGs), although it can be somewhat
counter-intuitive. I found that studying grammars for other parsers
very helpful; Spirit (for c++/boost) has some good examples, as does
ANTLR. You can translate these into parslet without too much difficulty.
But I am still struggling:-)
Good luck!
ant