in reply to Re^2: Order of Precedence in Parse::RecDescent grammar
in thread Order of Precedence in Parse::RecDescent grammar
Consider the generic outline:
The problem is that you want your parse to give different semantic values for the different branches. If you take the 2nd branch, it's just a "pass-through" of the semantic value and you don't want to construct a new arrayref around it. If you take the first branch where there is actually an operation, you need to construct an arrayref with the appropriate things.lower_prec_expr : higher_prec_expr lower_prec_op lower_prec_expr | higher_prec expr
You've combined both of these branches into one production in the grammar like this:
So now you're putting things inside an arrayref even in the "pass-through" case, where there is no operator at this point in the parse.lower_prec_expr : higher_prec_expr (lower_prec_op lower_prec_expr)(s?) { [ "put stuff in arrayref" ] }
To fix this, put a conditional in your semantic rule to distinguish these cases, i.e:
That's kinda nasty. Alternatively, have two different productions explicitly in the grammar:lower_prec_expr : higher_prec_expr (lower_prec_op lower_prec_expr)(s?) { @{$item[2]} ? [ ... ] : $item[1] }
I.e, if there *are* operators here (no question mark on the (s) quantifier), we build an arrayref for the semantic value with the first branch. Otherwise, the second branch has no semantic rule, so it's just a "pass-through" of the semantic value and does not add layers of arrayref.lower_prec_expr : higher_prec_expr (lower_prec_op lower_prec_expr)(s) { [ ... ] } | higher_prec_expr
The latter is probably the best choice. Just change the (s?)'s to (s)'s and add the other alternation to the grammar.
blokhead
|
|---|