【发布时间】:2015-05-24 23:31:30
【问题描述】:
好的,所以这里有一个问题:鉴于 Haskell 允许您定义具有任意运算符优先级的新运算符...如何实际解析 Haskell 源代码?
在解析源代码之前,您无法知道设置了哪些运算符优先级。但是在您知道正确的运算符优先级之前,您无法解析源代码。所以……嗯,怎么样?
例如,考虑表达式
x *** y +++ z
在我们完成对模块的解析之前,我们不知道导入了哪些其他模块,因此不知道哪些运算符(和其他标识符)可能在范围内。我们当然还不知道它们的优先级。但是解析器必须返回 something... 但它应该返回
(x *** y) +++ z
还是应该返回
x *** (y +++ z)
可怜的解析器无法知道。这只能在您找到将(+++) 和(***) 带入范围的导入、从磁盘加载该文件并发现运算符优先级后才能确定。很明显,解析器本身不会做所有的 I/O。解析器只是将字符流转换为 AST。
显然,某个地方的某个人已经想出了如何做到这一点。但我无法解决...有什么提示吗?
【问题讨论】:
-
你可以构建一个包含两个以上孩子的 AST。假设这个特定节点作为子节点获得列表
[x, ***, y, +++, z],然后检查优先级并构建一个二进制节点以在之后替换自己。 (可能有更好的方法)。 -
请注意,您也可以很容易地做到这一点,无需任何技巧,只需进行两次解析,一次获取运算符的固定性和优先级,另一次实际解析源代码。