为什么 YACC 不产生 shift-reduce 冲突?
Why doesn't YACC generate shift-reduce conflict?
试图理解 shift-reduce 冲突并解决它们。
我有以下 YACC 代码,我期待它发生 shift-reduce 冲突,但 Bison 没有生成任何此类警告
%%
lang_cons: /* empty */
| declaraion // SEMI_COLON
| func
;
declaraion : keyword ID
;
func : keyword ID SEMI_COLON
;
keyword : INT
| FLOAT
;
%%
但是如果我在第二条规则(即 | declaraion SEMI_COLON
)中取消注释 SEMI_COLON ,我会遇到 shift-reduce 冲突。在这种情况下,我期待减少减少冲突。请帮助我理解这个烂摊子!
PS:考虑输入,
1) int varName
2) int func;
如果您给 bison -v
命令行标志,它将生成一个 .output
文件,其中包含生成的状态机,这可能会帮助您了解发生了什么。
请注意,bison 实际上解析了增强语法,它由带有附加规则的语法组成
start': start END
其中 END
是一个特殊标记,其代码为 0,表示输入结束,而 start
是您的语法用作开始符号的任何内容。 (这确保了 bison 解析器不会静默地忽略有效输入末尾的垃圾。)
这使您的原始语法明确无误;在看到 varName
之后,前瞻将是 END
,在这种情况下 declaration
减少,或者 ';'
,这将被移动(随后减少 func
当看到下面的END
时)。
在您的第二个语法中,冲突涉及减少 declaration
或移动分号之间的选择。如果分号是 declaration
的一部分,那么您会看到 reduce/reduce 冲突。
试图理解 shift-reduce 冲突并解决它们。
我有以下 YACC 代码,我期待它发生 shift-reduce 冲突,但 Bison 没有生成任何此类警告
%%
lang_cons: /* empty */
| declaraion // SEMI_COLON
| func
;
declaraion : keyword ID
;
func : keyword ID SEMI_COLON
;
keyword : INT
| FLOAT
;
%%
但是如果我在第二条规则(即 | declaraion SEMI_COLON
)中取消注释 SEMI_COLON ,我会遇到 shift-reduce 冲突。在这种情况下,我期待减少减少冲突。请帮助我理解这个烂摊子!
PS:考虑输入,
1) int varName
2) int func;
如果您给 bison -v
命令行标志,它将生成一个 .output
文件,其中包含生成的状态机,这可能会帮助您了解发生了什么。
请注意,bison 实际上解析了增强语法,它由带有附加规则的语法组成
start': start END
其中 END
是一个特殊标记,其代码为 0,表示输入结束,而 start
是您的语法用作开始符号的任何内容。 (这确保了 bison 解析器不会静默地忽略有效输入末尾的垃圾。)
这使您的原始语法明确无误;在看到 varName
之后,前瞻将是 END
,在这种情况下 declaration
减少,或者 ';'
,这将被移动(随后减少 func
当看到下面的END
时)。
在您的第二个语法中,冲突涉及减少 declaration
或移动分号之间的选择。如果分号是 declaration
的一部分,那么您会看到 reduce/reduce 冲突。