Hello Pharoers and Moosers,
I did a Pratt parser extension for PetitParser.
A Pratt parser (a.k.a top-down operator precedence parser) handles left-recursion and
It handles grouping, prefix, postfix, infix (right- or left-associative) and
"multifix” operators (e.g. "if ... then ... else ...", "... ? ... :
...", Smalltalk keyword messages).
Normally Pratt Parsing needs a tokenization phase but here tokenization is done on the fly
with other PP parsers.
Apart from tokenization, no backtracking is needed so parsing is quite fast
(approximatively 2 times faster than PPExpressionParser).
Here is an exemple of a calculator:
parser := PPPrattParser new.
parser terminal: #digit asParser plus do: [ :token | token inputValue asNumber ].
parser skip: #space asParser plus.
parser groupLeft: $( asParser right: $) asParser.
"Addition, substraction, multiplication, division: all left infix, * and / have
higher precedence than + and -"
parser leftInfix: $+ asParser precedence: 1 do: [ :left :op :right | left + right ].
parser leftInfix: $- asParser precedence: 1 do: [ :left :op :right | left - right ].
parser leftInfix: $* asParser precedence: 2 do: [ :left :op :right | left * right ].
parser leftInfix: $/ asParser precedence: 2 do: [ :left :op :right | left / right ].
"Power: right infix with higher precedence than multiplication and
parser rightInfix: $^ asParser precedence: 3 do: [ :left :op :right | left raisedTo:
"Unary minus: prefix with highest precedence"
parser prefix: $- asParser precedence: 4 do: [ :op :right | right negated ].
parser parse: '2*3 + 4^(1/2)*3' ----> 12
To try it:
smalltalkhubUser: 'CamilleTeruel' project: 'PetitPratt';
Note that it is in beta stage so it might still change drastically.
I had trouble with the PPContext furthestFailure that is taken into account instead of the
failures I return, so I had to redefine #parseWithContext: to return the failures I want.
The results given by furthestFailure were not very meaningful in my case (the same is true
for PPExpressionParser btw).
But I guess it was introduced because it gives good results in other cases.
So would it be possible to change this behavior to let the parser decide if it returns the
furthestFailure or the original failure?
Show replies by date