Lex yacc移位/减少错误
我正在学习lex和yacc编程以及这个yacc程序,以验证和评估算术表达式,从而减少冲突。在阅读了其他stackoverflow解释之后,我理解问题的重要性,但是,我不确定如何使用错误处理来解决问题。我想知道是否有人能帮我 我尝试过这样的关联处理程序:Lex yacc移位/减少错误,c,parsing,yacc,lex,operator-precedence,C,Parsing,Yacc,Lex,Operator Precedence,我正在学习lex和yacc编程以及这个yacc程序,以验证和评估算术表达式,从而减少冲突。在阅读了其他stackoverflow解释之后,我理解问题的重要性,但是,我不确定如何使用错误处理来解决问题。我想知道是否有人能帮我 我尝试过这样的关联处理程序: %token VARNAME %token DIGIT %token EQ %token ADD SUB MULT DIV %token LPAREN RPAREN %token END %left ADD SUB MULT DIV LPAREN
%token VARNAME
%token DIGIT
%token EQ
%token ADD SUB MULT DIV
%token LPAREN RPAREN
%token END
%left ADD SUB MULT DIV LPAREN
%right RPAREN END
%nonassoc EQ VARNAME DIGIT
%token VARNAME
%token DIGIT
%token EQ
%token ADD SUB MULT DIV
%token LPAREN RPAREN
%token END
%left ADD SUB MULT DIV LPAREN
%right RPAREN END
%nonassoc EQ VARNAME DIGIT
但是,它不起作用,我很困惑。这是我的1.y文件:
%{
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char* argv[])
{
FILE *fp;
extern FILE *yyin;
extern int yylex();
extern int yyparse();
extern int yydebug;
yydebug = 1;
if (argc == 2)
{
fp = fopen(argv[1], "r");
if (!fp)
{
fprintf (stderr, "Usage: %s <filename>\n", argv[0]);
}
else
{
yyin = fp;
yyparse();
fprintf (stdout, "***PARSE COMPLETE***\n");
}
}
else
fprintf (stderr, "Usage: %s <filename>\n", argv[0]);
}
void yyerror (const char *err)
{
fprintf (stderr, "Error: %s\n", err);
}
%}
%token VARNAME
%token DIGIT
%token EQ
%token ADD SUB MULT DIV
%token LPAREN RPAREN
%token END
%%
statement:
END
|
expression END
{printf ("DONE!\n");};
|
error
{ printf(" INVALID EXPRESSION\n"); }
;
expression:
VARNAME
{printf("PARSED A VARIABLE!\n");};
|
DIGIT
{printf("PARSED A DIGIT!\n");};
|
expression ADD expression
{printf("PARSED A PLUS SIGN!\n");};
|
expression SUB expression
{printf("PARSED A MINUS SIGN!\n");};
|
expression MULT expression
{printf("PARSED A MULTPLY SIGN!\n");};
|
expression DIV expression
{printf("PARSED A DIVIDE SIGN!\n");};
|
expression EQ expression
{printf("PARSED A EQUALS SIGN!\n");};
|
LPAREN expression RPAREN
{printf("PARSED A PARENTHESIS!\n");};
;
%%
这种关联正确吗?这些问题在本文中都有很好的阐述 正如@Jonathan Leffler所说:
您需要指定运算符的优先级和关联性。查找
%left
、%right
和%nonassoc
。或者用不同的方式写语法。例如,C标准中的语法不需要优先级或关联性
%token
项看起来似乎合理。我认为%left
不需要LPAREN
;%right
也不需要RPAREN。我不确定您是否需要%nonassoc
。我假设“code”(
开头和)“code”
结尾是试图格式化注释的人工制品。通常,您希望ADD和SUB的优先级低于MULT和DIV
在算术示例中,这些问题通常通过编写语法来解决:
expression : term
| term ADD expression
| term SUB expression
;
term : factor
| factor MULT term
| factor DIV term
;
factor : VARNAME
| DIGIT
| LPAREN expression RPAREN
;
现在,在明确的语法中定义了运算符的关联性和优先级。需要指定运算符的优先级和关联性。查找
%left
、%right
和%nonassoc
。或者用不同的方式写语法。例如,C标准中的语法不需要优先级或关联性。@JonathanLeffler我在格式方面遇到了问题,但我尝试更新了文章。我是否正确地关联了数字、EQ和VARNAME?%token
项看起来似乎合理。我认为%left
不需要LPAREN
;%right
也不需要RPAREN
。我不确定您是否需要%nonassoc
。我假设“code”(
开头和)“code”
结尾是试图格式化注释的人工制品。通常,您希望ADD和SUB的优先级低于MULT和DIV。