Reduce order in Bison

安稳与你 提交于 2019-12-11 20:15:30

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!