>     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.

To add a really not well thought out remark: Could this kind of code be 
eliminated through a single meta rule? Like one that says:

        expression_of(term, [%w(&& ||), %w(* /), %w(+ -)])

The expression_of method would take term and build a hierarchy of binary 
rules that encode precedence in PEG-style. It would be so much easier to 
read... Left recursion elimination in the engine seems suddenly less 
elegant to me.

But maybe such a thing cannot be created for reasons not obvious to me 
right now. Anyone biting?

k

Reply via email to