Algorithm LL和LR解析之间的区别是什么?

Algorithm LL和LR解析之间的区别是什么?,algorithm,parsing,ll,lr,Algorithm,Parsing,Ll,Lr,有谁能给我举一个LL解析和LR解析的简单例子吗?在较高的层次上,LL解析和LR解析之间的区别在于,LL解析器从起始符号开始,并尝试应用结果来到达目标字符串,而LR解析器从目标字符串开始,并尝试返回起始符号 LL解析是从左到右、最左的派生。也就是说,我们考虑从左到右的输入符号,并试图构造最左边的推导。这是通过从开始符号开始并重复展开最左边的非终结符直到到达目标字符串来完成的。LR解析是从左到右、最右边的派生,这意味着我们从左到右扫描并尝试构造最右边的派生。解析器不断地拾取输入的子字符串,并尝试将其

有谁能给我举一个LL解析和LR解析的简单例子吗?

在较高的层次上,LL解析和LR解析之间的区别在于,LL解析器从起始符号开始,并尝试应用结果来到达目标字符串,而LR解析器从目标字符串开始,并尝试返回起始符号

LL解析是从左到右、最左的派生。也就是说,我们考虑从左到右的输入符号,并试图构造最左边的推导。这是通过从开始符号开始并重复展开最左边的非终结符直到到达目标字符串来完成的。LR解析是从左到右、最右边的派生,这意味着我们从左到右扫描并尝试构造最右边的派生。解析器不断地拾取输入的子字符串,并尝试将其反转回非终结符

在LL解析过程中,解析器连续在两个操作之间进行选择:

  • Predict:根据最左边的非终结符和一定数量的先行标记,选择应该应用哪个产品以更接近输入字符串
  • 匹配:将猜测的最左侧端子符号与输入的最左侧未使用符号匹配
  • 例如,根据以下语法:

    • → E
    • E→ T+E
    • E→ T
    • T→ <代码>整数
    然后给定字符串
    int+int+int
    ,LL(2)解析器(使用两个lookahead标记)将按如下方式解析该字符串:

    Production       Input              Action
    ---------------------------------------------------------
    S                int + int + int    Predict S -> E
    E                int + int + int    Predict E -> T + E
    T + E            int + int + int    Predict T -> int
    int + E          int + int + int    Match int
    + E              + int + int        Match +
    E                int + int          Predict E -> T + E
    T + E            int + int          Predict T -> int
    int + E          int + int          Match int
    + E              + int              Match +
    E                int                Predict E -> T
    T                int                Predict T -> int
    int              int                Match int
                                        Accept
    
    Workspace        Input              Action
    ---------------------------------------------------------
                     int + int + int    Shift
    int              + int + int        Reduce T -> int
    T                + int + int        Shift
    T +              int + int          Shift
    T + int          + int              Reduce T -> int
    T + T            + int              Shift
    T + T +          int                Shift
    T + T + int                         Reduce T -> int
    T + T + T                           Reduce E -> T
    T + T + E                           Reduce E -> T + E
    T + E                               Reduce E -> T + E
    E                                   Reduce S -> E
    S                                   Accept
    
    请注意,在每个步骤中,我们都会看到产品中最左边的符号。如果它是一个终端,我们匹配它,如果它是一个非终端,我们通过选择一个规则来预测它将是什么

    在LR解析器中,有两个操作:

  • Shift:将输入的下一个标记添加到缓冲区以供考虑
  • Reduce:通过反转生产,将此缓冲区中的终端和非终端集合还原为某些非终端
  • 例如,LR(1)解析器(带有一个前瞻标记)可以按如下方式解析相同的字符串:

    Production       Input              Action
    ---------------------------------------------------------
    S                int + int + int    Predict S -> E
    E                int + int + int    Predict E -> T + E
    T + E            int + int + int    Predict T -> int
    int + E          int + int + int    Match int
    + E              + int + int        Match +
    E                int + int          Predict E -> T + E
    T + E            int + int          Predict T -> int
    int + E          int + int          Match int
    + E              + int              Match +
    E                int                Predict E -> T
    T                int                Predict T -> int
    int              int                Match int
                                        Accept
    
    Workspace        Input              Action
    ---------------------------------------------------------
                     int + int + int    Shift
    int              + int + int        Reduce T -> int
    T                + int + int        Shift
    T +              int + int          Shift
    T + int          + int              Reduce T -> int
    T + T            + int              Shift
    T + T +          int                Shift
    T + T + int                         Reduce T -> int
    T + T + T                           Reduce E -> T
    T + T + E                           Reduce E -> T + E
    T + E                               Reduce E -> T + E
    E                                   Reduce S -> E
    S                                   Accept
    
    您提到的两种解析算法(LL和LR)具有不同的特性。LL解析器往往更易于手工编写,但它们的功能不如LR解析器,并且接受的语法集比LR解析器小得多。LR解析器有多种风格(LR(0)、SLR(1)、LALR(1)、LR(1)、IELR(1)、GLR(0)等),它们的功能要强大得多。它们也往往更复杂,几乎总是由
    yacc
    bison
    等工具生成。LL解析器也有多种风格(包括工具使用的LL(*),尽管在实践中LL(1)是使用最广泛的


    作为一个无耻的插件,如果你想了解更多关于LL和LR解析的知识,我刚刚教完一门编译器课程,并在课程网站上发布了。如果您认为它们中的任何一个有用的话,我很乐意详细说明。

    Josh Haberman在他的文章中声称LL解析直接对应于,而LR对应于。PN和RPN之间的差异是遍历方程二叉树的顺序:

    + 1 * 2 3  // Polish (prefix) expression; pre-order traversal.
    1 2 3 * +  // Reverse Polish (postfix) expression; post-order traversal.
    

    根据哈伯曼的说法,这说明了LL和LR解析器之间的主要区别:

    LL和LR解析器操作方式的主要区别在于,LL解析器输出解析树的前序遍历,LR解析器输出后序遍历


    要获得深入的解释、示例和结论,请查看哈伯曼的。

    LL使用自上而下的方法,而LR使用自下而上的方法。

    如果分析编程语言:

    • LL会看到一个源代码,其中包含函数,其中包含表达式
    • LR看到表达式,它属于函数,结果是完整的源代码

    与LR相比,LL解析是有缺陷的。这是一本语法书 对于LL解析器生成器来说,这是一个噩梦:

    Goal           -> (FunctionDef | FunctionDecl)* <eof>                  
    
    FunctionDef    -> TypeSpec FuncName '(' [Arg/','+] ')' '{' '}'       
    
    FunctionDecl   -> TypeSpec FuncName '(' [Arg/','+] ')' ';'            
    
    TypeSpec       -> int        
                   -> char '*' '*'                
                   -> long                 
                   -> short                   
    
    FuncName       -> IDENTIFIER                
    
    Arg            -> TypeSpec ArgName         
    
    ArgName        -> IDENTIFIER 
    
    LR解析器可以解析

    int main (int na, char** arg)
    
    在遇到一个“;”之前,不关心被认可的规则是什么或者一个“{”

    LL解析器在“int”处挂起,因为它需要知道 规则正在被识别。因此它必须提前查找“;”或 “{”

    LL解析器的另一个噩梦是语法中的左递归。左递归在语法中是正常的,对于LR来说没有问题 解析器生成器,但将无法处理它


    因此,你必须用LL以不自然的方式编写语法。

    最左边的派生示例: 上下文无关的语法G具有生成式

    z→ xXY(规则:1) X→ Ybx(规则:2) Y→ (第3条规则) Y→ c(规则:4)

    计算具有最左侧派生的字符串w='xcbxbc'

    z⇒ xXY(规则:1) ⇒ xYbxY(规则:2) ⇒ xcbxY(规则:4) ⇒ xcbxbY(规则:3) ⇒ xcbxbc(规则:4)


    最右边的派生示例: K→ aKK(规则:1) A.→ b(规则:2)

    计算具有最右边派生的字符串w='aababbb'

    K⇒ aKK(规则:1) ⇒ aKb(规则:2) ⇒ aaKKb(规则:1) ⇒ AAKKB(规则:1) ⇒ aaKaKbb(规则:2) ⇒ AAKABB(规则:2)
    ⇒ AABABB(规则:2)

    你的演讲幻灯片非常精彩,很容易成为我见过的最有趣的解释:)这是一种真正能激发兴趣的东西。我也必须对幻灯片进行评论!现在浏览所有幻灯片。非常有帮助!谢谢!非常喜欢这些幻灯片。我想你不可能发布非Windows版本的项目文件(还有scanner.l文件,用于pp2)?:)我能为Matt出色的总结答案做出贡献的一件事是,任何可以被解析的语法都是b