Più parser flex / bison
-
06-07-2019 - |
Domanda
Qual è il modo migliore per gestire più parser Flex / Bison all'interno di un progetto?
Ho scritto un parser e ora ho bisogno di un secondo nello stesso progetto. Finora nella terza sezione di parser1.y
ho inserito il metodo main (..)
e da lì ho chiamato yyparse
.
Quello che voglio ottenere è avere due diversi parser ( parser1.y
e parser2.y
) ed essere in grado di usarli da una funzione esterna (supponiamo < code> main in main.cpp
).
Quali precauzioni dovrei usare per esportare le funzioni yyparse
al di fuori dei file .y
e come dovrei gestire due parser?
PS. Sto usando g ++ per compilare ma non le versioni C ++ di Flex e Bison e vorrei mantenerlo in questo modo (evitando così di incapsulare il parser all'interno di un oggetto).
Soluzione
Nota che Bison fornisce l'opzione '-p zz' per aggiungere un prefisso ai simboli con 'zz' invece di 'yy'.
Analogamente, Flex fornisce l'opzione '-P zz' per aggiungere un prefisso ai simboli con 'zz' anziché 'yy'. Utilizza '-p' per i rapporti sulle prestazioni. È un peccato che non siano coerenti tra loro.
Altri suggerimenti
Oltre alla risposta di Leffler, vorrei fornire un altro approccio qui:
Nel file .lex
puoi usare % option prefix = " PREFIX "
e nel file .y
puoi usare % definisce api.prefix PREFIX
, che fa la stessa cosa passando -p PREFIX
a Bison e -P PREFIX
a Flex.
Avviso dopo la sostituzione del prefisso predefinito yy
, è possibile accedere ai nomi interni tramite ENTRAMBI il yy *
originale e il PREFIX *
sovrascritto , mentre ovviamente per i nomi esterni DEVI usare il tuo PREFIX *
per accedervi.
Se usi Bison 3.0 o superiore, dai un'occhiata a % define api.prefix {foo_}
, che sostituisce tutti yy
e YY prefissi con
foo_
e FOO_
.
Vedi Documentazione su Multiple Parser .
Tra Bison 2.6 e 3.0 non c'erano parentesi graffe: % define api.prefix foo_
.
La variabile api.prefix non funziona più per me (produce un errore di compilazione)
%define api.prefix {PREFIX}
Ho dovuto usare la sintassi seguente
%name-prefix="PREFIX"
Oltre a quanto già affermato, se si utilizza un '% define api.prefix {PREFIX}' rinominerà anche yytext & amp; & amp; yyparse in PREFIXtext e PREFIXparse. Non dimenticare il {} attorno al prefisso!
Lo stesso vale per '% option prefix = " PREFIX "' in lex, il tuo lexer verrà rinominato in PREFIXlex.