2011-09-30 15 views
7

Uso Bison e Flex per creare una coppia di analizzatori/parser rientranti ma non riesco a capire dove tutto deve essere incluso e dichiarato.Pasticcio dichiarazione Bison/Flex ... come devo includere/dichiarare dove?

Prima di tutto, sto usando rientrante Flex così ho bisogno di passare il tipo yyscan_t scanner primo a Bison dichiarando %parse-param {yyscan_t scanner} e poi fare passare questo Bison a Flex dichiarando %lex-param {yyscan_t scanner}. Ma yyscan_t non è dichiarato da Bison quindi devo includere il file di intestazione dello scanner generato da Flex (che ho chiamato scanner.flex.h) nel mio file Bison. Ma dal momento che il mio file Flex include l'intestazione Bison e l'intestazione Bison ora include l'intestazione Flex, ricevo circolari include che incasina roba in modi imprevedibili!

E diciamo che voglio aggiungere nel rilevamento della posizione con %locations nel mio file Bison e %bison-locations nel mio file Flex. Ora ho bisogno di cambiare la dichiarazione del mio yyerror e del mio yylex (sembra che devo definire yylex anche se è definito nell'intestazione di Flex generato ma non posso includere quello, ricordi?) Nel mio file Bison per includere il puntatore YYLTYPE . Ma adesso? Sembra che la dichiarazione YYLTYPE predefinita sia posizionata dopo che il prologo è stato inserito e quindi non posso usare questo YYLTYPE predefinito nella dichiarazione del mio yyerror e del mio yylex.

Mi rendo conto che ci sono un sacco di soluzioni per questi problemi ... ma come si dovrebbe fare correttamente? Mi sfugge totalmente e questo mi lascia solo un pasticcio ...

risposta

4

Nella parte superiore del tuo file bison devi inoltrare questi valori. Puoi farlo in un'intestazione comune o nel file di codice prima di includere i file flex e bison. yyscan_t è solo un typedef di un void *, quindi ho dichiarato i parametri come puntatori void per farlo funzionare.

CommonHeader.h

int yylex (union YYSTYPE * yyval_param, struct YYLTYPE * yylloc_param, void * yyscanner); 
int yyerror(struct YYLTYPE * yylloc_param, void *scanner, const char *s); 

Esempio di yyerror

int yyerror(struct YYLTYPE * yylloc_param, void *scanner, const char *s) 
{ 
    printf("*** Lexical Error %s %d.%d-%d.%d\n", s, 
     yylloc_param->first_line, yylloc_param->first_column, 
     yylloc_param->last_line, yylloc_param->last_column); 
} 
+0

che so di essere yyscan_t void * così l'ho già fatto che, anche se si sentiva un po 'come un hack in quanto si suppone di essere opaco. E allora YYLTYPE? Non è dichiarato fino a dopo il prologo e in avanti dichiarando che un'intera struttura sembra un po 'troppo? –

+0

Perché inoltrare la dichiarazione di una struttura sembra un po 'troppo. Un'altra opzione è aggiungere% definisce il tuo file bison. Questo genererà un file di intestazione che puoi includere. – Joe

+0

Una scoreggia totale del cervello da parte mia ... Ho pensato di definire ma ho detto che avrei dichiarato. Generico un file di intestazione ma non può essere incluso nel file Bison in quanto porterà a una ricorsione infinita poiché le intestazioni generate da Bison non hanno guardie incluse (ma hanno guardie contro i tipi di ridefinizione). ho potuto inoltrare dichiarare YYLTYPE però, qualcosa di simile ?: 'struct YYLTYPE;' ' typedef struct YYLTYPE YYLTYPE;' –

1

sono imbattuto in questo mentre alla ricerca di qualcosa di diverso.

La risposta è che Bison emette la dichiarazione interna per YYLTYPE dopo la% union spec. Quindi, mettendo i prototipi di funzione e altre cose in una sezione di prologo dopo che% union evita il problema di dichiarare YYLTYPE da solo; questo è abbastanza OK, Bison permette più di una sezione prologo:

%{ 

/* Prologue 1 */ 

%} 

%this 

%that 

%union {} 

%{ 

/* Prologue 2, YYLTYPE declared */ 

%} 

%% 

blah: talk | blah talk 

%% 
Problemi correlati