首页 > 解决方案 > Yacc 冲突我无法解决

问题描述

我一直在尝试修复我的 yacc 规范中的 shift/reduce 冲突,但我似乎找不到它在哪里。

%union{
   char* valueBase;
   char* correspondencia;
}
%token pal palT palC
%type <valueBase> pal  
%type <correspondencia> palT palC Smth

%%

Dicionario  : Traducao
            | Dicionario Traducao
            ;

Traducao    : Palavra Correspondencia
            ;
Palavra : Base Delim
        | Exp
        ;

Delim : 
      | ':'
      ;

Correspondencia :
                | palC                  {printf("PT Tradução: %s\n",$1);}
                ;

Exp : Smth '-' Smth                  {aux = yylval.valueBase; printf("PT Tradução: %s %s %s\n", $1, aux, $3);}
    ;

Smth : palT                         {$$ = strdup($1);}
     |                              {$$ = "";}
     ;

Base    : pal                   {printf("EN Palavra base: %s\n",$1);}
        ;

任何帮助查找和解决此冲突将不胜感激。

标签: yacc

解决方案


因此,查看语法中的 y.output 文件,您在状态 13 中存在移位/减少冲突:

State 13

   10 Exp: Smth '-' . Smth

    palT  shift, and go to state 2

    palT      [reduce using rule 12 (Smth)]
    $default  reduce using rule 12 (Smth)

    Smth  go to state 16

基本上,这就是说,当Exp在看到 aSmth '-'并查看前瞻之后解析 a 时palT,它不知道是否应该减少一个空Smth来完成Exp(留下palT作为稍后构造的一部分)或转移palTso然后可以将其减少(识别)为Smth完成 this的 a Exp

您正在识别的语言是一个或多个 的序列Traducao,每个由 aPalavra和一个可选的palCCorrespondencia可能是 apalC或空)组成。这意味着您可能有一个Palavra直接跟随另一个PalavraCorrespondencia第一个是空的)。Palavra所以解析器需要通过查看它的当前状态和一个前瞻标记来找到一个和下一个之间的边界,这是一个问题。

特别是当你有一个像 一样的输入时PalT '-' PalT '-' PalT,就是两个连续的,但是中间是属于第一个还是第二个Palavra就不清楚了。PalT它是模棱两可的,因为无论哪种方式都可以成功解析。

如果您希望解析器尽可能多地接受 first Palavra,那么您可以接受默认分辨率(移位)。如果这是错误的并且您需要其他解释,那么您将需要更多的前瞻性来识别这种情况,因为这取决于第二秒'-'之后是否有第二秒palT或其他什么。


推荐阅读