这是因为参照透明性。就像没有函数可以区分
let x = 1:x
let x = 1:1:1:x
let x = 1:1:1:1:1:1:1:1:1:... -- if this were writeable
没有任何函数可以区分有限图文法和无限树文法之间的区别。自下而上的解析算法需要能够将语法视为图形,以便枚举所有可能的解析状态。
自上而下的解析器将其输入视为无限树这一事实使它们更强大,因为树在计算上可能比任何图都更复杂;例如,
numSequence n = string (show n) *> option () (numSequence (n+1))
接受任何从 开始的有限升序数字n
。这有无数种不同的解析状态。(也许可以用上下文无关的方式来表示它,但我认为这会很棘手,并且需要比解析库能够更多地理解代码)
可以编写一个自下而上的组合器库,虽然它有点难看,但它要求所有解析器都以这样的方式“标记”
- 同一个标签总是指同一个解析器,并且
- 只有一组有限的标签
在这一点上,它开始看起来更像是传统的语法规范,而不是组合规范。但是,它仍然可以很好;您只需要标记递归产生式,这将排除任何无限大的规则,例如numSequence
.