现代语言是否仍使用解析器生成器?


38

我是研究关于gcc编译器套件在维基百科这里,当这想出了:

GCC开始使用由Bison生成的LALR解析器,但后来逐渐切换为手写递归下降解析器。2004年用于C ++,2006年用于C和Objective-C。目前,所有前端都使用手写递归下降解析器

因此,在最后一句话中,(以及我所信任的维基百科),我可以肯定地说:“ C(gcc),C ++(g ++),Objective-C,Objective-C ++,Fortran(gfortran),Java(gcj), Ada(GNAT),Go(gccgo),Pascal(gpc),... Mercury,Modula-2,Modula-3,PL / I,D(gdc)和VHDL(ghdl)”都是前端,不再使用解析器生成器。也就是说,它们都使用手写的解析器。

我的问题是,这种做法无处不在吗?具体来说,我在[Python,Swift,Ruby,Java,Scala,ML,Haskell]中寻找x的“ x的标准/官方实现是否具有手写的解析器”的确切答案?(实际上,这里也欢迎提供其他语言的信息。)我敢肯定,经过大量的挖掘,我可以自己找到它。但是,我也相信社区很容易对此负责。谢谢!


3
数据点:CPython具有家用Brew LALR解析器生成器(pgen)。不知道其余的。

8
数据点:Ghc(haskell)使用LALR解析器生成器(happy),OCaml也是如此。
Twan van Laarhoven 2014年

1
应该是“使用现代高性能编译器...”或类似名称,因为该语言不是规格,而是实现,而编译器则使用或不使用机器生成的解析器。
dmckee 2014年

@dmckee,是的,您是正确的。但是,命名开始变得冗长而少了点。如果您比我更有创造力,请随时进行编辑!
eatonphil 2014年

关于ML:MLton使用了特定于ML的解析器生成器,尽管我对此不太熟悉,但我90%确信SML / NJ也会这样做。您可能想要也可能不想考虑“手写”。
Patrick Collins 2014年

Answers:


34

AFAIK,GCC特别使用手写解析器来改进语法错误诊断(即,在语法错误方面提供有意义的人性化消息)。

解析理论(及其衍生的解析生成器)主要是关于识别和解析正确的输入短语的。但是我们希望编译器针对一些错误的输入给出有意义的错误消息(并且能够在语法错误之后有意义地解析其余的输入)。

同样,旧的旧式语言(例如C11或C ++ 11)(在概念上是旧的,即使它们的最新修订版只有三年之久)也不是完全没有上下文的。对于解析器生成器(即bison甚至menhir)在语法中处理上下文相关性非常困难。


2
同意。从解析错误中恢复良好(当您不想在第一个错误时停止解析,例如旧的Borland Pascal)并创建高质量的错误消息(包括解析和提示,就像人类想要的一样)都是固有的上下文敏感的启发式任务。可以在股票解析器生成器输出的顶部完成这些操作,但这只是一个口号。
乔纳森·尤尼斯

2
Dealing with that context sensitiveness in grammars for parser generators is boringly difficult。随着这些工具生成无上下文的解析器,这几乎是不可能的。如果使用的是此类工具,则生成解析树之后,检查是否存在所有上下文相关约束的正确位置。
dtech 2015年

7

解析器生成器和解析器引擎非常通用。通用性的优点是,在整体方案中,快速构建准确的解析器并使之易于操作很容易。

解析器引擎本身由于其通用性而在性能方面受到影响。任何手写代码总是比表驱动解析器引擎快得多。

解析器生成器/引擎难以解决的第二个方面是,所有真正的编程语言通常都是以非常微妙的方式对上下文敏感的。LR语言是无上下文的,这意味着在定位和环境方面存在许多无法在语法中正确传达的细节。属性语法尝试解决基本语言规则,例如“使用前声明”等。将这种上下文相关性连接到手写代码中是很简单的。


15
请引用性能要求?由表驱动可能是一项重要的性能优化,并且生成器可以访问非常高效的算法,但实际上从来没有手动实现过(确切的说,因为它们是表和魔术数的难以理解的混乱)。

2
关于第二个方面:许多主要的实际编程语言在任何适用的意义上都不是上下文敏感的(在类型检查等之后,您必须引用所有有效程序的集合,而这绝不是手写的或生成的解析器尝试解析)。的确,手写解析器更灵活,并且对某些语言很有用,但主要用于错误恢复和报告,增量性等方面。由于识别能力的缘故,解析器生成器很少被忽略(无论您是否愿意想要写这样的语法是另外一个故事)。-1

如果在解析过程中使用符号表信息,则最好将其称为上下文相关。属性语法绝对不是上下文无关的,尽管我认为它们不是完全上下文敏感的。关于错误恢复和报告的其他观点也很恰当。
BobDalgleish 2014年

1
C和C ++在解析过程中需要符号表信息(或接受不那么具体的解析树,在其中不区分例如表达式语句和变量声明)。但是我没有想到这些。诸如Java,Lips,JavaScript,Ruby,Python,Go,Rust,Scala,Swift,Haskell等语言(可能还有其他几种语言,也许还有C#和ML吗?)不需要任何此类信息即可构建所需的AST。反正想要。它们中的许多实际上具有LL(1)语法,甚至具有LALR语法。

1
对所有真实语言的引用都取决于上下文吗?
psr
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.