作为附带项目,我正在使用Python编写语言。我从使用称为Ply的flex / bison克隆开始,但是在那种语法风格所能表达的功能方面,我处于优势地位,并且由于与阻抗不匹配,我对破解我的语言不感兴趣。工具。因此,我不反对自己编写。
那么,最强大的解析器类型是什么?欢迎引用论文(以及更多介绍性文章)。
(我知道“功能强大”的定义不明确,但让我们稍微放松一点,看看答案在哪里)
作为附带项目,我正在使用Python编写语言。我从使用称为Ply的flex / bison克隆开始,但是在那种语法风格所能表达的功能方面,我处于优势地位,并且由于与阻抗不匹配,我对破解我的语言不感兴趣。工具。因此,我不反对自己编写。
那么,最强大的解析器类型是什么?欢迎引用论文(以及更多介绍性文章)。
(我知道“功能强大”的定义不明确,但让我们稍微放松一点,看看答案在哪里)
Answers:
文法通常被定义为一个上下文无关文法 -一个确切的定义是维基百科的页面上给出的,但是,当它在PLY,这是基于确实它的工作原理相同的野牛,其又基于YACC。
它在这里说PLY使用LALR解析器。从本质上讲,这是一个LR解析器,在该解析器中会压缩查找表,这可能会引入解析冲突,从而降低LR语法的某些表现力(即LR解析器可以解析的上下文无关语法)。如果您想了解解析器这个特定分支和其他解析器的局限性,请在此处概述各种解析技术(LL,LR和其他)。
要回答您的问题:即使语言模棱两可,也存在能够解析任何无上下文语言的解析算法(即,有多种方法可以解释输入):
第一个这样的算法是CYK算法,不幸具有一个运行时间,其中Ñ是输入字符串的长度和| G | 是语法的大小,因此对于解析语言而言是不切实际的。
第二种算法是Earley算法。该算法还能够解析任何上下文无关的语法。尽管该算法需要时间来解析一种模棱两可的语言,但它只需要O (n 2)时间来解析一种模棱两可的语言。另外,对于大多数LR语法,它显然可以在线性时间内工作,并且在左递归语法中,效果特别好。
在这里,您可以找到一篇论文,讨论Earley算法的实际实现(改编)。他们得出结论:“鉴于Earley解析与LALR(1)解析((大致是PLY所做的)相比)的一般性,并且考虑到即使是PEP((Earley算法的实现)),最坏的时间也不会引起注意。用户,这是一个极好的结果”。
解析器的最后一种类型是GLR解析器。这是LR解析的通用版本,能够解析任何上下文无关的语言。
GLR的成熟实现是ASF + SDF。Bison也可以生成GLR解析器,尽管其实现与“标准” GLR算法略有不同。所述Elkhound算法是一个GLR / LALR混合算法。它尽可能使用LALR,并在需要时使用GLR,以便既快速又能够解析任何语法。
除了上下文无关的语法外,还有上下文敏感的语法,但是这些语法通常很难解析,并且不会增加太多的表现力:您可以使用它们做更多的事情,但是对于大多数应用程序,多余的用途并不重要,除非您要解析一种自然的语言。
作为最后一步,存在不受限制的语法。在这一点上,语法是图灵完备的,因此无法给出解析特定语言所花费的时间,这对于大多数解析应用程序是不希望的。几乎不需要额外的电源。如果您确实想使用所有功能,则可以使用语言机器。
最后,实现您自己的解析器生成器并不是一件容易的事,尤其是要使其更快。我个人刚刚完成了自己的flex版本(lexer生成器)的制作,尽管这似乎是在相对简单的算法问题中进行的练习,但是正确起来变得相当复杂,尤其是当我尝试支持Unicode时。考虑使用现有的实现而不是编写自己的实现。
今年在ICFP 2010上的一篇论文,Total Parser Combinators,描述了一个可证明的终止解析器组合器库,并且还确定了在保证解析器能够终止的情况下,“解析器组合器尽可能具有表现力”。不幸的是,我不记得作者为“尽可能表现力”的含义所作的解释,但它显然与您关于“权力”的问题有关。