Parsing 在语法中找不到Reduce/Reduce冲突

Parsing 在语法中找不到Reduce/Reduce冲突,parsing,bison,yacc,Parsing,Bison,Yacc,我写了下面的语法,Bison警告我reduce/reduce冲突 parser.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr] 如何检测语法的哪一部分产生冲突?是否有Bison生成的日志,我可以在其中查看冲突?还有,我怎样才能解决这个问题 语法: %left TK_OC_OR TK_OC_AND %left '<' '>' TK_OC_LE TK_OC_GE TK_OC_EQ TK_OC_NE %left '+' '-'

我写了下面的语法,Bison警告我reduce/reduce冲突

parser.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]
如何检测语法的哪一部分产生冲突?是否有Bison生成的日志,我可以在其中查看冲突?还有,我怎样才能解决这个问题

语法:

%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
  |
  ;
如何检测语法的哪一部分产生冲突?是否有Bison生成的日志,我可以在其中查看冲突?还有,我怎样才能解决这个问题

对。如果在bison命令行上使用-v,它将在名为.output的文件中生成所有状态的报告。报告将包括各种冲突,您可以从指示的状态中看到冲突模式是什么。在阅读本答案的其余部分之前,您应该先尝试一下

如果这样做,您将看到问题:

seq_comando: comando seq_comando
  | comando
  |
  ;
由于seq_comando可以为空,因此单个comando可以匹配:

seq_comando: comando seq_comando

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

如何检测语法的哪一部分产生冲突?是否有Bison生成的日志,我可以在其中查看冲突?还有,我怎样才能解决这个问题

对。如果在bison命令行上使用-v,它将在名为.output的文件中生成所有状态的报告。报告将包括各种冲突,您可以从指示的状态中看到冲突模式是什么。在阅读本答案的其余部分之前,您应该先尝试一下

如果这样做,您将看到问题:

seq_comando: comando seq_comando
  | comando
  |
  ;
由于seq_comando可以为空,因此单个comando可以匹配:

seq_comando: comando seq_comando

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