不能找到缩小/在语法减少冲突(Cant find Reduce/Reduce conflict in

2019-09-26 14:01发布

我写了下面的语法和野牛警告我一个减少/减少冲突。

parser.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]

我如何检测其语法的一部分是产生冲突? 有野牛产生在那里我可以看到冲突日志? 而且,我该如何解决这个问题?

语法:

%left TK_OC_OR TK_OC_AND
%left '<' '>' TK_OC_LE TK_OC_GE TK_OC_EQ TK_OC_NE
%left '+' '-'
%left '*' '/'

%nonassoc LOWER_THAN_ELSE
%nonassoc TK_PR_ELSE

%start s

%type<symbol> decl_var
%type<symbol> cabecalho

%%

s: decl_global s
  | def_funcao s
  |
  ;

decl_global: decl_var ';'
  | decl_vetor ';'
  | decl_var {error("Faltando o ';' no final do comando.", $1->line); return IKS_SYNTAX_ERRO;}
  ;

decl_local: decl_var ';' decl_local
   |
   ;

decl_var
  : tipo_var TK_IDENTIFICADOR {$$ = $2;}
  ;

decl_vetor
   : tipo_var TK_IDENTIFICADOR '[' TK_LIT_INT ']'
   ;


tipo_var: TK_PR_INT
        | TK_PR_FLOAT
        | TK_PR_BOOL
        | TK_PR_CHAR
        | TK_PR_STRING
        ;

def_funcao: cabecalho decl_local bloco_comando
  | cabecalho decl_local bloco_comando ';' {error("Declaração de função com ';' no final do comando.\n",$1->line); return IKS_SYNTAX_ERRO;} 
  ;

chamada_funcao
  : TK_IDENTIFICADOR '(' lista_expressoes ')'
  ;

cabecalho: decl_var '(' lista_parametros ')' {$$ = $1;}
  ;

lista_parametros: lista_parametros_nao_vazia
  |
  ;

lista_parametros_nao_vazia: parametro ',' lista_parametros_nao_vazia
  | parametro
  ;

parametro: decl_var
  ;

comando: bloco_comando
  | controle_fluxo
  | atribuicao
  | entrada
  | saida
  | retorna
  | decl_var ';'
  | chamada_funcao
  | ';'
  ;

bloco_comando: '{' seq_comando '}'
  ;

seq_comando: comando seq_comando
  | comando
  |
  ;

atribuicao: TK_IDENTIFICADOR '=' expressao
  | TK_IDENTIFICADOR '[' expressao ']' '=' expressao
  ;

entrada
  : TK_PR_INPUT TK_IDENTIFICADOR
  ;

saida
  : TK_PR_OUTPUT lista_expressoes_nao_vazia
  ;

lista_expressoes_nao_vazia: expressao ',' lista_expressoes_nao_vazia
  | expressao
  ;

retorna: TK_PR_RETURN expressao ';'
  ;

controle_fluxo
  : TK_PR_IF '(' expressao ')' TK_PR_THEN comando %prec LOWER_THAN_ELSE
  | TK_PR_IF '(' error ')' TK_PR_THEN comando 
  | TK_PR_IF '(' expressao ')' TK_PR_THEN comando TK_PR_ELSE comando
  | TK_PR_WHILE '(' expressao ')' TK_PR_DO comando
  | TK_PR_DO comando TK_PR_WHILE '(' expressao ')'
  | TK_PR_DO comando TK_PR_WHILE '(' error ')'
  ;

expressao: TK_IDENTIFICADOR
  | TK_IDENTIFICADOR '[' expressao ']'
  | TK_LIT_INT
  | TK_LIT_FLOAT
  | TK_LIT_FALSE
  | TK_LIT_TRUE
  | TK_LIT_CHAR
  | TK_LIT_STRING
  | expressao '+' expressao 
  | expressao '-' expressao 
  | expressao '*' expressao 
  | expressao '/' expressao 
  | expressao '<' expressao 
  | expressao '>' expressao 
  | '+' expressao
  | '-' expressao
  | '(' expressao ')'
  | expressao TK_OC_LE expressao
  | expressao TK_OC_GE expressao
  | expressao TK_OC_EQ expressao
  | expressao TK_OC_NE expressao
  | expressao TK_OC_AND expressao
  | expressao TK_OC_OR expressao
  | chamada_funcao
  ;

lista_expressoes: lista_expressoes_nao_vazia
  |
  ;

Answer 1:

我如何检测其语法的一部分是产生冲突? 有野牛产生在那里我可以看到冲突日志? 而且,我该如何解决这个问题?

是。 如果使用-v野牛命令行上,它会在一个名为生产的所有状态的报告<filename>.output 。 该报告将包括各种冲突,您可以从指定的状态有什么冲突的模式是看到的。 你应该尝试阅读这个答案的其余部分之前。

如果你这样做,你会看到这个问题:

seq_comando: comando seq_comando
  | comando
  |
  ;

由于seq_comando可以为空,单个comando可以匹配:

seq_comando: comando seq_comando

要么

seq_comando: comando

最简单的办法是摆脱的seq_comando: comando规则。 您可能还需要考虑改变右递归左递归( seq_comando: seq_comando comando | /* empty */;因为这将需要更少的解析器堆栈。



文章来源: Cant find Reduce/Reduce conflict in Grammar