【问题标题】:yacc showing syntax error at the wrong positionyacc 在错误的位置显示语法错误
【发布时间】:2012-10-31 06:00:32
【问题描述】:

这只是一个例子

YACC 语法:

abc:ABC STRING NEWLINE

end:END

.

.

lex 文件:

int lineno=1;

.

.

string [a-zA-Z]+

%%

ABC   {return ABC;}

END   {return END;}

[\n]  {lineno++;return NEWLINE;}

{string} {return STRING;}

%%

每次出现 NEWLINE lineno 时都会增加 如果输入文件是:

ABC xyz

END

yacc 解析成功

如果输入文件是:

ABC 123

END

它显示第 1 行:语法错误

正如预期的那样

但如果输入文件是:

ABC

END

然后它显示 line2:syntax error

但是错误出现在第 1 行而不是第 2 行。

如何才能显示正确的行号?

【问题讨论】:

    标签: yacc lex


    【解决方案1】:

    因为解析器直到从词法分析器接收到NEWLINE 标记后才发现错误,到那时你已经增加了行号。

    这实际上不是一个罕见的问题,在错误的行上显示错误。一个很好的例子是您忘记在 C 源文件中的语句末尾添加分号 (;)。错误很可能在下一行。

    编辑: Yacc 中的错误恢复处理。

    Yacc 有一个特殊的终端符号error,可用于错误恢复。在您的情况下,它可以这样使用:

    abc:ABC STRING NEWLINE
       |error NEWLINE
       ;
    

    您可以在 errorNEWLINE 符号之间添加一段代码来打印错误消息,但它可能无法正常工作,因为解析器在看到 @987654327 之前并不知道有错误无论如何@符号。

    【讨论】:

    • 有什么方法可以检查出现在 NEWLINE 之前的这种缺失值吗?
    • @Tanya 您可以使用特殊的error 终端符号添加规则,但它可能无论如何都不起作用。
    • 上述情况能否报错如:"error at ABC"?
    • @Tanya 如果您有类似 `ABC error NEWLINE` 之类的规则,这可能是可能的。
    【解决方案2】:

    您可以将语法错误消息保守地表述为“第 %d 行附近的语法错误”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 2015-10-26
      • 1970-01-01
      • 2012-01-18
      • 1970-01-01
      相关资源
      最近更新 更多