Search code examples
pharopetitparser

PetitParser not distributive?


Are rules in PetitParser distributive?

There were next rules:

integerLiteral --> hexIntegerLiteral / octalIntegerLiteral / decimalIntegerLiteral
  hexIntegerLiteral     --> hexNumeral , (integerTypeSuffix optional)
  octalIntegerLiteral   --> octalNumeral , (integerTypeSuffix optional)
  decimalIntegerLiteral --> decimalNumeral , (integerTypeSuffix optional)

if I change them to:

integerLiteral --> (hexIntegerLiteral / octalIntegerLiteral / decimalIntegerLiteral) , (integerTypeSuffix optional)
  hexIntegerLiteral     --> hexNumeral
  octalIntegerLiteral   --> octalNumeral
  decimalIntegerLiteral --> decimalNumeral

then 0777L is not parsed anymore. It should match octalNumeral , (integerTypeSuffix optional) or in new version octalIntegerLiteral , (integerTypeSuffix optional) but that isn't happening.


Solution

  • Yes, the ordered-choice in PetitParser is distributive. In your example there is some context missing, so I don't know why it doesn't work for you.

    The PetitParser optimizer does the change you suggested automatically. The rewrite rule (in a slightly more general form) is defines as:

    PPOptimizer>>#postfixChoice
        <optimize>
    
        | before prefix body1 body2 postfix after |
        before := PPListPattern any.
        prefix := PPPattern any.
        body1 := PPListPattern any.
        body2 := PPListPattern any.
        postfix := PPPattern any.
        after := PPListPattern any.
        rewriter
            replace: before / (prefix , body1) / (prefix , body2) / after
            with: before / (prefix , (body1 / body2)) / after.
        rewriter
            replace: before / (body1 , postfix) / (body2 , postfix) / after
            with: before / ((body1 / body2) , postfix) / after