减少野牛的订单

时间:2015-12-28 15:20:32

标签: bison

我正在使用Bison编写一个编译器,我试图在while和repeat循环中使用相同的函数。我需要解析器在“condition”之前减少“statements_off”。 ¿我可以指定减少订单吗?

以下是循环的代码:

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 个答案:

答案 0 :(得分:1)

野牛减少量由自下而上和从左到右进行评估。这是算法的一个重要部分。

这给你一点点自由度 - 偶尔你可以写一个语法,这样自下而上的减少就会产生从右到左的效果 - 但你真的不应该这样做。当你解析AST(理想情况下独立于动作评估的顺序)然后在必要和方便的时候走AST时,语义分析效果最好。

通过将语言直接线性化为三地址代码来编写一次通过编译器可能看起来像是简化或优化。但最终感觉更像是直夹克,因为很难歪曲一个旨在将树生成线性控制流的过程。

一次性编译器 - 想到Lua编译器 - 通常最终不得不重新排序生成的代码块,这既是因为这个问题的结构,也是为了实现非窥孔优化。

(将whilefor语句中的预测试随机播放到循环结束实际上很常见,这似乎与此处考虑的内容相反。)

要明确可能性,请考虑以下区别:

expressions: 
           | expressions expression     { printf("%d\n", $2); }

expressions:
           | expression expressions     { printf("%d\n", $1); }

这两个都从左到右减少expression,但expressions的自下而上减少导致第二个摘录以相反的顺序打印表达式的值。如果expression不是递归的(几乎可以肯定),你可以将它解构为expressions生成,导致表达式本身的减少与自下而上的逻辑相对应。但是这种转变是非常有限的,因为它只会在你进行递归制作之前有效,而且几乎所有有趣的制作都是递归的。 (statementexpression只是两个例子。)