On Mon, May 2, 2011 at 4:02 PM, Thiel Chang <[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('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

Reply via email to