使用参考手册语法时,Pyparsing Ada 2005 作用域标识符导致堆栈溢出

3 投票
1 回答
606 浏览
提问于 2025-04-17 19:14

我现在正在用Pyparsing和参考手册中的语法规则实现一个Ada 2005的解析器。我们需要这个解析器来分析和转换我们老旧的Ada代码库中的部分代码到C/C++。

大部分功能都正常。

不过,有一个小问题让我很烦恼:

在解析带作用域的标识符时,语法规则name(规则selected_component)在处理像"Global_Types.Integer2"这样的表达式时出错,因为它陷入了一个左关联的语法规则循环。

我觉得这个规则写得不太对:子规则direct_name应该放在子规则direct_name之后。实际上,它应该放在所有选择的最后。否则,direct_namename会匹配到"Global_Types",然后就期待字符串在那之后结束。这不是我想要的结果。

所以我现在把规则direct_name移动到name的选择最后……但这样我反而遇到了Pyparsing的无限递归,Python报出最大递归深度超限的错误。

我认为问题可能是由于以下原因造成的:

  • 语法规则selected_component的关联性是从右到左的。我查阅了Pyparsing的参考手册,但没有找到相关的信息。我们应该把点号(.)当作一个从右到左的操作符,还是可以通过扩展和重构语法规则来解决这个问题呢?

  • 或者是因为Pyparsing没有检查无限递归。我觉得实现这个检查并不难。可以使用一个映射,将当前活动的规则(函数)与源位置/偏移量(getTokensEndLoc())关联起来,如果当前源输入的位置/偏移量等于刚进入的规则相关的位置,就总是让这个规则失败。

使用pyparsing的递归表达式可能和我的问题有关。

这个问题似乎也和解析Python语法的一部分密切相关,但不幸的是还没有答案。

这是导致无限递归的Ada 2005语法规则循环:

请注意,这个问题并不是Ada特有的,而是与所有包含左递归规则的语法相关。

1 个回答

1

作为参考,在GNAT: GNU Ada 编译器中提到,§2.2 解析器,"Ada 的语法在ARM中是模糊的,因此一个基于表的解析器必须修改语法,才能使其适用于 LL (1) 或 LALR (1) 的技术。"

撰写回答