我正在研究Context Free Grammars,我坚持第一步:了解自上而下的解析算法的结构。
我的问题围绕着自上而下的解析器。我有三种算法介绍给我:
但不明白如何联系它们。所以请回答以下问题:
也请回答这个问题:
谢谢
答案 0 :(得分:4)
递归下降允许您实现一定范围的正式解析器。例如,它允许开发LL(k)解析器。在LL情况下,递归下降不需要回溯,也就是说,鉴于LL的性质,解析器将不会意识到它错过了一些解析规则。另一方面,递归下降还允许您实现使用回溯的解析器。所以你可以使用或不使用回溯,你可以使用递归下降来修改一系列解析器系列。
递归下降没有内置的效率保证。这取决于您编码的内容以及您正在解决的问题。 C语言系列的clang解析器是递归的,回溯并被作者认为是解析C语言的正确方法。
我不确定有关预测解析的术语,维基百科建议它是一个递归下降解析器,不会像上面的例子那样进行回溯,但是这种情况更有意义,被称为预测递归下降解析器。有一些讲义指出,预测解析器是一个不隐式使用堆栈来保存解析器状态的解析器。在这种情况下,预测解析器使用显式托管的堆栈,可能由具有解析规则的表驱动。
鉴于递归下降和预测解析之间的对比作为解析的两种实现技术,我会说递归解析器是一种使用递归函数实现解析器(并隐式使用堆栈)的方法,同时以某种方式进行预测解析使用表和显式堆栈实现解析器(但没有递归函数)。预测性递归下降表明有一个使用表和递归函数的解析器,这对我来说很奇怪。最糟糕的情况是,预测递归下降解析器是一个递归下降解析器(而不是预测解析器),它没有回溯,具有丑陋的名称。
概念LL解析器既可以转换为递归下降解析器(即一组递归函数),也不会进行任何回溯,因为LL不需要它,或者是预测解析器(是,while循环+堆栈+表。)
了解递归下降解析器的最佳方法是进行万花筒语言教程: http://llvm.org/docs/tutorial/LangImpl2.html
http://en.wikipedia.org/wiki/LL_parser
http://en.wikipedia.org/wiki/Recursive_descent_parser
Are GCC and Clang parsers really handwritten?
http://www.cs.purdue.edu/homes/xyzhang/spring09/notes/ll.pdf
答案 1 :(得分:3)
预测解析器是一种通用的解析器系列,有多种形式(LL和LR解析器是更突出的例子)。预测解析器通常通过使用对解析的当前状态的一些了解来“预测”要使用哪些产品(或应用哪些减少)来工作。例如,在LL解析中,解析器尝试根据当前的非终结符和输入的下几个字符来预测要应用的生成。在LR解析中,预测是根据输入的下一个终端和解析器的当前配置在特定时间点执行的减少(如果有的话)。
许多(但不是全部)预测解析器都是由表驱动的。 LR解析器通常使用表来实现,一些LL解析器也是如此,但情况并非总是如此。许多LL解析器使用递归下降实现,许多LR解析器使用递归上升实现。
递归下降解析通常是指自上而下的解析算法,它通过为每个终端和非终端设置不同的递归函数来猜测要使用哪些产品。它们通常基于语法使用一定量的回溯,并且通常在左递归语法上失败。通常,手写的LL解析器是使用递归下降而没有回溯来编写的,这是可能的,因为语法是专门构造的,不需要任何回溯。这是预测性的递归下降。
通过回溯,递归下降可能非常低效。通常,您不会在需要回溯的语法上使用递归下降。
希望这有帮助!