例如我有代码
%nonassoc lower
%nonassoc ELSE
if_stmt: IF '(' expr ')' statement %prec lower
{
/*some code*/
}
| IF '(' expr ')' statement ELSE statement
{
/*some code*/
}
;
根据规则和代码(不做太多)我现在得到" elsesyntax 错误"当我测试IF-ELSE语句时。如果它只是一个IF语句,它可以正常工作。
我认为我应该在第二个动作中传递一些东西以使其起作用,但我不确定是什么。
如果可能的话,我不想将这两项行动分开。
编辑:所以这里是被问及的语法和优先级: EDIT2:实现了我的语法规则。复合_stmt和local_declarations是评论因为我还不知道如何处理它们。%nonassoc islowerthanelse
%nonassoc ELSE
%%
%token <intVal> NUM WHILE PRINT IF ELSE INT
program : declaration_list statement_list
{
printf("/0\n");
}
;
declaration_list : declaration_list declaration
{
printf("/1\n");
$$ = make_node(DeclSeq, NULL, $1, $2, NULL, NULL);
}
|declaration
{
printf("/2\n");
$$ = $1;
}
;
declaration : type_specifier ID ';'
{
printf("/3\n");
$$ = make_node(Decl, p3, $1, NULL, NULL, NULL);
}
type_specifier : INT
{
printf("/5\n");
$$ = make_node(INT, NULL, NULL, NULL, NULL, NULL);
}
;
statement_list : statement_list statement
{
printf("/6\n");
$$ = make_node(StmtSeq, NULL, $1, $2, NULL, NULL);
}
|/* EMPTY */
{
printf("/7\n");
$$ = make_node(astEmptyStmtSeq, NULL, NULL, NULL, NULL, NULL);
}
;
statement : expression_stmt
{
printf("/8\n");
$$ = $1;
}
/*|compound_stmt
{
$$ = $1;
}*/
|selection_stmt
{
$$ = $1;
}
|iteration_stmt
{
$$ = $1;
}
|print_stmt
{
printf("/12\n");
$$ = $1;
}
;
/*compound_stmt : '{' local_declarations statement_list '}'
;
local_declarations : local_declarations declaration
|/* EMPTY *\
;*/
expression_stmt : expression ';'
{
printf("/15\n");
$$ = make_node(ExprStmt, NULL, $1, NULL, NULL, NULL);
}
|/* EMPTY */ ';'
{
printf("/16\n");
$$ = make_node(EmptyExprStmt, NULL, NULL, NULL, NULL, NULL);
}
;
selection_stmt : IF '(' expression ')' statement %prec islowerthanelse
{ printf("/256\n");
$$ = make_node(IfStmt, NULL, $3, $5, NULL, NULL);
}
|IF '(' expression ')' statement ELSE statement
{printf("/257\n");
$$ = make_node(IfElseStmt, NULL, $3, $5, $7, NULL);
}
;
iteration_stmt : WHILE '(' expression ')' statement
{
$$ = make_node(astWhileStmt, NULL, $3, $5, NULL, NULL);
}
;
答案 0 :(得分:0)
行动是相互独立的;没有“堕落”。如果要在两个动作之间重构公共代码,请将其放入可以从动作中调用的函数中。
但是,这应该与您看到的语法错误无关。操作不会影响解析;如果解析器报告语法错误,它将执行此操作而不运行任何操作(因为错误反映了无法找到适当的生产)。
答案 1 :(得分:0)
来自片段节目的最佳猜测 - 您的%prec lower
实际上具有比ELSE
令牌更高的优先级,因此当看到ELSE
时,它会减少第一个规则,然后获得语法错误,因为它无法在缩减后对ELSE
执行任何操作。
然而,实际上回答这个问题需要看到完整的语法。
我在你的语法中添加了以下内容来制作一个MVCE:
%{
#include <stdio.h>
#define make_node(...) 0
%}
%nonassoc islowerthanelse
%nonassoc ELSE
%token NUM WHILE PRINT IF INT ID
%token expression print_stmt
%%
%%
#include "lex.yy.c"
int main() { return yyparse(); }
int yywrap() { return 1; }
void yyerror(const char *msg) { printf("%s\n", msg); }
除了一个微不足道的词法分子:
%%
"while" return WHILE;
"print" return PRINT;
"if" return IF;
"else" return ELSE;
"int" return INT;
"expression" return expression;
[A-Za-z][A-Za-z0-9]* return ID;
[0-9]* return NUM;
[ \t\n] ;
. return *yytext;
和输入文件如:
int A;
if (expression) expression; else expression;
它似乎工作得很好......
$ a.out <input.txt/5
/3
/2
/7
/15
/8
/15
/8
/257
/6
/0