我写了下面的语法,Bison警告我减少/减少冲突。
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
|
;
答案 0 :(得分:4)
如何检测语法的哪个部分产生冲突?是否有Bison生成的日志,我可以看到冲突?而且,我怎么能解决这个问题?
是。如果在bison命令行上使用-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 */;
),因为这将需要更少的解析器堆栈。