我正在为着色引擎编写一个编译器,并且每个编译器都运行良好,直到我到达语句解析部分。
我使用了一个用类定义的抽象语法树来完成所有工作(以简化类型检查和中间代码生成)。所以我有一个祖先类ASTNode
和所有降级类,如ASTFloat
,等等。ASTExpression
ASTIdentifier
在.y
文件中,我能够以常见的方式构建 AST:
nexp:
T_LPAR nexp T_RPAR { $$ = $2; }
| nexp OP_PLUS nexp { $$ = new ASTBExpression('+', (ASTExpression*)$1, (ASTExpression*)$3); }
| nexp OP_MINUS nexp { $$ = new ASTBExpression('-', (ASTExpression*)$1, (ASTExpression*)$3); }
| nexp OP_TIMES nexp { $$ = new ASTBExpression('*', (ASTExpression*)$1, (ASTExpression*)$3); }
它工作得很好,但是后来我尝试以这种方式生成范围的语句(例如if语句的主体):我使用了一个类ASTStatements
,该类具有ASTNode*
必须由解析器在遇到的每个语句时填充的列表。
因此,该方法将类似于以下内容:
statements:
statement { if ($$ == null) $$ = new ASTStatements(); ((ASTStatements*)$$)->addStatement($1); } statements { $$->generateASM(); }
;
问题是每个语句块应该只初始化一次该项目,但我不知道该怎么做。Usingif ($$ == null)
是我尝试过的一种技巧,但它不起作用,因为它yylval
可以包含到目前为止的任何内容。
使用 Bison 处理这种情况的正常/最佳方法是什么?