问题
I am writing a compiler using Bison and I am trying to use the same function with while and repeat loops. I need the parser to reduce "condition
" before "statements_off
". ¿Can I specify the reduction order?
Here is the code for the loops:
loop_stmt:
WHILE line condition DO ENDL line statements_off DONE
{ $$ = process_while($<elem>3, $<elem>7, $<ival>2, $<ival>6); }
| REPEAT ENDL line statements_off UNTIL line condition
{ $$ = process_not($<elem>7);
$$ = process_while($$, $<elem>4, $<ival>6, $<ival>3); }
| FOR for_condition DO ENDL statements_off DONE
{ $$ = process_for($<elem>5, $<ival>2); }
;
condition: '(' expr_bool_or ')' { validate_bool_condition($<elem>2); $$ = $<elem>2; }
;
回答1:
Bison reductions are evaluated bottom-up and left-to-right. That is an essential part of the algorithm.
That gives you a tiny bit of latitude -- occassionally you can write a grammar so that bottom-up reductions will have a right-to-left effect -- but you really shouldn't. Semantic analysis works best when you parse into an AST (ideally independent of the order of action evaluation) and then walk the AST as necessary and convenient.
Writing a one-pass compiler by directly linearizing the language into three-address code may seem like a simplification, or an optimisation. But it will end up feeling more like a straight-jacket because of the difficulty of warping a process designed to produce a tree into a linear control flow.
One-pass compilers -- the Lua compiler springs to mind -- often end up having to reorder chunks of generated code, both because of constructs such as this question and in order to implement non-peephole optimizations.
(It's actually pretty common to shuffle the pre-test in while
and for
statements to the end of the loop, which seems to be the opposite of what is being contemplated here.)
To be clear about the possibilities, consider the difference between:
expressions:
| expressions expression { printf("%d\n", $2); }
and
expressions:
| expression expressions { printf("%d\n", $1); }
Both of these reduce expression
left-to-right, but the bottom-up reduction of expressions
causes the second excerpt to print the values of the expressions in reverse order. If expression
were not recursive (which it almost certainly is), you could unfactor it into the expressions
production, causing the reductions of the expressions themselves to correspond to the bottom-up logic. But this transformation is extremely limited, because it will only work until you hit a recursive production, and almost all interesting productions are recursive. (statement
and expression
being just two examples.)
来源:https://stackoverflow.com/questions/34496124/reduce-order-in-bison