使用lex / yacc对遗留数据进行标记

时间:2009-05-08 18:23:40

标签: python yacc lex ply

请原谅我,我对解析和lex / yacc完全不熟悉,而且我可能已经超越了我的想法,但仍然如此:

我正在用PLY编写一个非常基本的计算器,但它的输入可能并不总是一个等式,我需要在解析时确定它是否存在。输入的极端情况可以完美地评估一个方程式,它可以很好地解析并计算,或者某个类似于方程式的东西,它无法解析并且也很好。

灰色区域是一个输入,具有类似等式的部分,解析器将抓取并计算出来。这不是我想要的 - 我需要能够判断字符串的某些部分是否被拾取和标记化,这样我就可以抛出错误,但我不知道该怎么做。

有没有人知道我如何定义,基本上是'抓住任何剩下的'令牌?或者有更好的方法可以解决这个问题吗?

4 个答案:

答案 0 :(得分:1)

yacc中有一个内置的error令牌。你通常会这样做:

line: goodline | badline ;

badline : error '\n' /* Error-handling action, if needed */

goodline : equation '\n' ;

任何与equation不匹配的行都将由badline处理。

您可能希望在错误处理操作中使用yyerrok,以确保为下一行重置错误处理。

答案 1 :(得分:1)

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

所以以前,如果你有这些令牌:

'1' 'PLUS' '1'

你现在有:

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

现在,您可以在解析器中定义顶级规则。而不是(例如):

Equation ::= EXPRESSION

你会有

Equation ::= EXPRESSION END_OF_INPUT

显然你必须在PLY语法中重写这些,但这应该可以帮到你。

答案 2 :(得分:0)

我通常使用一个单独的'命令阅读器'来获取一个完整的命令 - 可能是你的情况下的一行 - 变成一个主变量字符串,然后安排词法分析器分析字符串,包括告诉我它什么时候没有'到达终点。这很难设置,但使一些错误报告类更容易。我使用这种技术的地方之一通常有多行命令,有3个注释约定,两组带引号的字符串,还有一些其他的东西可以让我站稳脚跟(上下文敏感的标记化 - 哎呀!)。

否则,Don对Yacc'错误'令牌的建议很好。

答案 3 :(得分:0)

看起来您已经找到了解决方案,但我会添加另一个建议,以防您或其他人对替代方法感兴趣。

你说你正在使用PLY,但是因为你希望编译器在Python环境中运行吗?如果是这样,您也可以考虑其他工具。对于这样的工作,我经常使用具有Python代码生成器的ANTLR(http://www.antlr.org)。 ANTLR有许多技巧,比如在词法分析器级别吃一堆输入,这样解析器就不会看到它(例如注释),能够在更大的语法中调用子规则(例如方程式)(应该终止一次规则已经匹配,没有处理任何更多的输入...听起来有点像你想做的事情)和一个非常好的左因子算法。

ANTLRs解析功能与使用StringTemplate(http://www.stringtemplate.org)引擎相结合,是一个很好的组合,并且都支持Python(以及其他许多)。