Semplice Flex / Bison C ++

Ho già cercato la mia risposta ma non ho avuto alcuna risposta rapida per un semplice esempio.

Voglio compilare uno scanner + parser flex / bison usando g ++ solo perché voglio usare le classi C ++ per creare AST e cose simili.

Cercando su internet ho trovato alcuni exploit, tutti dicendo che l’unica cosa necessaria è dichiarare alcuni prototipi di funzione usando extern “C” nel file lex.

Quindi il mio file shady.y è

%{ #include  #include "opcodes.h" #include "utils.h" void yyerror(const char *s) { fprintf(stderr, "error: %s\n", s); } int counter = 0; extern "C" { int yyparse(void); int yylex(void); int yywrap() { return 1; } } %} %token INTEGER FLOAT %token T_SEMICOL T_COMMA T_LPAR T_RPAR T_GRID T_LSPAR T_RSPAR %token EOL %token T_MOV T_NOP %% ... GRAMMAR OMITTED ... %% main(int argc, char **argv) { yyparse(); } 

mentre il file shady.l è

 %{ #include "shady.tab.h" %} %% "MOV"|"mov" { return T_MOV; } "NOP"|"nop" { return T_NOP; } ";" { return T_SEMICOL; } "," { return T_COMMA; } "(" { return T_LPAR; } ")" { return T_RPAR; } "#" { return T_GRID; } "[" { return T_LSPAR; } "]" { return T_RSPAR; } [1-9][0-9]? { yylval = atoi(yytext); return INTEGER;} [0-9]+"."[0-9]+ | "."?[0-9]? { yylval.d = atof(yytext); return FLOAT; } \n { return EOL; } [ \t] { /* ignore whitespace */ } . { printf("Mystery character %c\n", *yytext); } %% 

Finalmente nel makefile uso g ++ invece di gcc:

 shady: shady.l shady.y bison -d shady.y -o shady.tab.c flex shady.l g++ -o [email protected] shady.tab.c lex.yy.c -lfl 

flex e bison funzionano correttamente ma al momento del collegamento ottengo il seguente errore:

 Undefined symbols: "_yylex", referenced from: _yyparse in ccwb57x0.o 

Ovviamente se provo a cambiare qualcosa sulla funzione nel file bison si dice che yylex non è dichiarato nell’ambito di yyparse.

Sto cercando di risolvere semplicemente qualcosa che è più complesso di quanto sembri? In realtà non ho bisogno di una struttura chiusa per avere accesso a analisi e lexer in modo orientato agli oggetti, voglio solo farlo funzionare.

Voglio solo essere in grado di usare C ++ in file bison (per creare AST) e chiamare yyparse () dagli oggetti C ++.

Grazie in anticipo

Hai bisogno extern "C" {} per yylex di essere in shady.l :

 %{ extern "C" { int yylex(void); } #include "shady.tab.h" %} %% "MOV"|"mov" { return T_MOV; } "NOP"|"nop" { return T_NOP; } ...etc... 

Inoltre, dopo aver aggiunto una regola grammaticale fittizia, sono riuscito a creare ed eseguire questo con solo:

  559 flex shady.l 560 bison -d shady.y 561 g++ shady.tab.c lex.yy.c