用lex/yacc对剩余数据进行词法分析
请原谅我,我对解析和lex/yacc完全是新手,可能有点超出我的能力范围,但我还是想说:
我正在用PLY写一个比较简单的计算器,但它的输入不一定总是一个方程式,我需要在解析时判断它是否是方程式。输入的极端情况可能是一个完美的方程式,这样解析和计算都没问题;或者是完全不像方程式的东西,这样解析失败也没关系。
问题在于,有些输入看起来像方程式的一部分,解析器会抓取并处理这些部分。这不是我想要的——我需要能够判断字符串中有没有部分没有被识别和处理,这样我才能抛出错误,但我不知道该怎么做。
有没有人知道我该如何定义一个“捕捉剩余部分”的标记?或者有没有更好的方法来处理这个问题?
4 个回答
我通常会使用一个单独的“命令读取器”来获取完整的命令——在你的情况下可能就是一行命令——然后把这个命令放到一个主机变量字符串里,再安排词法分析器来分析这个字符串,包括告诉我什么时候没有到达字符串的末尾。这种设置比较复杂,但可以让某些错误报告变得更简单。我常用这种方法的地方是处理多行命令,这些命令有三种注释方式、两种引号字符串,还有一些其他让人头疼的东西(上下文敏感的标记化——真让人受不了!)。
除此之外,Don关于Yacc的“错误”标记的建议也很好。
定义一个标记(输入结束),并让你的词法分析器在输入结束时输出它。
之前,如果你有这些标记:
'1' 'PLUS' '1'
现在你会有:
'1' 'PLUS' '1' 'END_OF_INPUT'
现在,你可以在你的解析器中定义顶层规则。比如,不再是:
Equation ::= EXPRESSION
你将会有
Equation ::= EXPRESSION END_OF_INPUT
显然,你需要用PLY的语法重新写这些内容,但这样做应该能让你走上正轨。
在yacc中,有一个内置的error
标记。通常你会这样写:
line: goodline | badline ;
badline : error '\n' /* 如果需要,可以在这里处理错误 */
goodline : equation '\n' ;
任何不符合equation
的行都会被badline
处理。
你可能想在错误处理的动作中使用yyerrok
,这样可以确保下一个行的错误处理会被重置。