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

Reply via email to