3

原谅我,我对解析和 lex/yacc 完全陌生,我可能有点不知所措,但尽管如此:

我正在用 PLY 编写一个非常基本的计算器,但它的输入可能并不总是一个方程,我需要在解析时确定它是否是。输入的极端情况是可以完美地评估为方程,它可以很好地解析和计算,或者与方程完全不同,它解析失败并且也很好。

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

有谁知道我如何定义,基本上,一个“抓住任何剩下的东西”令牌?还是有更好的方法可以处理这个问题?

4

4 回答 4

1

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

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

'1' 'PLUS' '1'

您现在将拥有:

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

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

Equation ::= EXPRESSION

你会有

Equation ::= EXPRESSION END_OF_INPUT

显然,您必须用 PLY 语法重写这些,但这应该可以帮助您完成大部分工作。

于 2009-05-11T06:31:03.463 回答
1

yacc中有一个内置error令牌。您通常会执行以下操作:

line: goodline | badline ;

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

goodline : equation '\n' ;

任何不匹配的行equation将由badline.

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

于 2009-05-08T23:33:39.680 回答
0

我通常使用一个单独的“命令阅读器”来获取一个完整的命令——在你的情况下可能是一行——进入一个主变量字符串,然后安排词法分析器来分析这个字符串,包括告诉我它什么时候没有到达结尾。这很难设置,但会使某些类别的错误报告更容易。我经常使用这种技术的地方之一是多行命令,带有 3 个注释约定、两组引用的字符串,以及一些其他让我难以接受的讨厌的东西(上下文敏感的标记化 - 糟糕!)。

否则,Don 对 Yacc 'error' 令牌的建议是好的。

于 2009-05-09T00:06:45.560 回答
0

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

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

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

于 2009-05-12T14:51:13.653 回答