【问题标题】:How many ways are there to build a parser? [closed]有多少种方法可以构建解析器? [关闭]
【发布时间】:2017-01-02 13:37:51
【问题描述】:

我正在学习 ANTLR v4,它是一个基于所谓的自适应 LL(*) 算法的解析器生成器。号称比 LL(*) 算法有很大的改进,但我也听说过一些类似 LR 的算法。

ANTLR 的 Adaptive LL(*) 算法(相对于 LR)有什么优势/局限?

【问题讨论】:

  • 关于这个主题已经写了整本书,恐怕这个问题对 SO 来说太宽泛了。
  • 你能推荐一些关于这个主题的书吗?谢谢。
  • 恕我直言,创建各种语法和词法分析器/解析器的主题更具学术性而非实际意义。在编译器中完成的大部分工作和花费的时间都在“优化器”中。
  • 据我记得,ANTLR 参考并没有深入到算法的核心,但我很确定 Terrence Parr 一定发表了一篇关于 ALL(*) 的论文。至于经典的 LL、LR、LALR 等请看“龙书”(注意:本质上非常数学/学术)。
  • 这个问题实际上毫无意义。任何人都可以编写自己的解析器生成器,或者确实发明自己的(可能不正确的)解析算法。没有办法列举这些,这样做也毫无意义。

标签: parsing compiler-construction antlr ll lr


【解决方案1】:

有多少现代算法可以构建解析器?

首先可以查看常用解析器生成器的列表。
请参阅:Comparison of parser generators 并查看标题 Parsing algorithm

ALL(*)  
Backtracking Bottom-up  
Backtracking LALR(1)  
Backtracking LALR(k)  
GLR  
LALR(1)  
LR(1)  
IELR(1)  
LALR(K)
LR(K)  
LL  
LL(1)
LL(*)  
LL(1), Backtracking, Shunting yard
LL(k) + syntactic and semantic predicates  
LL, Backtracking  
LR(0)  
SLR  
Recursive descent  
Recursive descent, Backtracking  
PEG parser interpreter, Packrat  
Packrat (modified)  
Packrat  
Packrat + Cut + Left Recursion  
Packrat (modified), mutating interpreter  
2-phase scannerless top-down backtracking + runtime support  
Packrat (modified to support left-recursion and resolve grammar ambiguity)  
Parsing Machine  
Earley  
Recursive descent + Pratt  
Packrat (modified, partial memoization)  
Hybrid recursive descent / operator precedence  
Scannerless GLR  
runtime-extensible GLR  
Scannerless, two phase  
Combinators  
Earley/combinators  
Earley/combinators, infinitary CFGs  
Scannerless GLR  
delta chain  

除了解析器生成器之外,还有其他算法/方法可以解析。特别是 Prolog 有DCG,大多数没有经过正式培训就从零开始编写第一个解析器的人通常以recursive descent 开头。还有Chart parserLeft corner parser

在编写解析器时,我总是问自己的第一个问题是如何为Chomsky hierarchy 中最高类型的语言编写语法。这里最低的是Type-0,最高的是Type-3。

几乎 90% 的时间它是 Type-2 语法 (context-free grammars),然后对于更简单的任务它是 Type-3 语法 (regular grammars)。我已经尝试过 Type-1 语法 (context-sensitive grammars) 甚至 Type-0 语法 (unrestricted grammars)。

ANTLR 的 Adaptive LL(*) 算法的优势/局限是什么?

参见Terrence ParrAdaptive LL(*)的创建者写的论文: Adaptive LL(*) Parsing: The Power of Dynamic Analysis

实际上,Adaptive LL(*) 可以让您更快地从语法转换为可以工作的解析器,因为您不必了解太多的解析理论,因为Adaptive LL(*) 是,容我说,足够灵活,可以在不知不觉中绕过地雷放在语法中。这样做的代价是,您在语法中无意中放置的一些地雷会导致解析器运行时效率低下。

对于大多数实用的编程语言目的,Adaptive LL(*) 就足够了。 IIRC Adaptive LL(*) 不能执行 Prolog DCG 可以的 Type-0 语法 (unrestricted grammars),但正如我所说,大多数人和最常见的编程任务只需要类型 2 或类型 3。

大多数解析器生成器也适用于类型 2,但这并不意味着它们不能执行类型 1 或可能的类型 0。我不能更具体,因为我对所有这些都没有实际经验。

每当您使用解析工具或库时,都有一个学习曲线来学习如何使用它以及它可以做什么和不能做什么。

如果您不熟悉词法分析/解析并且真的想进一步了解它,请参加课程和/或阅读Compilers: Principles, Techniques, and Tools (2nd Edition)

【讨论】:

  • 是的,但是您真正想要的是一个解析器生成器引擎,它涵盖了最广泛的语言范围,并且工作量最小。实际上,GLR 在这方面做得非常好(任意上下文无关语法),并且可以在许多工具中使用。 GLL 同样不错,但很难找到。 Earley 还可以,但效率不高,至少它相对容易编码。其他一切都与真正的语法有问题;您只需要在您陷入哪个解析坑以及为您的特定语法爬出该坑需要多少工作之间进行选择。包括 ANTLR。
  • 我喜欢@IraBaxter 的说法,you are only choosing between which parsing pit you fall into, and how much work it takes to climb out the pit for your particular grammar. Including ANTLR
猜你喜欢
  • 2016-10-23
  • 2020-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-17
  • 1970-01-01
  • 2018-08-09
  • 1970-01-01
相关资源
最近更新 更多