首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用用户定义的运算符优先级进行解析

使用用户定义的运算符优先级进行解析
EN

Stack Overflow用户
提问于 2015-03-22 01:02:33
回答 1查看 830关注 0票数 20

好的,这里有一个问题:假设Haskell允许您定义具有任意操作符优先级的新运算符……如何才能真正解析Haskell源代码?

在解析源代码之前,您无法知道设置了哪些运算符优先级。但在知道正确的运算符优先顺序之前,您无法解析源代码。所以..。嗯,怎么做?

例如,考虑下面的表达式

代码语言:javascript
复制
x *** y +++ z

在解析完模块之前,我们不知道导入了哪些其他模块,因此不知道作用域中可能存在哪些运算符(和其他标识符)。我们当然还不知道他们的先例。但是解析器必须返回一些东西。但是,如果它返回

代码语言:javascript
复制
(x *** y) +++ z

或者它应该返回

代码语言:javascript
复制
x *** (y +++ z)

可怜的解析器没有办法知道。只有在查找将(+++)(***)带入作用域的导入,从磁盘加载该文件,并发现运算符的优先顺序之后,才能确定这一点。显然,解析器本身不会完成所有的I/O操作;解析器只是将字符流转换成AST。

显然,某个地方的某个人已经想出了如何做到这一点。但我解决不了这个问题...有什么提示吗?

EN

回答 1

Stack Overflow用户

发布于 2015-03-22 11:26:27

András Kovács的回答告诉了GHC到底做了什么,但这是有历史的。

实际上,从Haskell 98到Haskell 2010标准有一些假设的变化。在前者的BNF语法中,操作符固定和解析以这样一种方式交织在一起,理论上您可以在固定规则和表达式和缩进块何时结束的规则之间进行一些非常奇怪的交互。(对于后两者,规则本质上是“继续前进,直到你不得不停下来”。)

特别是,您可以重新定义局部运算符及其固定性,以便它的使用恰好属于重新定义的内部where块……所以你得到了一个解析器悖论。我找不到任何旧的例子,但这可能是一个:

代码语言:javascript
复制
let (+) = (Prelude.+)
    infix 9 + -- make the inner + high precedence and non-associative
in 2 + 3 + 4
--       ^ this + cannot parse here as the inner operator, which means
--         the let ... in ... expression should end automatically first,
--         but then it's the standard +, and its fixity says it should parse
--         as part of the inner expression...

在Haskell 2010中,他们正式更改了这一点,以便在正确解析之后在单独的阶段确定运算符固定。

那么,为什么这是一个假设的变化呢?因为所有的编译器作者都已经按照Haskell 2010的方式做了,而且总是这样做,这是为了他们自己的理智。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29185467

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档