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(k)语法,我希望最小化k。

我认为您的
LR(0)
解析器不是标准解析器:

LR(0)解析器是一种移位/归约解析器,它使用零前瞻标记来确定要采取的操作(因此是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