这是一个很长的问题,我希望你们有耐心。在
我正在写一个程序,检查一个分子式的语法是否正确。在
我有一个BNF语法:
<formel>::= <mol> \n
<mol> ::= <group> | <group><mol>
<group> ::= <atom> |<atom><num> | (<mol>) <num>
<atom> ::= <LETTER> | <LETTER><letter>
<LETTER>::= A | B | C | ... | Z
<letter>::= a | b | c | ... | z
<num> ::= 2 | 3 | 4 | ...
这是我的密码:
^{pr2}$现在代码应该接受某些给定的公式,并为某些给定的错误公式提供错误代码。让我们看看这些公式:
正确: 硅(C3(COOH)2)4(H2O)7
不正确: 水)铁
(Cl)2)3
程序接受正确的公式,但不幸的是也接受了错误的公式。这是因为if语句在:
if not q.peek() == ")":
try:
readMol()
except FormelError:
pass
使其能够使向右不平衡的括号(右侧有一个或多个括号太多)从代码中滑出,而不是被检测为“组”的错误开头。当Si(C3(COOH)2)4(H2O)7仍然被接受为语法正确的时候,我该如何解决这个问题呢?在
感谢您的耐心:)
你的readMol代码对“)”有一个错误的测试(你甚至告诉过我们)。如果您正在编写recursive descent parser,那么您的语法不需要这样的测试。在
事实上,你的语法对mol有一个奇怪的规则:
这在递归下降解析器中不能很好地工作。您已经重构了这些规则,以共享每个规则中的公共前缀。在这种情况下,很容易:
^{pr2}$然后直接根据语法规则编写代码(参见上面的链接) [除了“)”支票之外,你也这样做了。] 应该是这样的(我不是python专家):
在编写递归下降解析器时,首先将语法转换成最兼容的形式(就像我对您的mol规则所做的那样),这很有帮助。然后对单个识别器进行编码是一项很难出错的纯机械任务。在
相关问题 更多 >
编程相关推荐