用lex/yacc对剩余数据进行词法分析

3 投票
4 回答
744 浏览
提问于 2025-04-15 11:28

请原谅我,我对解析和lex/yacc完全是新手,可能有点超出我的能力范围,但我还是想说:

我正在用PLY写一个比较简单的计算器,但它的输入不一定总是一个方程式,我需要在解析时判断它是否是方程式。输入的极端情况可能是一个完美的方程式,这样解析和计算都没问题;或者是完全不像方程式的东西,这样解析失败也没关系。

问题在于,有些输入看起来像方程式的一部分,解析器会抓取并处理这些部分。这不是我想要的——我需要能够判断字符串中有没有部分没有被识别和处理,这样我才能抛出错误,但我不知道该怎么做。

有没有人知道我该如何定义一个“捕捉剩余部分”的标记?或者有没有更好的方法来处理这个问题?

4 个回答

0

我通常会使用一个单独的“命令读取器”来获取完整的命令——在你的情况下可能就是一行命令——然后把这个命令放到一个主机变量字符串里,再安排词法分析器来分析这个字符串,包括告诉我什么时候没有到达字符串的末尾。这种设置比较复杂,但可以让某些错误报告变得更简单。我常用这种方法的地方是处理多行命令,这些命令有三种注释方式、两种引号字符串,还有一些其他让人头疼的东西(上下文敏感的标记化——真让人受不了!)。

除此之外,Don关于Yacc的“错误”标记的建议也很好。

1

定义一个标记(输入结束),并让你的词法分析器在输入结束时输出它。

之前,如果你有这些标记:

'1' 'PLUS' '1'

现在你会有:

'1' 'PLUS' '1' 'END_OF_INPUT'

现在,你可以在你的解析器中定义顶层规则。比如,不再是:

Equation ::= EXPRESSION

你将会有

Equation ::= EXPRESSION END_OF_INPUT

显然,你需要用PLY的语法重新写这些内容,但这样做应该能让你走上正轨。

1

在yacc中,有一个内置的error标记。通常你会这样写:

line: goodline | badline ;

badline : error '\n' /* 如果需要,可以在这里处理错误 */

goodline : equation '\n' ;

任何不符合equation的行都会被badline处理。

你可能想在错误处理的动作中使用yyerrok,这样可以确保下一个行的错误处理会被重置。

撰写回答