【问题标题】:How to prevent default "syntax error" in Bison如何防止 Bison 中的默认“语法错误”
【发布时间】:2020-03-11 04:23:04
【问题描述】:

如标题中所述,我正在使用 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。

【问题讨论】:

    标签: error-handling compiler-construction bison flex-lexer yacc


    【解决方案1】:

    人们经常混淆 yacc/bison 中 error 规则的用途——它们是用于错误恢复,而不是用于错误处理。所以错误规则不会被调用来响应错误——错误发生然后错误规则用于恢复。

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

    【讨论】:

    • 谢谢你的回答,我想问你另一个看似愚蠢的问题是为什么,上面的代码运行后,打印出“语法错误”消息后,它无法恢复并继续解析输入文件的其余部分?我错过了什么?我感谢您的帮助!更新:我明白了,因为我把 exit(1) 放在我的 yyerror() 函数中,我怎么能指望它会继续并恢复。愚蠢的我,非常感谢你指出这个重要的事情。
    猜你喜欢
    • 2021-01-05
    • 2017-05-19
    • 2019-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-23
    • 1970-01-01
    相关资源
    最近更新 更多