ado*_*srs 1 parsing yacc bison
我写了以下语法,Bison 警告我有关归约/归约冲突。
\n\nparser.y: warning: 1 reduce/reduce conflict [-Wconflicts-rr]\nRun Code Online (Sandbox Code Playgroud)\n\n如何检测语法的哪一部分产生了冲突?Bison 是否生成了日志,可以在其中查看冲突?还有,我该如何解决这个问题?
\n\n语法:
\n\n%left TK_OC_OR TK_OC_AND\n%left \'<\' \'>\' TK_OC_LE TK_OC_GE TK_OC_EQ TK_OC_NE\n%left \'+\' \'-\'\n%left \'*\' \'/\'\n\n%nonassoc LOWER_THAN_ELSE\n%nonassoc TK_PR_ELSE\n\n%start s\n\n%type<symbol> decl_var\n%type<symbol> cabecalho\n\n%%\n\ns: decl_global s\n | def_funcao s\n |\n ;\n\ndecl_global: decl_var \';\'\n | decl_vetor \';\'\n | decl_var {error("Faltando o \';\' no final do comando.", $1->line); return IKS_SYNTAX_ERRO;}\n ;\n\ndecl_local: decl_var \';\' decl_local\n |\n ;\n\ndecl_var\n : tipo_var TK_IDENTIFICADOR {$$ = $2;}\n ;\n\ndecl_vetor\n : tipo_var TK_IDENTIFICADOR \'[\' TK_LIT_INT \']\'\n ;\n\n\ntipo_var: TK_PR_INT\n | TK_PR_FLOAT\n | TK_PR_BOOL\n | TK_PR_CHAR\n | TK_PR_STRING\n ;\n\ndef_funcao: cabecalho decl_local bloco_comando\n | cabecalho decl_local bloco_comando \';\' {error("Declara\xc3\xa7\xc3\xa3o de fun\xc3\xa7\xc3\xa3o com \';\' no final do comando.\\n",$1->line); return IKS_SYNTAX_ERRO;} \n ;\n\nchamada_funcao\n : TK_IDENTIFICADOR \'(\' lista_expressoes \')\'\n ;\n\ncabecalho: decl_var \'(\' lista_parametros \')\' {$$ = $1;}\n ;\n\nlista_parametros: lista_parametros_nao_vazia\n |\n ;\n\nlista_parametros_nao_vazia: parametro \',\' lista_parametros_nao_vazia\n | parametro\n ;\n\nparametro: decl_var\n ;\n\ncomando: bloco_comando\n | controle_fluxo\n | atribuicao\n | entrada\n | saida\n | retorna\n | decl_var \';\'\n | chamada_funcao\n | \';\'\n ;\n\nbloco_comando: \'{\' seq_comando \'}\'\n ;\n\nseq_comando: comando seq_comando\n | comando\n |\n ;\n\natribuicao: TK_IDENTIFICADOR \'=\' expressao\n | TK_IDENTIFICADOR \'[\' expressao \']\' \'=\' expressao\n ;\n\nentrada\n : TK_PR_INPUT TK_IDENTIFICADOR\n ;\n\nsaida\n : TK_PR_OUTPUT lista_expressoes_nao_vazia\n ;\n\nlista_expressoes_nao_vazia: expressao \',\' lista_expressoes_nao_vazia\n | expressao\n ;\n\nretorna: TK_PR_RETURN expressao \';\'\n ;\n\ncontrole_fluxo\n : TK_PR_IF \'(\' expressao \')\' TK_PR_THEN comando %prec LOWER_THAN_ELSE\n | TK_PR_IF \'(\' error \')\' TK_PR_THEN comando \n | TK_PR_IF \'(\' expressao \')\' TK_PR_THEN comando TK_PR_ELSE comando\n | TK_PR_WHILE \'(\' expressao \')\' TK_PR_DO comando\n | TK_PR_DO comando TK_PR_WHILE \'(\' expressao \')\'\n | TK_PR_DO comando TK_PR_WHILE \'(\' error \')\'\n ;\n\nexpressao: TK_IDENTIFICADOR\n | TK_IDENTIFICADOR \'[\' expressao \']\'\n | TK_LIT_INT\n | TK_LIT_FLOAT\n | TK_LIT_FALSE\n | TK_LIT_TRUE\n | TK_LIT_CHAR\n | TK_LIT_STRING\n | expressao \'+\' expressao \n | expressao \'-\' expressao \n | expressao \'*\' expressao \n | expressao \'/\' expressao \n | expressao \'<\' expressao \n | expressao \'>\' expressao \n | \'+\' expressao\n | \'-\' expressao\n | \'(\' expressao \')\'\n | expressao TK_OC_LE expressao\n | expressao TK_OC_GE expressao\n | expressao TK_OC_EQ expressao\n | expressao TK_OC_NE expressao\n | expressao TK_OC_AND expressao\n | expressao TK_OC_OR expressao\n | chamada_funcao\n ;\n\nlista_expressoes: lista_expressoes_nao_vazia\n |\n ;\nRun Code Online (Sandbox Code Playgroud)\n
如何检测语法的哪一部分产生了冲突?Bison 是否生成了日志,可以在其中查看冲突?还有,我该如何解决这个问题?
是的。如果您-v在 bison 命令行上使用,它将在名为 的文件中生成所有状态的报告<filename>.output。该报告将包括各种冲突,您可以从指示的状态中看到冲突的模式是什么。在阅读本答案的其余部分之前,您应该尝试一下。
如果你这样做,你就会看到问题:
seq_comando: comando seq_comando
| comando
|
;
Run Code Online (Sandbox Code Playgroud)
由于seq_comando可以为空,因此单个comando可以匹配:
seq_comando: comando seq_comando
Run Code Online (Sandbox Code Playgroud)
或者
seq_comando: comando
Run Code Online (Sandbox Code Playgroud)
简单的解决办法就是摆脱规则seq_comando: comando。您可能还需要考虑将右递归更改为左递归 ( seq_comando: seq_comando comando | /* empty */;),因为这将需要更少的解析器堆栈。
| 归档时间: |
|
| 查看次数: |
783 次 |
| 最近记录: |