2009-10-28 13 views
5

Qual è il modo migliore per gestire più parser Flex/Bison all'interno di un progetto?Multiple parser di bisello/flex

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 chiamato yyparse da lì.

Quello che voglio ottenere è avere due parser diversi (parser1.y e parser2.y) ed essere in grado di usarli da una funzione esterna (supponiamo main in main.cpp).

Quali precauzioni dovrei utilizzare per esportare le funzioni yyparse all'esterno 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).

risposta

7

Nota che Bison fornisce l'opzione '-p zz' per prefisso i simboli con 'zz' invece di 'yy'.

Analogamente, Flex fornisce l'opzione '-P zz' per prefisso i simboli con 'zz' invece di 'yy'. Utilizza '-p' per il reporting delle prestazioni. È un peccato che non siano coerenti l'uno con l'altro.

+0

Quando faccio questo il mio lexer e il parser hanno un sacco di riferimenti a YYTYPE e YYSTYPE, ecc. E la compilazione fallisce. Perché non vengono convertiti? Che cosa sto facendo di sbagliato?? Non voglio un parser rientrante, voglio solo un parser unico che invochi uno dei due parser, quindi il programma si chiude. – TimeHorse

+0

@TimeHorse: Data la quantità di tempo tra il momento in cui questa domanda ha avuto risposta e il tuo commento/domanda, penso che dovresti fare una nuova domanda, illustrando il problema che hai con due piccoli esempi di lexer/grammar (un MCVE - [MCVE ]) e mostra il processo di generazione che stai utilizzando e i messaggi di errore che stai ricevendo. Senza che tu colga l'opportunità di fornire tali informazioni, che ottieni con una nuova domanda, non posso davvero dare una risposta. Con ogni mezzo torna e lascia un commento qui chiedendomi di guardare la tua nuova domanda; considera anche un link a questa domanda nel tuo. –

10

Oltre alla risposta di Leffler, vorrei fornire un altro approccio qui:

Nel file .lex si potrebbe usare %option prefix="PREFIX", e nel file .y si potrebbe utilizzare %define api.prefix PREFIX, che fa la stessa cosa di passaggio -p PREFIX a Bison e -P PREFIX a Flex.

Avviso dopo il primario del prefisso predefinito yy, è possibile accedere a nomi interni tramite sia l'originale e la tua yy* sovrascritto PREFIX*, mentre, ovviamente, per i nomi esterni è necessario utilizzare il PREFIX* per accedervi.

+0

Nota che nelle versioni moderne di bisonte devi fare "% define api.prefix {PREFIX}" o ricevi un avvertimento –

5

Se si utilizza Bison 3.0 o meglio, allora dare un'occhiata a %define api.prefix {foo_}, che sostituisce tutte le yy e YY prefissi con foo_ e FOO_.

Vedere Documentation about Multiple Parsers.

Tra Bison 2.6 e 3.0, non c'erano parentesi: %define api.prefix foo_.

-1

In aggiunta a ciò che è stato già detto, se si utilizza un '% definiscono api.prefix {prefix}' sarà anche rinominare yytext & & yyparse a PREFIXtext e PREFIXparse. Non dimenticare il {} intorno al prefisso!
Lo stesso vale per '% option prefix = "PREFIX"' in lex, il tuo lexer verrà rinominato in PREFIXlex.