Ошибка компиляции файла.y.c в синтаксическом анализе Bison

#c #bison #flex-lexer

#c #бизон #флекс-лексер

Вопрос:

Я пытаюсь скомпилировать и запустить файл Bison и использовал следующие команды в терминале Linux:

 bison -d comp.y mv comp.tab.h comp.h mv comp.tab.c comp.y.c flex fonte.l mv lex.yy.c fonte.lex.c gcc -g -c fonte.lex.c -o fonte.lex.o gcc -g -c comp.y.c -o comp.y.o  

Все работает без проблем. Но когда я запускаю последнюю ( gcc -g -c comp.y.c -o comp.y.o ), она выдает следующие ошибки:

 comp.tab.c:1278:16: warning: implicit declaration of function ‘yylex’ [-Wimplicit-function-declaration] comp.y:22:22: warning: implicit declaration of function ‘yyerror’; did you mean ‘yyerrok’? [-Wimplicit-function-declaration]  22 | FECHA_CHAVE | error {yyerrok("erro no inicio", linhas); };  | ^~~~~~~  | yyerrok comp.y: In function ‘yyerror’: comp.y:61:4: warning: implicit declaration of function ‘strcmp’ [-Wimplicit-function-declaration]  61 | if(strcmp(str,"syntax error")==0){  | ^~~~~~ comp.y: At top level: comp.y:72:1: warning: return type defaults to ‘int’ [-Wimplicit-int]  72 | int main (int argc, char **argv )```   

Я пытался найти некоторые решения в Интернете, но ничего по-настоящему не работало. Вот мой файл комп.у:

 %{ #include lt;stdio.hgt; #include lt;stdlib.hgt; extern int linhas; extern int erros; int yylex(void); %}  %token ASPAS ABRE_PARENTESIS FECHA_PARENTESIS %token ABRE_CHAVE FECHA_CHAVE SEPARADOR VIRGULA FLOAT INT PRINTF VOID DOUBLE LONG MAIN %token IDENTIFICADOR INTEIRO REAL OPERADOR COMPARADORES NEGACAO IGUAL %token ATRIBUICAO %start Programa_principal  %%  //programa principal Programa_principal: MAIN ABRE_PARENTESIS FECHA_PARENTESIS ABRE_CHAVE Comandos FECHA_CHAVE | error {yyerrok("erro no inicio", linhas); };  Comandos: Comando Comandos | Comando ;  Comando: Declaracao | Atribuicao | Print | error {yyerror("erro de comando",linhas); };  Declaracao: Tipo Decl SEPARADOR;  Tipo: INT | FLOAT | DOUBLE | LONG INT ;  Decl: LISTA_VAR ;  LISTA_VAR: IDENTIFICADOR Atribui_valor VIRGULA LISTA_VAR | IDENTIFICADOR Atribui_valor;  Atribui_valor: IGUAL Num | ;  Num: INTEIRO | REAL ;   Atribuicao: IDENTIFICADOR IGUAL Exp SEPARADOR ;  Exp: INT x | FLOAT x | Num x | IDENTIFICADOR x;  x: OPERADOR Exp | ;  //Sintaxe de impressão Print: PRINTF ABRE_PARENTESIS ASPAS Qualquer_palavra ASPAS FECHA_PARENTESIS SEPARADOR;  Qualquer_palavra: IDENTIFICADOR y;  y: IDENTIFICADOR y | ;  %%  FILE *yyin;  int yyerror(char *str, int num_linha) { if(strcmp(str,"syntax error")==0){ erros  ; printf("Erro sintáticon"); } else { printf("O erro aparece próximo à linha %dn",num_linha);//Exibe a linha do erro } return erros; }  int main (int argc, char **argv ) {   argv, --argc; //desconsidera o nome do programa if ( argc gt; 0 ) yyin = fopen( argv[0], "r" ); else { puts("Falha ao abrir arquivo, nome incorreto ou não especificado. Digite o comando novamente.");  exit(0); } do {  yyparse();  } while (!feof(yyin)); if(erros==0) puts("Análise concluída com sucesso"); }  

Раньше это было просто «main», поэтому я изменил его на «int main». Я также поместил int yylex(); в верхней части comp.y файла, но ни один из 2 не решил ни одной из проблем.

Комментарии:

1. Если вы внесли эти изменения comp.y и соответствующие ошибки сохраняются, это, вероятно, означает, что вы не перекомпилировали правильный файл. Вы должны использовать какой-то сценарий сборки, а не сложную серию команд. (Вы можете упростить команды, используя -o опции bison и flex. Но вы все равно должны использовать сценарий сборки.) Я не понимаю мотивации для использования strcmp in yyerror , но если вы собираетесь его использовать, вам это понадобится #include lt;string.hgt; . И yyerror должен быть объявлен в прологе.

2. Разве это не просто опечатка, и yyerrok она должна быть yyerror ?