繁体   English   中英

Haskell 中的广义自底向上解析器组合器

[英]Generalized Bottom up Parser Combinators in Haskell

我想知道为什么在 Haskell 中没有用于自下而上解析的通用解析器组合器,如用于自上而下解析的 Parsec 组合器。
(我可以找到一些研究工作在 2004 年进行,但之后就什么也没有了
https://haskell-functional-parsing.googlecode.com/files/Ljunglof-2002a.pdf http://www.di.ubi.pt/~jpf/Site/Publications_files/technicalReport.pdf )

没有实现它有什么具体原因吗?

这是因为引用透明。 正如没有函数可以区分

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

由于 luqui 的回答表明自下而上的解析器组合器库是不现实的。 如果有人访问此页面只是寻找 haskell 的自底向上解析器生成器,那么您正在寻找的内容称为Happy parser generator 这就像haskell的yacc

正如 luqui 上面所说:Haskell 对递归解析器定义的处理不允许自底向上解析库的定义。 但是,如果您以不同的方式表示递归语法,则可以使用自下而上的解析库。 为自我宣传道歉,使用这种方法的一个(研究)解析器库是语法组合器 它实现了一种称为统一 Paull 变换的文法变换,该变换可以与自顶向下的解析器算法相结合,以获得原始文法的自底向上的解析器。

@luqui 本质上说,在某些情况下无法观察到共享。 然而,一般情况并非如此:存在许多可观察共享的方法。 例如http://www.ittc.ku.edu/~andygill/papers/reifyGraph.pdf提到了几种不同的方法来实现可观察共享,并提出了自己的新方法:

这种循环结构可用于解释,但不能用于进一步分析、漂亮打印或一般处理。 这里的挑战,也是本文的主题,是如何允许从 Haskell 托管的深度 DSL 中提取的树具有可观察的后端,或者更一般地说,可观察的共享。 这是一个很好理解的问题,有许多标准的解决方案。

请注意,论文中以显式标签的名义提到了@liqui 的“丑陋”解决方案。 该论文提出的解决方案仍然“丑陋”,因为它使用了所谓的“稳定名称”,但其他解决方案如http://www.cs.utexas.edu/~wcook/Drafts/2012/graphs.pdf (其中依赖 PHOAS)可能有效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM