【问题标题】:What is the runtime difference between different parsing algorithms?不同解析算法之间的运行时差异是什么?
【发布时间】:2011-04-24 18:36:13
【问题描述】:

那里有许多不同的解析算法(递归下降、LL(k)、LR(k)、LALR,...)。我找到了很多关于不同类型的解析器可以接受的不同语法的信息。但是它们在运行时行为上有什么不同呢?哪种算法更快,使用更少的内存或堆栈空间?

或者换一种说法——假设语法可以与任何算法一起使用,哪种算法性能最好?

【问题讨论】:

标签: algorithm parsing language-agnostic


【解决方案1】:

LR 解析器恕我直言,可能是最快的。基本上,他们使用令牌作为前瞻集或转换表的索引来决定下一步做什么(推送状态索引,弹出状态索引/调用缩减例程)。转换为机器代码,这可能只是一些机器指令。 Pennello 在他的论文中详细讨论了这一点:

Thomas J. Pennello:非常快的 LR 解析。 SIGPLAN 编译器构建研讨会 1986:145-151

LL 解析器涉及递归调用,这比简单的表查找要慢一些,但它们可以非常快。

GLR 解析器是 LR 解析器的泛化,因此 必须 比 LR 解析器慢。一个关键的观察结果是,在大多数情况下,GLR 解析器的行为与 LR 解析器完全相同,并且可以使该部分的运行速度与 LR 解析器基本相同,因此它们可以相当快。

您的解析器可能会花费更多时间将输入流分解为标记,而不是执行解析算法,因此这些差异可能并不重要。

在将语法转化为可用形式方面,以下是解析技术“使其变得容易”的顺序:

  • GLR(真的很简单:会写语法规则就可以解析)
  • LR(k)(适合许多语法,解析器生成器极少)
  • LR(1)(最常用的 [YACC、Bison、Gold...]
  • LL(通常需要对语法进行大量重新设计以删除左递归)
  • 手工编码的递归下降(简单语法易于编码;复杂语法难以处理,如果语法变化很大,则难以维护)

【讨论】:

  • LL 解析器不需要递归。它们可以用表来实现。 LR 和 LL 都是 O(N)。
  • 当算法都是 O(n) 时,constant 因素很重要。 Pennello 的方法建设性地构建了 LR 解析器,每个令牌实际上只执行几条机器指令。 Turbo Pascal,IIRC 使用递归下降解析器,并且速度非常快,尽管没有实际分析它是否会针对每个令牌命中几条机器指令。因此,这实际上取决于您如何努力推动解析速度的工程。但首先要优化的关键是令牌提取,因为每个字符很难不花费一些机器指令。
【解决方案2】:

我研究了 LRSTAR 和 YACC 之间的 LR 解析器速度。

1989 年,我将论文中定义的矩阵解析器表"Optimization Of Parser Tables For Portable Compilers" 与 YACC 解析器表(梳状结构)进行了比较。这些都是 LR 或 LALR 解析器表。我发现矩阵解析器表的速度通常是梳状解析器表的两倍。这是因为非终结转换(goto 动作)的数量通常是终结转换数量的两倍左右。矩阵表具有更快的非终结转换。但是,除了状态转换之外,解析器中还有许多其他事情发生,因此这可能不是瓶颈。

在 2009 年,我将矩阵词法分析器表与 flex 生成的词法分析器表以及 re2c 生成的直接代码词法分析器进行了比较。我发现矩阵表的速度大约是 flex 生成表的两倍,几乎与 re2c 词法分析器代码一样快。矩阵表的好处是它们比直接代码表编译得更快,而且它们更小。最后,如果您允许矩阵表非常大(没有压缩),它们实际上可以比直接代码 (re2c) 表更快。有关显示比较的图表,请参阅:the LRSTAR comparison page

使用 LRSTAR 构建的编译器前端(无预处理)每秒处理大约 2,400,000 行代码,其中包括在解析和词法分析时构建符号表和抽象语法树。使用 DFA 构建的词法分析器每秒处理 30,000,000 个令牌。使用 DFA 时,矩阵表驱动的词法分析器还有另一个优势。词法分析器骨架可以用汇编语言重写。当我在 1986 年这样做时,词法分析器的速度是 C 代码版本速度的两倍。

我对 LL 解析器速度或递归下降解析器速度没有太多经验。对不起。如果 ANTLR 可以生成 C++ 代码,那么我可以对其解析器进行速度测试。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-07
    • 1970-01-01
    • 2020-11-13
    • 2018-07-25
    • 2015-07-28
    • 1970-01-01
    • 2013-07-12
    相关资源
    最近更新 更多