LR(1)解析器中的左递归

时间:2014-01-30 16:25:51

标签: parsing context-free-grammar lr

LR(1)解析器可以解析这种类型的语法吗?

S -> SA  | A
A -> aSb | ab

我正在尝试编写一个实现这种类型解析器的Java程序,但是我只能在没有左递归的语法上得到正确的结果。

2 个答案:

答案 0 :(得分:9)

LR(1)解析器可以处理某些类型的左递归,但并非所有左递归语法都是LR(1)。

让我们看看你的特定语法是否为LR(1)。增加语法给出了

  

S'→S

     

S→SA |甲

     

A→aSb | AB

因此我们的配置集

 (1)
 S' -> .S    [$]     (Go to 2)
 S  -> .SA   [$a]    (Go to 2)
 S  -> .A    [$a]    (Go to 3)
 A  -> .aSb  [$a]    (Shift on a and go to 4)
 A  -> .ab   [$a]    (Shift on a and go to 4)

 (2)
 S' -> S.    [$]     (Accept on $)
 S  -> S.A   [$a]    (Go to 3)
 A  -> .aSb  [$a]    (Shift on a and go to 4)
 A  -> .ab   [$a]    (Shift on a and go to 4)

 (3)
 S  -> A.    [$a]    (reduce on $ or a)

 (4)
 A  -> a.Sb  [$a]    (Go to 6)
 A  -> a.b   [$a]    (Shift on b and go to 10)
 S  -> .SA   [ab]    (Go to 11)
 S  -> .A    [ab]    (Go to 12)
 A  -> .aSb  [ab]    (Shift on a and go to 8)
 A  -> .ab   [ab]    (Shift on a and go to 8)

 (5)
 A  -> ab.   [$a]    (Reduce on a or $)

 (6)
 A  -> aS.b  [$a]    (Shift on b and go to 7)
 S  -> S.A   [ab]    (Go to 13)
 A  -> .aSb  [ab]    (Shift on a and go to 8)
 A  -> .ab   [ab]    (Shift on a and go to 8)

 (7)
 A  -> aSb.  [$a]    (Reduce on a or $)

 (8)
 A  -> a.Sb  [ab]    (Go to 14)
 A  -> a.b   [ab]    (Shift on b and go to 16)
 S  -> .SA   [ab]    (Go to 11)
 S  -> .A    [ab]    (Go to 12)
 A  -> .aSb  [ab]    (Shift on a and go to 8)
 A  -> .ab   [ab]    (Shift on a and go to 8)

 (9)
 S  -> SA.   [$a]    (Reduce on a or $)

 (10)
 A  -> ab.   [$a]    (Reduce on a or b)

 (11)
 S  -> S.A   [ab]    (Go to 13)
 A  -> .aSb  [ab]    (Shift on a and go to 8)
 A  -> .ab   [ab]    (Shift on a and go to 8)

 (12)
 S  -> A.    [ab]    (Reduce on a or b)

 (13)
 S  -> SA.   [ab]    (Reduce on a or b)

 (14)
 A  -> aS.b  [ab]    (Shift on b and go to 15)
 S  -> S.A   [ab]    (Go to 13)
 A  -> .aSb  [ab]    (Shift on a and go to 8)
 A  -> .ab   [ab]    (Shift on a and go to 8)   

 (15)
 A  -> aSb.  [ab]    (Reduce on a or b)

 (16)
 A  -> ab.   [ab]    (Reduce on a or b)

这个语法中没有转移/减少或减少/减少冲突,所以它应该是LR(1)(除非我在某个地方犯了错误!)

希望这有帮助!

答案 1 :(得分:2)

原来它也是一个SLR语法,所以LR太过分了。不需要16个LR状态,SLR只需要10个状态。

(1)
 S' -> .S    S => (Go to 2)
 S  -> .SA   A => (Go to 3)
 S  -> .A    a => (Shift and go to 4)
 A  -> .aSb     
 A  -> .ab   

 (2)
 S' -> S.    $ => (Accept on $)
 S  -> S.A   A => (Go to 5)
 A  -> .aSb  a => (Shift and go to 6)
 A  -> .ab   

 (3)
 S  -> A.    [$b] => (reduce on $ or b)

 (4)
 A  -> a.Sb  S => (Go to 7)
 A  -> a.b   A => (Go to 9)
 S  -> .SA   a => (Shift and go to 6)
 S  -> .A    b => (Shift and go to 8)
 A  -> .aSb  
 A  -> .ab   

 (5)
 S  -> SA.   [$b] => (reduce on $ or b)

 (6)
 A  -> a.Sb  S => (Go to 7)
 A  -> a.b   A => (Go to 3)
 S  -> .SA   a => (Shift and go to 4)
 S  -> .A    b => (Shift and go to 8)
 A  -> .aSb  
 A  -> .ab   

 (7)
 A  -> aS.b  A => (Go to 5)
 S  -> S.A   a => (Shift and go to 6)
 A  -> .aSb  b => (Shift and go to 10)
 A  -> .ab   

 (8)
 A  -> ab.   [$b] => (reduce on $ or b)

 (9)
 S  -> A.    [$b] => (reduce on $ or b)

 (10)
 A  -> aSb.  [$b] => (reduce on $ or b)