test.y
%%
TOP :
OPTIONS
;
OPTIONS :
OPTION
| OPTIONS OPTION
;
OPTION :
/*no option is possible*/
| 'C'
;
%%
yacc -v test.y
y.output包含以下内容
0 $accept : TOP $end
1 TOP : OPTIONS
2 OPTIONS : OPTION
3 | OPTIONS OPTION
4 OPTION :
5 | 'C'
0: shift/reduce conflict (shift 1, reduce 4) on 'C'
state 0
$accept : . TOP $end (0)
OPTION : . (4)
'C' shift 1
$end reduce 4
TOP goto 2
OPTIONS goto 3
OPTION goto 4
state 1
OPTION : 'C' . (5)
. reduce 5
state 2
$accept : TOP . $end (0)
$end accept
3: reduce/reduce conflict (reduce 1, reduce 4) on $end
3: shift/reduce conflict (shift 1, reduce 4) on 'C'
state 3
TOP : OPTIONS . (1)
OPTIONS : OPTIONS . OPTION (3)
OPTION : . (4)
'C' shift 1
$end reduce 1
OPTION goto 5
state 4
OPTIONS : OPTION . (2)
. reduce 2
state 5
OPTIONS : OPTIONS OPTION . (3)
. reduce 3
State 0 contains 1 shift/reduce conflict.
State 3 contains 1 shift/reduce conflict, 1 reduce/reduce conflict.
3 terminals, 4 nonterminals
6 grammar rules, 6 states
为什么会改变/减少和减少/减少冲突。
我已经阅读了yacc解析器如何在http://dinosaur.compilertools.net/yacc/的“Parser如何工作”部分中工作,但我不明白yacc如何处理空规则。似乎它试图在任何地方使用空规则。
问题1. yacc如何处理状态机的空规则interms和上面链接中描述的“look ahead token”。
问题2.我如何摆脱冲突并仍然保持语法的“逻辑”?
事先感谢您的帮助。
答案 0 :(得分:1)
当然,它试图使用“无处不在”的空规则。它正在做你告诉它做的事。
您所说的是非终端OPTIONS
代表OPTION
个非终端的任意正数,OPTION
非终端可以是C
或空的。
由于OPTION
可以为空,因此空输入中可以有任意数量的OPTION
。两个空OPTION
看起来与153空OPTION
完全相同。更重要的是,两个C
令牌之间可以有任意数量的空OPTIONS
。
所以你的语法含糊不清,野牛报告解析冲突。
如果您想将OPTION
定义为任意数量的OPTION
s,包括零options: %empty
| options option
option : 'C'
s,那么只需说明:
-DEIGEN_HAS_RVALUE_REFERENCES=0