📜  SLR,CLR和LALR解析器|套装3

📅  最后修改于: 2021-06-28 07:35:37             🧑  作者: Mango

在本文中,我们将讨论自下而上解析器的组成部分SLR解析器,CLR解析器和LALR解析器。单反解析器
SLR解析器类似于LR(0)解析器,只是条目减少了。减少的产量只写在减少其产量的变量的FOLLOW中。 SLR解析表的构建–

  1. 构造C = {I 0 ,I 1 ,…。 I n },是G’的LR(0)个项目的集合。
  2. 状态i是从Ii构造的。确定状态i的解析动作如下:
    • 如果[A->?.a?在I i中,并且GOTO(I i ,a)= I j ,然后将ACTION [i,a]设置为“ shift j”。这里必须是终端。
    • 如果[A->?。]在I i中,则将ACTION [i,a]设置为“减少A->?”对于所有在FOLLOW(A)中的a;这里A可能不是S’。
    • 是[S-> S.]在I i中,然后将action [i,$]设置为“ accept”。如果上述规则产生了任何冲突的动作,我们可以说该语法不是SLR。
  3. 使用以下规则为所有非终端A构造状态i的goto转换:
    如果GOTO(I i ,A)= I j,则GOTO [i,A] = j。
  4. 所有未由规则2和3定义的条目都将出错。

例如:
如果在解析表中我们有多个条目,则称这是冲突。

Consider the grammar E -> T+E | T
                     T ->id
    Augmented grammar - E’ -> E
                E -> T+E | T
                T -> id

parser_16

注1 –对于GATE,我们不必绘制表格,只需在GOTO图中查找在一个状态下同时发生的减法和平移。如果是两次减法,则如果两个减法产量的跟随都有共同点那么它将导致表中有多个条目,因此不是SLR。在单班减一班的情况下,如果他们是从该状态开始的终端上的GOTO操作(减少产量的结果),那么它将导致多次录入,因此不是SLR。
注2 –每个SLR语法都是明确的,但是它们有许多不是SLR的明确语法。 CLR解析器

在SLR方法中,我们正在处理LR(0))项目。在CLR解析中,我们将使用LR(1)项。 LR(k)项被定义为使用长度为k的超前项的项。因此,LR(1)项由两部分组成:LR(0)项和与该项关联的前瞻。
LR(1)解析器是更强大的解析器。
对于LR(1)项目,我们修改了Closure和GOTO函数。关闭操作

Closure(I)
repeat 
    for (each item [ A -> ?.B?, a ] in I )
        for (each production B -> ? in G’)
          for (each terminal b in FIRST(?a))
            add [ B -> .? , b ] to set I;
until no more items are added to I;
return I;

让我们通过一个例子来理解它–
parser_17

转到操作

Goto(I, X)
Initialise J to be the empty set;
for ( each item A -> ?.X?, a ] in I )
    Add item A -> ?X.?, a ] to se J;   /* move the dot one step */
return Closure(J);    /* apply closure to the set */

例如-
parser_18 LR(1)件

Void items(G’)
Initialise C to { closure ({[S’ -> .S, $]})};
Repeat
    For (each set of items I in C)
        For (each grammar symbol X)
            if( GOTO(I, X) is not empty and not in C)
                Add GOTO(I, X) to C;
Until no new set of items are added to C;

GOTO图的构造

  • 状态I 0 –增强的LR(1)项的关闭。
  • 在DFA的帮助下,使用I 0查找LR(1)项集的所有集合
  • 将DFA转换为LR(1)解析表

CLR解析表的构造-
输入法-扩充语法G’

  1. 构造C = {I 0 ,I 1 ,…。 I n },表示G’的LR(0)个项目的集合。
  2. 状态i是从Ii构造的。确定状态i的解析动作如下:
    i)如果[A->?.a ?, b]在I i中,并且GOTO(I i ,a)= I j ,则将ACTION [i,a]设置为“ shift j”。这里必须是终端。
    ii)如果[A->?。 ,a]在I i中,A≠S,然后将ACTION [i,a]设置为“减少A->?”。
    iii)是[S-> S.,$]在I i中,然后将action [i,$]设置为“接受”。
    如果上述规则产生了任何冲突的动作,我们说文法是
    不是CLR。
  3. 使用以下规则为所有非终端A构造状态i的goto转换:如果GOTO(I i ,A)= I j,则GOTO [i,A] = j。
  4. 所有未由规则2和3定义的条目都将出错。

例如:

Consider the following grammar 
    S -> AaAb | BbBa
    A -> ?
    B -> ?
    Augmented grammar - S’ -> S
                  S -> AaAb | BbBa
                  A -> ?
                  B -> ?
    GOTO graph for this grammar will be - 

parser_19
–如果一个状态有两个约简并且都具有相同的前瞻性,则它将在解析表中的多个条目中发生冲突。如果一个状态有一个约简,并且它们是在该终端上从该状态开始的转移,与减少的前瞻相同,那么它将导致解析表中有多个条目,从而产生冲突。解析器
LALR解析器与CLR解析器相同,只是有所不同。在CLR解析器中,如果两个状态仅在前瞻方面有所不同,则我们将这些状态组合在LALR解析器中。最小化后,如果分析表没有冲突,则语法也是LALR。
例如:

consider the grammar S ->AA
                     A -> aA | b
    Augmented grammar - S’ -> S
                        S ->AA
                        A -> aA | b

parser_20

重要笔记
1.即使CLR解析器没有RR冲突,但LALR可能包含RR冲突。
2.如果状态数LR(0)= n1,
状态数SLR = n2,
状态数LALR = n3,
那么,状态数CLR = n4,
n1 = n2 = n3 <= n4 parser_21