Parsing 可以处理歧义的解析器库

Parsing 可以处理歧义的解析器库,parsing,scala,haskell,Parsing,Scala,Haskell,我正在为Scala或Haskell寻找一个成熟的解析器库。 最重要的一点是,库可以处理歧义。 如果一个表达式是不明确的,我需要与该表达式匹配的所有可能的抽象语法树。 简单示例:表达式a⊗ B⊗ c可以看作是(a⊗ (b)⊗ c或a⊗ (b)⊗ c) ,我需要两种变体。 谢谢 我觉得自己就像一个老家伙,因为我记得瓦尔德的论文《理解单子》(do记谱法的前身)是令人兴奋和新颖的。其思想是(引用)将失败替换为成功列表,这意味着维护一个包含所有可能解析的列表。在比赛结束时,你通常只参加第一场比赛,但通过这

我正在为Scala或Haskell寻找一个成熟的解析器库。 最重要的一点是,库可以处理歧义。 如果一个表达式是不明确的,我需要与该表达式匹配的所有可能的抽象语法树。 简单示例:表达式a⊗ B⊗ c可以看作是(a⊗ (b)⊗ ca⊗ (b)⊗ c) ,我需要两种变体。
谢谢

我觉得自己就像一个老家伙,因为我记得瓦尔德的论文《理解单子》(do记谱法的前身)是令人兴奋和新颖的。其思想是(引用)将失败替换为成功列表,这意味着维护一个包含所有可能解析的列表。在比赛结束时,你通常只参加第一场比赛,但通过这种设置,你可以参加所有比赛

对于确定性解析器来说,这些并不是那么有效,这就是为什么它们不那么流行的原因,但它们正是您所需要的

看看,尤其是
Text.ParserCombinators.HuttonMeijer
Text.ParserCombinators.HuttonMeijerWallace

(Hutton&Meijer将解析器库翻译成Haskell(来自Gofer),Wallace添加了额外的功能。)

确保您可以在简单的情况下查看它,例如使用解析
“aaaa”

testP = do
   a <- many $ char 'a'
   b <- many $ char 'a'
   return (a,b)
testP=do

a我不能说它有多成熟,也不能给出任何使用示例,但我已经让scala库在选项卡中打开了几天。这个问题立刻让我想起了2010年底的辩论。Yacc的作者是一篇死论文,提供了Scala(未维护)、Haskell和Racket中的一篇文章。在Yacc is alive响应中,Russ Cox指出,对于模棱两可的语法,代码以指数时间运行

众所周知,在
O(n^3)
中解析歧义语法是可能的,尽管很明显,如果解析树的数量是指数级的,那么枚举所有解析树可能需要指数级的时间,而在
x1+x2+x3…+xn
bison
实现了GLR算法,这样做;不幸的是,
bison
当然是成熟的(如果不是濒临死亡的话),但它既不是用Haskell编写的,也不是用Scala编写的


Daniel Spiewak在Scala IIRC中实现了一个GLL解析器,但上次我看到它时,它遇到了一些性能问题。因此,我也不确定它是否可以说是成熟的。

最后,选择的是语法定义形式主义() 使用sdf表格生成器
作为解析器生成器。

我想这将是一项艰巨的任务。我使用的解析器生成器(支持一定程度的歧义)都只是创建了一个parse/AST。通常是第一次成功的解析。此外,如果输入源足够大(并且语法不明确),将有大量可能的解析…您可以使用parsec之类的库,解析到
[AST]
,而不仅仅是
AST
。显然,这意味着您必须手工编写所有不同的歧义选项,并在每个级别管理子结果的合并。但是,您可能可以使用
ParsecT
做一些事情,事实上,它是一个monad转换器,可以稍微简化一些事情。(这只是一个猜测,它需要比我更有知识的人。)@schlicht我不知道你对什么理解为“成熟”,但是一个最小的解析器库可以为任何特定表达式生成所有可能的结果,它可以用大约30行haskell代码编写。我知道这一点,因为这是我在一些我现在找不到的文章之后写的第一个单子。库比克:可以肯定的说,这样一个库不算成熟。显然,如果存在一个成熟的库,那么使用它的理由有很多。Happy的GLR解析应该处理歧义(这是GLR的卖点)。Happy是一个Haskell预处理器而不是一个库,而且与“常规”Happy.Preco(Daniel和我工作的公司)相比,GLR支持似乎还不够成熟。我们的产品在性能上非常关键,GLL在性能和成熟度上都与之保持一致。Russ Cox的指数时间示例是错误的,但其他不太自然的示例确实存在。Bison真的能处理语法歧义吗?@sergey:Bison的GLR实现坚持解决歧义,但在如何解决歧义方面是灵活的;一种可能性是创建解析林。所以在某种意义上,它可以处理歧义,但它在指数歧义方面不是很好,因为它没有实现一个图形结构的堆栈。乍一看很好看。但软件包的第一个版本是从2015年开始的,问题是从2012年开始的。