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

标签 bison yacc

我有一个使用括号和方括号作为分隔符的语法。当由 bison 生成的解析器输入带有不平衡分隔符的输入时,传递给 yyerrorYYLTYPE*​​ 中的错误位置是输入的结尾。所以,例如,在输入 xx(yy, 在 void yyerror(YYLTYPE*​​ yylloc, Context* ctx, const char* msg) 我有那个 yylloc->first_column == yylloc->last_column == 5。不幸的是,输入的末尾不是指示不匹配分隔符的最显着位置。更有用的是左括号或左方括号的位置没有匹配的。(在示例中,这将是偏移量 2 处的左括号。)我认为此信息在解析堆栈中可用 --- 必须有一些 n 使得 $-n 是不匹配的 ([ 标记并且 @-n保持其位置的 YYLTYPE 结构 --- 但 yyerror 似乎没有这些结构可用。我知道我可以保留自己的堆栈来跟踪定界符的偏移量和把它藏在 Context 我已经传递给 yyerror,但是这似乎不雅且重复,因为 Bison 已经在跟踪这一点。

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

最佳答案

您应该能够添加规则:

atom: '(' error    { /* unmatched left paren at @1 */ }

atom: '(' alt error    { /* unmatched left paren at @1 */ }

获取有关不匹配的左括号的信息。不同之处在于,第一个规则将匹配一个不匹配的括号,该括号后面没有任何可解析的内容(例如在输入的末尾),而第二个规则仅在其后跟看起来像有效 的内容时才匹配alt.

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

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

关于bison - 如何在 yacc/bison 中找到用于错误报告的不平衡分隔符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15936049/

相关文章:

compiler-construction - BISON + FLEX 语法 - 为什么标记被连接在一起

parsing - 让 Bison 解析器泄露调试信息

grammar - 是否有可能使这个 YACC 语法明确?表达式 : . .. |表达式 表达式

c++ - 如何从 YACC 获取 AST?

parsing - 如何用基于语法的解析器替换宏?

linux - 由于 Bison 设置问题,RHEL 5 中的单声道设置问题

bison - 使用 Flex 和 Bison 的简单 Java 语法

对 Bison/YACC 语法的困惑

yacc - yytext [0]是什么意思?

yacc - 如何将 lex 文件中的 yytext 传递给 yacc?