使用野牛解析的元素列表
-
11-09-2019 - |
题
我正在写一个编译器的着色引擎,每工作得很好,直到我达到解析一部分的论述。
我使用的抽象语法树与类来完成所有的工作中(为了简化类型检查和中间代码生成)中所定义..所以我有一个祖先类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); }
和它的工作原理相当不错,但后来我想产生一个范围的语句(例如一个身体的如果的声明)中这样说:我已经使用了类ASTStatements
其中有一个列表ASTNode*
必须由解析器与遇到的每个语句被填充。
因此,办法是与此类似:
statements:
statement { if ($$ == null) $$ = new ASTStatements(); ((ASTStatements*)$$)->addStatement($1); } statements { $$->generateASM(); }
;
的问题是,该项目应每个语句块只初始化一次,但我不知道该怎么做。使用if ($$ == null)
被一劈我想,但它不工作,因为yylval
可以包含任何到这一点。
这是处理这种使用野牛情况正常/最佳方式是什么?
解决方案 3
我通过产生不是语句列表,但退化的树来解决这个问题。所以涉及的类对象是:
ASTStatements
{
ASTStatements *m_next;
ASTStatement *m_statement;
....
public:
ASTStatements(ASTStatement *statement) // used for last one
ASTStatements(ASTStatement *stat, ASTStatements *next) // used with a next one
}
以下面的方式使用规则.y
statements: /* empty */ { $$ = null; }
| statements statement { if ($1 == null) $$ = new ASTStatements($2); else $$ = new ASTStatements($2, (ASTStatements*)$1); }
和确实这是左递归的,从而允许在不弄乱堆栈尽快减小语句。我跟任何其他种类的“符号列表”涉及我的语言同样的方法..
其他提示
尝试增强语法如下所示:
statements: statement { $$ = new ASTStatements();
((ASTStatements*)$$)->addStatement($1); }
| statements statement { ((ASTStatements*)$$)->addStatement($2); }
不知道这会有所帮助。
有各种原因喜欢左递归规则yacc可有一件事你就可以尽早在输入减少。
在任何情况下,当你这样做,就可以使用一个图案是这样的:
statements: { $$ = new ... }
| statements statement { /* now $1 and $2 do just what you want */ }
;
不隶属于 StackOverflow