我正在寻找一个成熟的解析器库,用于Scala或Haskell。 最重要的一点是,库可以处理歧义。 如果表达式不明确,我想要每个可能的抽象语法树,它与表达式匹配。 简单示例:表达式 a⊗b⊗c 可以看作(a⊗b)⊗c 或 a⊗(b⊗c) ,我需要两种变体。 谢谢!
答案 0 :(得分:12)
我觉得,当Walder的文件如“理解Monads”(作为记谱法的前身)令人兴奋和新的时候,我就会想起那个老家伙。这个想法是你(引用)用成功列表替换失败,意味着维护所有可能的解析列表。最后你通常只参加第一场比赛,但是通过这种设置,你可以拿走所有这些。
对于确定性解析器来说,这些并不是那么有效,这就是为什么它们不那么流行,但它们就是你需要的。
查看polyparse,特别是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)
查看它是否具有您所寻求的语义。
你要求成熟。这些库是纯函数式编程遗产的一部分!话虽如此,我称parsec更成熟,即使它更年轻。
(推测:我认为parsec不能做你想要的。它的标准选择组合是确定性的。我没有考虑调整或替换那种行为,我不想让我害怕。)
答案 1 :(得分:4)
这个问题立即让我想起了2010年底的Yacc is dead / No, it's not辩论。 Yacc的作者死了论文提供library在Scala(unmaintained),Haskell和Racket。在 Yacc is alive 响应中,Russ Cox指出代码在模糊语法的指数时间内运行。
众所周知,可以在O(n^3)
中解析模糊语法,尽管很明显,在指数中存在指数级数的情况下,可能需要指数时间来枚举所有解析树 - 并且会是x1 + x2 + x3 ... + xn
的情况。 bison
实现了这样做的GLR算法;不幸的是,虽然bison
肯定是成熟的(如果不是真的垂死),它既不是在Haskell中也不是在Scala中。
Daniel Spiewak在Scala IIRC中实现了一个GLL解析器,但是上次我看过它时遇到了一些性能问题。所以我不确定它是否可以被描述为成熟。
答案 2 :(得分:3)
我不能说它有多成熟或者给你任何用法示例,但我已经在标签中打开scala gll-combinators库几天了。它处理模糊的语法,看起来很漂亮。
答案 3 :(得分:3)