python - 解析算法中解决优先级的方法
问题描述
我正在研究解析,更准确地说是解析器组合器,我遇到了优先级和关联性问题。
我找到的第一个解决方案是在语法中表达优先级。但这似乎使语法复杂化。由于我正在处理解析器组合器,因此我希望将语法表达为函数组合。我得到的第一个解决方案是这样的
expr = or(sequence(int, regex("[+-]"), expr),
int)
int = regex("\d+")
此处or
并在 BNF 语法中sequence
模拟和多个术语。|
_这是非常假设的,如果有兴趣的话,真正的来源是这里的 Rust。我的问题更具理论性......这里还有一个更易于管理的python版本_
我想知道的另一个选择是。只需按原样解析输入,然后进行第二次运行简化它,简化是指也解决优先级和关联问题。我没有发现有人这样做,所以我来到了这里。
我想做这样的事情,假设我解析这个输入a * b + c
并输出这样的东西
[
a,
Op(*, p=0),
[
b,
Op(+, p=1),
[
c
]
]
]
然后使用它p
(从优先级)创建正确的树。这样做我可以创建非常声明性的语法,例如sum = or(sequence(term, op('+', 1), sum), term)
. 我担心这会变得太慢而无法运行,因为树上有多次遍历。
我的第三个想法,而我不知道如何以令人满意的方式实施的这个想法是将两者混合。保留组合器,但在它们中间添加一些简化逻辑,在一些关键点(但在分离的函数中)可以在构建树时修复它,我尝试了类似的方法来删除终端和嵌套序列。
我还缺少其他方法吗?这是一个总结
- 在语法中表达优先逻辑
- 生成整个树并在后面固定优先级
- 生成部分树并在生成树时逐步修复优先级
一些问题:
- 大型编译器通常采用什么方法?我知道 C 需要 (1) 而 python 也需要 (1) 之类的东西。
- 2 和 3 是否具有相同的计算成本?(对我来说,3 似乎更轻,因为它必须访问更少的节点,但我的猜测是在最坏的情况下它会花费高达 2)。
最后感谢您在这里阅读。
解决方案
推荐阅读
- css - 如何在 Bootstrap v 4.5.x CDN 中启用 RFS
- c# - Azure Functions 事件中心读写延迟峰值与 StorageException 和 SocketException 峰值
- bash - 打印从文本派生的所有链接
- mysql - MySQL Query 在较新的服务器版本上给出错误 #1054
- java - 将自定义规则添加到声纳门
- haskell - Reader monad中本地和询问功能的目的是什么
- sass - Foundation 电子邮件 - 导入所有样式
- javascript - 当键入为 [key: string] 时,Typescript 不检查对象属性是否存在
- git - ST 终端显示“?” 对于电力线 git 状态
- batch-file - 一个批处理脚本中的腻子连接和远程桌面连接