如何在yacc/bison中找到错误报告的不平衡分隔符?

uck*_*man 3 yacc bison

我有一个语法,它使用括号和方括号作为分隔符.当bison生成的解析器被赋予带有不平衡分隔符的输入时,YYLTYPE*传递给的传入的错误位置yyerror是输入的结尾.所以,例如,在输入中xx(yy,void yyerror(YYLTYPE* yylloc, Context* ctx, const char* msg)我有这个yylloc->first_column == yylloc->last_column == 5.不幸的是,输入的结尾不是指示不匹配分隔符的最显着位置.更有用的是左括号或左方括号的位置,没有匹配.(在该示例中,这将是左括号在偏移2)我推测,此信息可用在分析堆---必须有一些Ñ使得$-n是不匹配([令牌,并@-nYYLTYPE结构保持其位置---但似乎没有一个可用yyerror.我知道我可以保留一堆我自己用于跟踪分隔符的偏移并隐藏在Context我已经传递的内容中yyerror,但这似乎是不优雅和重复的,因为野牛已经在跟踪这个.

那么:如何从bison中获得它在输入中遇到的第一个不平衡分隔符的位置,以便在为解析错误生成消息时可以使用它?

Chr*_*odd 6

您应该能够添加以下规则:

atom: '(' error    { /* unmatched left paren at @1 */ }
Run Code Online (Sandbox Code Playgroud)

要么

atom: '(' alt error    { /* unmatched left paren at @1 */ }
Run Code Online (Sandbox Code Playgroud)

获取有关不匹配的左括号的信息.区别在于第一个规则将匹配一个不可匹配的任何可解析的不匹配的括号(例如在输入的末尾),而第二个规则只匹配如果它后面跟一个看似有效的东西alt.

如果您的语法中有任何其他错误产生(您没有在链接语法中),则可能存在问题,在这种情况下,可能首先触发不同的错误产生.由于没有其他错误规则,第一种选择更好.

请注意,使用yacc/bison错误恢复规则不会以任何方式抑制语法错误,它只是在语法错误后运行一些代码以尝试恢复.该代码可以打印其他错误消息,然后中止而不是尝试恢复,但这些消息将在语法错误消息之后打印.

  • 你的答案解决了我的问题是"请注意,使用yacc/bison错误恢复规则不会以任何方式抑制语法错误,它只是在语法错误后运行一些代码以尝试恢复." 这让我意识到与错误规则相关的操作永远不会被运行,因为我在`yyerror`中抛出一个异常.在调整之后,我可以看到我*做*匹配错误规则. (2认同)