Parsing 规范语法中的结构差异
考虑以下语法:Parsing 规范语法中的结构差异,parsing,computer-science,grammar,ambiguity,Parsing,Computer Science,Grammar,Ambiguity,考虑以下语法: S → A | B A → xy B → xyz 这就是我认为LR(0)解析器在给定输入的情况下应该做的: | xyz → shift x | yz → shift xy | z → reduce A | z → shift Az | → fail 如果我的假设是正确的,我们将规则B改为: B → Az 现在,LR(0)解析器突然接受了语法。我假设这个新语法描述的字符串集与这个问题中的第一个语法完全相同 第一个和第
S → A | B
A → xy
B → xyz
这就是我认为LR(0)解析器在给定输入的情况下应该做的:
| xyz → shift
x | yz → shift
xy | z → reduce
A | z → shift
Az | → fail
如果我的假设是正确的,我们将规则B
改为:
B → Az
现在,LR(0)解析器突然接受了语法。我假设这个新语法描述的字符串集与这个问题中的第一个语法完全相同
- 第一个和第二个语法之间有什么区别
- 我们如何将语法中的结构差异与它们所描述的语言分离?
- 通过正常化
- 什么样的正常化
LR(0)
解析器不是标准解析器:
S->A|B
A->xy
B->Az
或
LR(0)
永远不会检查B
规则,对于这两个规则,它都将失败
State0 - Clousure(S->°A):
S->°A
A->°xy
Arcs:
0 --> x --> 2
0 --> A --> 1
-------------------------
State1 - Goto(State0,A):
S->A°
Arcs:
1 --> $ --> Accept
-------------------------
State2 - Goto(State0,x):
A->x°y
Arcs:
2 --> y --> 3
-------------------------
State3 - Goto(State2,y):
A->xy°
Arcs:
-------------------------
但是如果你有
I->S
S->A|B
A->xy
B->xyz or B->Az
它们都将接受xyz
,但状态不同:
State0 - Clousure(I->°S):
I->°S
S->°A
S->°B
A->°xy A->°xy, $z
B->°xyz B->°Az, $
Arcs:
0 --> x --> 4
0 --> S --> 1
0 --> A --> 2
0 --> B --> 3
-------------------------
State1 - Goto(State0,S):
I->S°
Arcs:
1 --> $ --> Accept
-------------------------
State2 - Goto(State0,A):
S->A° S->A°, $
B->A°z, $
Arcs: 2 --> z --> 5
-------------------------
State3 - Goto(State0,B):
S->B°
Arcs:
-------------------------
State4 - Goto(State0,x):
A->x°y A->x°y, $z
B->x°yz
Arcs:
4 --> y --> 5 4 --> y --> 6
-------------------------
State5 - Goto(State4,y): - Goto(State2,z):
A->xy° B->Az°, $
Arcs:
5 --> z --> 6 -<None>-
-------------------------
State6 - Goto(State5,z): - Goto(State4,y)
B->xyz° A->xy°, $z
Arcs:
-------------------------
当您将B->xyz
更改为B->Az
时,只需将操作添加到LR表
,即可找到差异,您可以查看操作表
和转到表
()
- 当您有
A->xy
和B->xyz
时,您有两个底部句柄[xy
或xyz
],但当您有B->Az
时,您只有一个底部句柄[xy
],可以接受额外的z
- 我认为与局部优化有关-c=a+b;d=a+b->c=a+b;d=c-当您使用
B->Az
时,会使B->xyz
优化
我认为LR(0)
使用B->Az
的解析器对于xyz
;)也会失败。关于这个langauge是否为LR(0),您可能是对的。我想你没有抓住他的问题的重点。@shA.t谢谢你花时间回答。你提供了两个语法。问题是为什么一个语法可以被LR(0)解析,而另一个则不能,即使两个语法描述的是同一种语言。@thwd:这真的是你问题的重点吗?简单的回答是,“因为一个语法是LR(0)[字面上的意思是LR(0)引擎可以用它进行解析],而另一个不是”,但我看不出这如何为您提供任何有用的信息。我以为你问的是一个更复杂的问题,“我如何判断两个语法(不管处理它们需要什么样的解析引擎)代表同一种语言”(我不认为你一般可以,也许有特定的情况)以及如何规范语法以最大限度地提高看到相似性或同一性的几率。@irabakster也许我过于简单化了。更深层次的问题是:如果我可以为同一种语言编写两个语法,其中一个可以在LR(0)中解析,而另一个是LR(1),那么该语言的后一个语法结构是“不必要的复杂”。如何在语法结构没有任何影响的情况下向解析器描述语言?换言之,我如何得出语言作为语法的最基本定义?@thwd:嗯,我真的很喜欢问题的方向,语法复杂性的概念或某种“最小语法”。我不知道答案,我来这里是因为我喜欢这些问题。关于“解析器不受语法影响”的问题:您将常规语法交给能够进行上下文无关解析的解析器,然后它就可以进行解析。Earley和GLR解析器都有这种能力(我在这方面有很多GLR解析器的经验,请参阅我的简历)。但我认为这并不是你问题的核心。
State0 - Clousure(I->°S):
I->°S
S->°A
S->°B
A->°xy A->°xy, $z
B->°xyz B->°Az, $
Arcs:
0 --> x --> 4
0 --> S --> 1
0 --> A --> 2
0 --> B --> 3
-------------------------
State1 - Goto(State0,S):
I->S°
Arcs:
1 --> $ --> Accept
-------------------------
State2 - Goto(State0,A):
S->A° S->A°, $
B->A°z, $
Arcs: 2 --> z --> 5
-------------------------
State3 - Goto(State0,B):
S->B°
Arcs:
-------------------------
State4 - Goto(State0,x):
A->x°y A->x°y, $z
B->x°yz
Arcs:
4 --> y --> 5 4 --> y --> 6
-------------------------
State5 - Goto(State4,y): - Goto(State2,z):
A->xy° B->Az°, $
Arcs:
5 --> z --> 6 -<None>-
-------------------------
State6 - Goto(State5,z): - Goto(State4,y)
B->xyz° A->xy°, $z
Arcs:
-------------------------
[B->xyz] [B->Az]
| Stack | Input | Action | Stack | Input | Action
--+---------+--------+---------- --+---------+--------+----------
1 | 0 | xyz$ | Shift 1 | 0 | xyz$ | Shift
2 | 0 4 | yz$ | Shift 2 | 0 4 | xy$ | Shift
3 | 0 4 5 | z$ | Shift 3 | 0 4 6 | z$ | Reduce A->xy
4 | 0 4 5 6 | $ | Reduce B->xyz 4 | 0 2 | z$ | Shift
5 | 0 3 | $ | Reduce S->B 5 | 0 2 5 | $ | Reduce B->Az
6 | 0 1 | $ | Accept 6 | 0 3 | $ | Reduce S->B
7 | 0 1 | $ | Accept