Mi piacerebbe fare un po 'di analisi e di tokenizzazione in C++ per scopi di apprendimento. Ora mi capita spesso di incontrare bison/yacc e lex quando leggo su questo argomento online. Ci sarebbe qualche beneficio di primo piano nell'usarli, ad esempio un tokenizzatore/parser scritto usando STL o boost :: regex o forse anche solo C?C++ qual è il vantaggio di lex e bisonte per un tokenizzatore self-parser/parser
risposta
Recentemente ho iniziato a scrivere un semplice lexer e parser.
Si è scoperto che il lexer era più semplice da codificare a mano. Ma il parser era un po 'più difficile. Il parser generato da Bison ha funzionato quasi subito e mi ha dato molti messaggi utili su dove avevo dimenticato gli stati. In seguito scrissi lo stesso parser a mano ma ci volle molto più debug prima che funzionasse perfettamente.
L'attrattiva di generare strumenti per i parser e parser è che è possibile scrivere le specifiche in un linguaggio pulito e di facile lettura che si avvicina ad una resa più breve possibile delle specifiche. Un parser scritto a mano è solitamente almeno due volte più grande. Inoltre, il parser automatico (/ lexer) viene fornito con un sacco di codice diagnostico e logica per aiutarti a ottenere il debug della cosa.
Una specifica del parser/lexer in linguaggio simile a BNF è anche molto più semplice da modificare, nel caso in cui la lingua o le esigenze cambino. Se hai a che fare con un parser/lexer scritto a mano, potresti aver bisogno di approfondire il tuo codice e apportare modifiche significative.
Infine, poiché sono spesso implementati come macchine a stati finiti senza retrocessione (migliaia di miliardi di opzioni su Bison, quindi non è sempre un dato), è possibile che il codice generato automaticamente sia più efficiente della tua mano prodotto codificato.
Qualcun altro ha già scritto e DEBUGGATO loro per te?
Più facile e più generale. Bison/Lex può tonkenize e analizzare la grammatica arbitraria e presentarlo in quello che potrebbe essere un formato più semplice. Potrebbero essere anche più veloci, a seconda di quanto bene scrivi la tua espressione regolare.
Non vorrei scrivere il mio parser in C poiché la lingua non ha grandi intuizioni riguardo le stringhe. Se scrivi il tuo, ti consiglierei perl per la facilità di regex (o forse python).
È probabilmente più veloce utilizzare gli strumenti esistenti, ma può essere divertente o meno. Se hai tempo e dal momento che è solo per l'apprendimento, provaci. C++ è un buon linguaggio per cominciare.
Certamente non possono analizzare "grammatica arbitraria". –
Diverse corse per persone diverse. A me personalmente piacciono i parser di discendenza ricorsiva, li trovo facili da capire e puoi farli produrre messaggi di errore utente superiore a quelli prodotti da strumenti come il bisonte.
Trovo anche che tendano ad essere un po 'più robusti di fronte ai complicati casi limite in alcune lingue dove l'analisi e il lexing si sovrappongono. – Kylotan
grazie per la tua risposta dettagliata, credo che proverò sia per il confronto, dal momento che è solo per divertimento in ogni caso! – moka