Compiler construction 使用bison解析元素列表
我正在为着色引擎编写一个编译器,在到达语句解析部分之前,每个引擎都工作得很好 我使用类定义的抽象语法树来完成所有工作(以简化类型检查和中间代码生成)。。因此,我有一个祖先类Compiler construction 使用bison解析元素列表,compiler-construction,parsing,yacc,bison,Compiler Construction,Parsing,Yacc,Bison,我正在为着色引擎编写一个编译器,在到达语句解析部分之前,每个引擎都工作得很好 我使用类定义的抽象语法树来完成所有工作(以简化类型检查和中间代码生成)。。因此,我有一个祖先类ASTNode和所有降序类,如ASTFloat,asexpression,astiIdentifier等等 在.y文件中,我能够以常见的方式构建AST: nexp: T_LPAR nexp T_RPAR { $$ = $2; } | nexp OP_PLUS nexp { $$ = new ASTBExpression('+'
ASTNode
和所有降序类,如ASTFloat
,asexpression
,astiIdentifier
等等
在.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(); }
;
问题是每个语句块只需初始化一次项,但我不知道如何初始化。使用if($$==null)
是我尝试过的一种黑客行为,但它不起作用,因为yylval
可以包含任何内容
使用Bison处理此类情况的正常/最佳方法是什么?尝试以下扩充语法:
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 */ }
;
我不是通过生成语句列表而是通过生成一棵退化树来解决这个问题。因此,所涉及的类对象是:
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); }
事实上,这是左递归的,允许在不扰乱堆栈的情况下尽快减少语句。对于我的语言中涉及的任何其他类型的“符号列表”,我采用了相同的方法。您有%type语句吗?如果有,等等?当然,我必须解决将ASTStatements*转换为一个包含左侧部分(ASTStatement*)和右侧部分(ASTStatements*)的类的问题。我实际上把列表变成了一棵退化树..我真的很喜欢退化树的想法。