这里是简化yaac文件:消除移/减少由产生式规则的冲突与相同前缀
%token CONTEXT_ // the corresponding string is "context"
%token CONTEXTREF_ //"contextref"
%token IS_ //"is"
%token ID_L //"id_l"
%token ID_L1 //"id_l1"
%token LIB_
%start design_file
%%
design_file :design_unit
|design_file design_unit
;
design_unit :context_cl LIB_
|context_decl
;
context_cl : /* empty */ { }
|context_cl context_ref
;
context_decl :CONTEXT_ ID_L IS_ ';'
;
context_ref :CONTEXT_ ID_L1 '.' ID_L ';'
;
有2个移/减少冲突。
CONTEXT_ shift, and go to state 1 CONTEXT_ [reduce using rule 5 (context_cl)]
第5 context_cl : /* empty */ { }
。
一般来说,这并不重要,解析器在大多数情况下运行良好。 但在一个奇怪的情况下,对源文件进行像以下:
context id_l is ...
...
分析器不会移位,但减少,因此使用context_ref :CONTEXT_ ID_L1 '.' ID_L ';'
解析context id_l is ...
,这会导致语法错误。
所以我必须消除冲突。 我想他们是由规则context_decl
和context_ref
在开始时都有CONTEXT_
引起的。
为了验证我的猜测,我只是将context_ref :CONTEXT_ ID_L1 '.' ID_L ';'
更改为context_ref :CONTEXTREF_ ID_L1 '.' ID_L ';'
。然后,没有冲突,并且没有语法错误。
但是,我不能用这种方法代替context_ref
。这是标准。
那么,如何通过其他方式避免这两个冲突呢?或者,是否有解决这种冲突的一般方法?
而且,对于移位/减少冲突,解析器会选择减少而不是移位?因为我认为解析器总是会转移到reduce。
我无法重现你描述的问题。我精确地使用了你指定的语法,并精确地得到了你引用的两种状态下的转换/减少冲突。这样所有的检查。我猜测一个词法分析器可能看起来像什么样,并且在调试模式下使用输入'context id_l is;'来运行它;它认可输入没有错误。由于转换/减少冲突的解决,它不会解析'context_id_l1 ...'。这是你的意思吗?如果是这样,请编辑您的问题,我会尽力回答。否则,请[mcve],强调“完整”和“可验证”。 – rici
语法错误间歇发生。所以我只想消除转移/减少冲突。@ rici –