它是用Lemon编译的,它是一个LALR(1)解析器生成器:
program ::= statement.
statement ::= ifstatement Newline.
statement ::= returnstatement Newline.
ifstatement ::= If Number A statement B.
ifstatement ::= If Number A statement B Newline Else A statement B.
returnstatement ::= Return Number.
错误消息是:
user@/tmp > lemon test.lm
test.lm:6: This rule can not be reduced.
1 parsing conflicts.
调试输出为:
State 0:
program ::= * statement
statement ::= * ifstatement Newline
statement ::= * returnstatement Newline
ifstatement ::= * If Number A statement B
ifstatement ::= * If Number A statement B Newline Else A statement B
returnstatement ::= * Return Number
If shift 10
Return shift 3
program accept
statement shift 13
ifstatement shift 12
returnstatement shift 11
State 1:
statement ::= * ifstatement Newline
statement ::= * returnstatement Newline
ifstatement ::= * If Number A statement B
ifstatement ::= * If Number A statement B Newline Else A statement B
ifstatement ::= If Number A statement B Newline Else A * statement B
returnstatement ::= * Return Number
If shift 10
Return shift 3
statement shift 4
ifstatement shift 12
returnstatement shift 11
State 2:
statement ::= * ifstatement Newline
statement ::= * returnstatement Newline
ifstatement ::= * If Number A statement B
ifstatement ::= If Number A * statement B
ifstatement ::= * If Number A statement B Newline Else A statement B
ifstatement ::= If Number A * statement B Newline Else A statement B
returnstatement ::= * Return Number
If shift 10
Return shift 3
statement shift 8
ifstatement shift 12
returnstatement shift 11
State 3:
returnstatement ::= Return * Number
Number shift 14
State 4:
ifstatement ::= If Number A statement B Newline Else A statement * B
B shift 15
State 5:
ifstatement ::= If Number A statement B Newline Else * A statement B
A shift 1
State 6:
ifstatement ::= If Number A statement B Newline * Else A statement B
Else shift 5
State 7:
(3) ifstatement ::= If Number A statement B *
ifstatement ::= If Number A statement B * Newline Else A statement B
Newline shift 6
Newline reduce 3 ** Parsing conflict **
State 8:
ifstatement ::= If Number A statement * B
ifstatement ::= If Number A statement * B Newline Else A statement B
B shift 7
State 9:
ifstatement ::= If Number * A statement B
ifstatement ::= If Number * A statement B Newline Else A statement B
A shift 2
State 10:
ifstatement ::= If * Number A statement B
ifstatement ::= If * Number A statement B Newline Else A statement B
Number shift 9
State 11:
statement ::= returnstatement * Newline
Newline shift 16
State 12:
statement ::= ifstatement * Newline
Newline shift 17
State 13:
(0) program ::= statement *
$ reduce 0
State 14:
(5) returnstatement ::= Return Number *
{default} reduce 5
State 15:
(4) ifstatement ::= If Number A statement B Newline Else A statement B *
{default} reduce 4
State 16:
(2) statement ::= returnstatement Newline *
{default} reduce 2
State 17:
(1) statement ::= ifstatement Newline *
{default} reduce 1
----------------------------------------------------
Symbols:
0: $:
1: Newline
2: If
3: Number
4: A
5: B
6: Else
7: Return
8: error:
9: program: If Return
10: statement: If Return
11: ifstatement: If
12: returnstatement: Return
答案 0 :(得分:1)
从调试输出看一下状态7。它描述了解析器已经接受下一组令牌的情况:
ifstatement ::= If Number A statement B *
在这种情况下,当Newline令牌出现时,解析器可以选择以下两个选项:
记住它并切换到State 6.这个转变是由你的语法中的下一个规则规定的:
ifstatement ::= If Number A statement B Newline Else A statement B.
将当前规则视为已完成并返回上级规则。这种减少是由你的语法规则规定的:
ifstatement ::= If Number A statement B.
LALR(1)解析器在这种情况下没有其他选项可以失败,因为它无法预测流中的下一个令牌。它无法预测在Newline之后的Else。
修改语法以避免这种冲突的情况。我只能添加新的行字符通常不包括在语言语法中。 Tokenizer通常将它们视为与其他空白字符类似的标记边界。