3

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

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

4

2 回答 2

6

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

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

或者

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

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

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

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

于 2013-04-13T20:27:48.303 回答
1

查看野牛中的错误标记:http ://www.gnu.org/software/bison/manual/html_node/Error-Recovery.html#Error-Recovery

我想这样的事情会起作用(我没有测试过):

atom:  '(' alt ')'        { $$ = $2; }
    |  '(' alt error '\n' { /* this handles an extra left paren */ }
    |   error alt ')'     { /* this handles an extra right paren */ }
    |   literal
    ;
于 2013-04-11T19:25:54.367 回答