Error handling “如何防止违约”;语法错误“;野牛

Error handling “如何防止违约”;语法错误“;野牛,error-handling,compiler-construction,bison,flex-lexer,yacc,Error Handling,Compiler Construction,Bison,Flex Lexer,Yacc,正如在标题中所描述的,我使用Bison和Flex来获取解析器,但是我需要处理错误并在找到一个解析器后继续。因此,我使用: Stmt: Reference '=' Expr ';' { printf(" Reference = Expr ;\n");} | '{' Stmts '}' { printf("{ Stmts }");} |

正如在标题中所描述的,我使用Bison和Flex来获取解析器,但是我需要处理错误并在找到一个解析器后继续。因此,我使用:

Stmt:   Reference '=' Expr ';'                                { printf(" Reference = Expr ;\n");}
|       '{' Stmts '}'                                         { printf("{ Stmts }");}
|       WHILE '(' Bool ')' '{' Stmts '}'                      { printf(" WHILE ( Bool ) { Stmts } ");}
|       FOR NAME '=' Expr TO Expr BY Expr '{' Stmts '}'       { printf(" FOR NAME = Expr TO Expr BY Expr { Stmts } ");}
|       IF '(' Bool ')' THEN Stmt                             { printf(" IF ( Bool ) THEN Stmt ");}
|       IF '(' Bool ')' THEN Stmt ELSE Stmt                   { printf(" IF ( Bool ) THEN Stmt ELSE Stmt ");}
|       READ Reference ';'                                    { printf(" READ Reference ;");}
|       WRITE Expr ';'                                        { printf(" WRITE Expr ;");}
|       error ';'                                             { yyerror("Statement is not valid"); yyclearin; yyerrok;}
;
然而,我总是得到一个消息“语法错误”,我不知道它从哪里来,以及如何防止它,以便我自己的“错误代码”将被执行。
我试图在这里进行错误恢复,以便我的解析器在EOF之前继续解析输入。

人们经常混淆yacc/bison中
错误规则的目的——它们是用于错误恢复,而不是用于错误处理。因此,不会调用错误规则来响应错误——错误发生,然后使用错误规则进行恢复


如果您希望自己处理错误(因此避免打印“语法错误”消息),则需要定义自己的
yyrorm
函数(即错误处理程序),该函数使用“syntax error”字符串而不是打印它。一种选择是什么都不做,然后在错误恢复规则中打印一条消息(例如,在您调用yyerror的地方,将其改为printf)。问题是,如果错误恢复失败,您将不会收到任何消息(您将从yyparse获得失败返回,因此可以在那里打印消息)。

人们经常混淆yacc/bison中
错误规则的目的——它们是用于错误恢复,而不是用于错误处理。因此,不会调用错误规则来响应错误——错误发生,然后使用错误规则进行恢复


如果您希望自己处理错误(因此避免打印“语法错误”消息),则需要定义自己的
yyrorm
函数(即错误处理程序),该函数使用“syntax error”字符串而不是打印它。一种选择是什么都不做,然后在错误恢复规则中打印一条消息(例如,在您调用yyerror的地方,将其改为printf)。问题是,如果错误恢复失败,您将不会收到任何消息(您将从yyparse获得失败返回,因此可以在那里打印消息)。

感谢您的回答,我想问您另一个看似愚蠢的问题是,为什么在上面的代码运行时,在打印出“语法错误”消息之后,它将不会恢复并继续解析输入文件的其余部分?我错过什么了吗?我感谢你的帮助!更新:我明白了,因为我在yyerror()函数中设置了exit(1),我怎么能期望它继续并恢复。愚蠢的我,非常感谢你指出了这一重要问题。感谢你的回答,我想问你另一个看似愚蠢的问题,就是为什么在上面的代码运行时,在打印出“语法错误”消息后,它不会恢复并继续解析输入文件的其余部分?我错过什么了吗?我感谢你的帮助!更新:我明白了,因为我在yyerror()函数中设置了exit(1),我怎么能期望它继续并恢复。愚蠢的我,非常感谢你指出了这件重要的事情。