我的gramamar的一段代码让我疯狂。
我必须编写一个允许具有多个输入的写函数的语法
e.g。
function
begin
a:
<statments>
b:
<statements>
end
它的问题就是这样的赋值语句
ID = Expresion。
在以下引文中,您可以看到yacc生成的输出。
0 $accept : InstanciasFuncion $end
1 InstanciasFuncion : InstanciasFuncion InstanciaFuncion
2 | InstanciaFuncion
3 InstanciaFuncion : PuntoEntrada Sentencias
4 PuntoEntrada : ID ':'
5 Sentencias : Sentencias Sentencia
6 | Sentencia
7 Sentencia : ID '=' ID
State 0
0 $accept: . InstanciasFuncion $end
ID shift, and go to state 1
InstanciasFuncion go to state 2
InstanciaFuncion go to state 3
PuntoEntrada go to state 4
State 1
4 PuntoEntrada: ID . ':'
':' shift, and go to state 5
State 2
0 $accept: InstanciasFuncion . $end
1 InstanciasFuncion: InstanciasFuncion . InstanciaFuncion
$end shift, and go to state 6
ID shift, and go to state 1
InstanciaFuncion go to state 7
PuntoEntrada go to state 4
State 3
2 InstanciasFuncion: InstanciaFuncion .
$default reduce using rule 2 (InstanciasFuncion)
State 4
3 InstanciaFuncion: PuntoEntrada . Sentencias
ID shift, and go to state 8
Sentencias go to state 9
Sentencia go to state 10
State 5
4 PuntoEntrada: ID ':' .
$default reduce using rule 4 (PuntoEntrada)
State 6
0 $accept: InstanciasFuncion $end .
$default accept
State 7
1 InstanciasFuncion: InstanciasFuncion InstanciaFuncion .
$default reduce using rule 1 (InstanciasFuncion)
State 8
7 Sentencia: ID . '=' ID
'=' shift, and go to state 11
State 9
3 InstanciaFuncion: PuntoEntrada Sentencias .
5 Sentencias: Sentencias . Sentencia
ID shift, and go to state 8
ID [reduce using rule 3 (InstanciaFuncion)]
$default reduce using rule 3 (InstanciaFuncion)
Sentencia go to state 12
State 10
6 Sentencias: Sentencia .
$default reduce using rule 6 (Sentencias)
State 11
7 Sentencia: ID '=' . ID
ID shift, and go to state 13
State 12
5 Sentencias: Sentencias Sentencia .
$default reduce using rule 5 (Sentencias)
State 13
7 Sentencia: ID '=' ID .
$default reduce using rule 7 (Sentencia)
也许有人可以帮我消除歧义这个语法
答案 0 :(得分:3)
Bison为您提供至少一个提示。在State 9中,除了语法本身之外,它实际上是输出的唯一相关部分,我们看到:
State 9
3 InstanciaFuncion: PuntoEntrada Sentencias .
5 Sentencias: Sentencias . Sentencia
ID shift, and go to state 8
ID [reduce using rule 3 (InstanciaFuncion)]
$default reduce using rule 3 (InstanciaFuncion)
Sentencia go to state 12
与ID
的转变/减少冲突,在可能性的背景下:
完成InstanciaFuncion
(缩小)
继续解析Sentencias
(轮班)
在这两种情况下,ID
都是可能的。构建一个例子很容易。考虑这两个实例:
f : a = b c = d ...
f : a = b c : d = ...
我们已经完成b
而c
是前瞻,所以我们看不到c后面的符号。现在,我们完成了解析函数f
吗?或者我们应该尝试一个更长的sentencias列表?没有sabe。 (没人知道。)
是的,你的语法是明确的,所以不需要消除歧义。但它不是LR(1):你只能通过查看下一个一个符号来告诉你该怎么做。但是,它是LR(2),并且有一个证据比任何LR(2)语法都有相应的LR(1)语法。 (对于任何值2 :))。但是,不幸的是,实际上进行转型并不总是非常漂亮。它可以机械地完成,但结果语法很难阅读。 (参见下面的注释以供参考。)
在您的情况下,很容易找到等效的语法,但需要调整解析树。这是一个例子:
InstanciasFuncion : PuntoEntrada
| InstanciasFuncion PuntoEntrada
| InstanciasFuncion Sentencia
PuntoEntrada: ID ':' Sentencia
Sentencia : ID '=' ID
这是一个奇怪的事实,这种精确的转移/减少冲突是野牛本身语法的一个特征,因为野牛接受如上所述的语法(即没有分号)。 Posix坚持yacc
这样做,而野牛试图模仿yacc
。 Bison本身在扫描程序中解决了这个问题,而不是语法:它的扫描程序将“ID:”识别为单个标记(即使用任意空格分隔)。这也许是你最好的选择。
对于证据的优秀描述,LR(1)语法可以涵盖任何LR(k)语法,包括构造技术和如何恢复原始解析树的简要描述,在Sippu&amp; Sons,Inc。 Soisalon-Soininen,Parsing Theory,Vol。 II(Springer Verlag,1990)(Amazon)。这套两卷本书对于理论家来说是一个很好的参考,并且有很多有价值的实用信息,但是它的阅读量很大,也是一项严肃的投资。如果你有一个方便的大学图书馆,应该有一个可用的副本。所提出的算法归功于MD Mickunas,并于1976年在JACM 23:17-30(paywalled)出版,您也应该能够在一个好的大学图书馆中找到它。如果做不到这一点,我在Richard Marion Schell's thesis中找到了一个非常简短的描述。
就个人而言,我不会为此烦恼。要么使用GLR解析器,要么使用相同的技巧bison用于相同的目的。或者在上面的答案中使用简单的语法,然后在AST中使用AST;这不是很难。