LL解析器比LR解析器有什么优势?

Ada*_*ter 31 parsing lalr parser-generator ll-grammar lr-grammar

LL解析器比LR解析器有什么优势可以保证它们在今天的解析器生成器工具中相对流行?

根据维基百科,LR解析似乎比LL更有优势:

LR解析可以处理比LL解析更大范围的语言,并且在错误报告方面也更好,即它在输入不尽快符合语法时检测语法错误.这与LL(k)(或甚至更糟的LL(*)解析器)形成对比,LL(k)可能由于回溯而将错误检测推迟到语法的不同分支,通常使错误难以在具有长公共前缀的分离上进行本地化. .

注意:这不是作业.当我发现Antlr是一个LL解析器生成器(尽管名字中有"LR")时,我感到很惊讶.

Ter*_*arr 31

如果你想要一个解析树/森林并且不介意黑盒子,那么GLR是很棒的.它允许您输入任何您想要的CFG,代价是通过详尽的测试来检查分析时的歧义,而不是静态地解决LR/LALR冲突.有人说这是一个很好的权衡.Ira Baxter的DMS工具或具有免费C++语法的Elkhound对这类问题很有用.ANTLR对于大类语言应用程序也很有用,但是使用自上而下的方法,生成称为LL(*)的递归下降解析器,允许语义谓词.我将在此处说明,谓词允许您解析超出CFG的上下文敏感语言.程序员喜欢将动作插入到语法中,例如良好的错误处理,以及单步调试.LL擅长三种.LL是我们手工操作的,因此更容易理解.不要相信维基百科关于LR更好地处理错误.也就是说,如果你使用ANTLR回溯很多,LL(*)(PEGs有这个问题)的错误确实更糟.

重新回溯.GLR也推测(即回溯),就像PEG,ANTLR和任何其他非确定性策略一样.在任何非确定性LR状态下,GLR"分叉"子解析器以尝试任何可行的路径.无论如何,LL具有良好的错误处理环境.在LR知道它与表达式匹配的情况下,LL知道它是赋值中的表达式或IF有条件的; LR知道它可能在任何一个但不确定 - 并且不确定性是它获得力量的地方.

GLR是O(n^3)最糟糕的情况.packrat/PEG是O(n)最糟糕的情况.ANTLR是O(n^2)由于循环前瞻DFA而O(n)在实践中.没关系真的.GLR足够快.

ANTLRAN其他Ť OOL为大号 ANG ř ecognition不是反LR,但我喜欢一个太;)

坦率地说,就像80年代的很多年轻编码员一样,我不理解LALR并且不喜欢黑盒子(现在我挖掘了GLR引擎的美感但仍然喜欢LL).我构建了一个基于商业LL(k)的编译器,并决定构建一个工具来生成我手工构建的内容.ANTLR并不适合所有人,而像C++这样的边缘情况可能会更好地处理GLR,但很多人发现ANTLR适合他们的舒适区.自2008年1月以来,在ANTLRWorks中已经有134,000个ANTLR二进制jar下载量和源拉链总数(根据谷歌分析).请参阅我们关于LL(*)的论文,其中包含大量经验数据.

  • 全部:我同意ANTLR和大多数解析器生成器实际上都适合构建"适度"语法的解析器.当语法变得"艰难"时,区别开始发生.如果你控制语法并且可以改变它以使强硬的案例消失,那么任何解析器生成器都会这样做.如果你不是,那么解析器生成器的强度确实很重要.在任何一种情况下,支持该工具的工程确实有帮助.尽管我对GLR有偏见(他们在实践中也是O(n)!),我将是第一个承认Terence在使ANTLR有效方面做得相当不错的工作. (3认同)
  • @Ira:我只是说GLR是一个黑盒子,因为它有效但不透明.另一个极端是递归下降解析器(由ANTLR生成),它不是黑盒子,因为它是程序员手工构建的,可以单步调试.实际上,这并非完全正确.LL(*)允许循环DFA向前扫描,我为这些决策生成状态机(黑盒子),但这只是替代生产预测而不是解析. (2认同)
  • 更新。即将发表的有关自适应LL(*),ALL(*)的OOPSLA '14论文,该论文采用任何语法,但有一个例外:没有*间接*左递归。处理`e:e'*'e | INT;`规则文件http://www.antlr.org/papers/allstar-techreport.pdf ALL(*)是我对解析的最终决定。25年后,我终于破解了。开箱即用的C11规范具有左递归功能,尽管解析缓慢的线性步伐不需调整语法。Java语法解析器在不到6秒的时间内解析了12,920个文件,360万行,Java库大小为123M。看到纸上的工具枪战。GLR工具需要对数刻度或单独的图。 (2认同)

Ira*_*ter 12

如果你必须手动编码,递归下降(LL)是你可以现实地做的事情; 人们不能手工制作L(AL)R解析器.

鉴于现代解析器生成器将为您处理所有解析器构造,并且该空间不是一个问题,我更喜欢LR解析器,因为您不必与语法争用,以使它们对您的特定解析器生成器有效(没有"删除所有左递归"的愚蠢).

事实上,我更喜欢GLR解析器,它几乎可以用无上下文语法解析任何东西.没有左递归的担忧.没有转变/减少冲突的担忧.没有前瞻性的限制.

如果你想看到一个 GLR解析引擎可以处理的语言范围(包括着名的难以解析的LL/LALR语言,C++),你可以看看这里.

  • LALR的存在是因为对于许多实用语法而言,您获得的表比LR小.你当然可以定义LALR(3)语法的概念,尽管在实践中没有人这样做.GLR的原因是你可以不再考虑K. (2认同)
  • @Adam:维基百科网站上的引用是必读的,但它们很难找到"免费"; 我有很多年前获得的硬拷贝.Adrian Johnstone似乎在高级GLR解析方面做了大量工作,例如:http://portal.acm.org/citation.cfm?id = 1149674.如果您是ACM会员,这是免费的.他的网站http://www.cs.rhul.ac.uk/research/languages/publications/aj_publications.html可能有免费的文件. (2认同)
  • 自上而下实现的解析器可以将 kleene 运算符从逻辑上正确的递归转换为循环操作。但人们仍然可以以复杂的方式编写涉及左递归的规则;我没有现成的例子,但我很高兴知道我不用担心如何编写语法规则。如果你看看人们对自顶向下解析器的抱怨,即使是那些带有小星号表示法的解析器,你几乎总是会发现他们试图找到一种方法来摆脱一些不方便的左递归。为什么要担心呢? (2认同)