繁体   English   中英

不同的解析算法之间的运行时差异是什么?

[英]What is the runtime difference between different parsing algorithms?

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

或者换句话说 - 哪种算法表现最好,假设语法可以用于任何算法?

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

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

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

GLR解析器是LR解析器的推广,因此必须比LR解析器慢。 一个关键的观察是,大多数时候GLR解析器的行为与LR解析器完全相同,并且可以使该部分基本上以与LR解析器相同的速度运行,因此它们可以相当快。

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

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

  • GLR(非常简单:如果你可以编写grammmar规则,你可以解析)
  • LR(k)(许多语法适合,极少数解析器生成器)
  • LR(1)(最常见的[YACC,Bison,Gold,...]
  • LL(通常需要重大的语法重新设计以消除左递归)
  • 手动编码的递归下降(简单的语法易于编码;难以处理复杂的语法,如果语法变化很大,难以维护)

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

1989年,我将论文中定义的矩阵解析器表“优化便携式编译器的解析表”与YACC解析器表(梳状结构)进行了比较。 这些都是LR或LALR解析器表。 我发现矩阵解析器表的速度通常是梳形解析器表的两倍。 这是因为非终结转换(转到动作)的数量通常约为终端转换数量的两倍。 矩阵表具有更快的非终结转换。 但是,除了状态转换之外,解析器还有许多其他的事情,所以这可能不是瓶颈。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM