#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
inyyerror
, но если вы собираетесь его использовать, вам это понадобится#include lt;string.hgt;
. Иyyerror
должен быть объявлен в прологе.2. Разве это не просто опечатка, и
yyerrok
она должна бытьyyerror
?