【发布时间】:2015-07-04 19:40:37
【问题描述】:
我一直在研究一个爱好编译器,在解析阶段使用 lex 和 yacc。这对大多数事情来说都很好,但是当我添加 if 语句时,符号的产生规则现在给出堆栈上的上一个(或下一个?)项目,而不是所需的符号值。
语法如下,希望去掉不相关的规则:
%{
...
%}
%define parse.error verbose
%token ...
%%
Program:
Function { root->addChild($1);}
;
Function:
Type Identifier '|' ArgumentList '|' StatementList END
{ $$ = new FunctionDef($1, $2, $4, $6); }
/******************************************/
/* Statements and control flow ************/
/******************************************/
Statement:
Expression Delimiter
| VariableDeclaration Delimiter
| ControlFlowStatement Delimiter
| Delimiter
;
ControlFlowStatement:
IfStatement
;
IfStatement:
IF Expression StatementList END { $$ = new IfStatement($2, $3); }
| IF Expression StatementList ELSE StatementList END { $$ = new IfStatement($2, $3, $5);}
;
VariableDeclaration:
Type Identifier { $$ = new VariableDeclaration($1, $2);}
| Type Identifier EQUALS Expression { $$ = new VariableDeclaration($1, $2, $4);}
;
StatementList:
StatementList Statement { $1->addChild($2); }
| Statement { $$ = new GenericList($1); }
;
Delimiter:
';'
| NEWLINE
;
Type:
...
Expression:
...
PostfixExpression:
Value '[' Expression ']' { std::cout << "TODO: indexing operators ([ ])" << std::endl;}
| Value '.' SYMBOL { std::cout << "TODO: member access" << std::endl;}
| Value INCREMENT { $$ = new UnaryExpression(UNARY_POSTINC, $1); }
| Value DECREMENT { $$ = new UnaryExpression(UNARY_POSTDEC, $1); }
| Value '(' ')' { $$ = new FunctionCall($1, NULL); }
| Value '(' ExpressionList ')' { $$ = new FunctionCall($1, $3); }
| Value
;
Value:
BININT { $$ = new Integer(yytext, 2); }
| HEXINT { $$ = new Integer(yytext, 16); }
| DECINT { $$ = new Integer(yytext); }
| FLOAT { $$ = new Float(yytext); }
| SYMBOL { $$ = new Symbol(yytext); }
| STRING { $$ = new String(yytext); }
| LambdaFunction
| '(' Expression ')' { $$ = $2; }
| '[' ExpressionList ']' { $$ = $2;}
;
LambdaFunction:
...
%%
我无法弄清楚控制流代码可以制作符号: 规则匹配未归类为 lex 定义中的符号的内容:
symbol [a-zA-Z_]+(alpha|digit)*
...
{symbol} {return SYMBOL;}
任何了解 yacc 和一般语法的人的帮助将不胜感激。如果需要,还可以显示它解析的语法示例文件。
谢谢!
【问题讨论】:
-
TL;DR!将语法缩小到支持有问题的规则所需的最低限度。例如,您可能不需要完整的表达式层次结构或大多数其他语句或声明。如果它有效,则为表达式再添加一个级别,并继续直到出现错误。如果即使使用最少的语法也会出现错误,至少您消除了许多可能的来源,并且可以编辑您的问题以仅包含最少的语法。
-
我自己也在想同样的事情,可能发布时间太长,但我决定谨慎行事,不知道错误在哪里!你是对的,虽然我可以不用表达式堆栈等。
-
关于剥离语法以查找问题根源,我确实这样做了,发现它是控制流代码,但我不知道如何或为什么。跨度>
-
再看
IF规则,你确定要一个语句作为条件吗?现在它允许无限递归(它允许if if if if if if ...等等)。 -
这实际上是我忘记取出的遗留测试,我已经在黑暗中跌跌撞撞了一段时间!它应该是表达,但这仍然没有帮助:/感谢您的回复。