Vantaggi di Antlr (rispetto a dire, lex / yacc / bison) [chiuso]


143

Ho usato lex e yacc (più spesso bisonti) in passato per vari progetti, di solito traduttori (come un sottoinsieme di EDIF trasmesso in streaming in un'app EDA). Inoltre, ho dovuto supportare il codice basato su grammatiche lex / yacc risalenti a decenni fa. Quindi conosco gli strumenti, anche se non sono un esperto.

Ho visto commenti positivi su Antlr in varie sedi in passato e sono curioso di sapere cosa potrei perdere. Quindi, se hai usato entrambi, per favore dimmi cosa c'è di meglio o di più avanzato in Antlr. I miei attuali vincoli sono che lavoro in un negozio C ++ e qualsiasi prodotto che spediamo non includerà Java, quindi i parser risultanti dovrebbero seguire quella regola.

Risposte:


145

Aggiornamento / avviso: questa risposta potrebbe non essere aggiornata!


Una delle principali differenze è che ANTLR genera un parser LL (*), mentre YACC e Bison generano entrambi parser LALR. Questa è una distinzione importante per una serie di applicazioni, i più ovvi sono gli operatori:

expr ::= expr '+' expr
       | expr '-' expr
       | '(' expr ')'
       | NUM ;

ANTLR è totalmente incapace di gestire questa grammatica così com'è. Per usare ANTLR (o qualsiasi altro generatore di parser LL), dovresti convertire questa grammatica in qualcosa che non è ricorsivo a sinistra. Tuttavia, Bison non ha alcun problema con le grammatiche di questo modulo. Dovresti dichiarare "+" e "-" come operatori associativi di sinistra, ma ciò non è strettamente necessario per la ricorsione di sinistra. Un esempio migliore potrebbe essere l'invio:

expr ::= expr '.' ID '(' actuals ')' ;

actuals ::= actuals ',' expr | expr ;

Si noti che sia il expre le actualsregole sono lasciati-ricorsivo. Ciò produce un AST molto più efficiente quando arriva il momento della generazione del codice perché evita la necessità di più registri e fuoriuscite inutili (un albero inclinato a sinistra può essere compresso mentre un albero inclinato a destra non può).

In termini di gusto personale, penso che le grammatiche LALR siano molto più facili da costruire e da eseguire il debug. Il rovescio della medaglia è che devi affrontare errori in qualche modo criptici come il cambio-riduzione e (il temuto) ridurre-ridurre. Questi sono errori che Bison rileva durante la generazione del parser, quindi non influisce sull'esperienza dell'utente finale, ma può rendere il processo di sviluppo un po 'più interessante. ANTLR è generalmente considerato più facile da usare rispetto a YACC / Bison proprio per questo motivo.


2
Quindi il grande, forse unico, vantaggio di Antlr nella tua percezione è che genera meno errori come sr e rr durante la fase di costruzione? Immagino che ci proverò, ma probabilmente finirò per restare fedele a quello che so ...
Don Wakefield,

1
Sì, è praticamente tutto. :-) Non sono nemmeno d'accordo con l'opinione popolare secondo cui ANTLR è più facile di Bison, quindi penso che sarei d'accordo con la tua decisione.
Daniel Spiewak,

2
La regola degli "effettivi" ha bisogno di una seconda regola per indicare che un semplice "expr" è un reale? Altrimenti, bella spiegazione.
Jonathan Leffler il

8
Un altro commento che ho scoperto di recente, sebbene vecchio di dieci anni, fa una ragionevole osservazione dell'output : compilers.iecc.com/comparch/article/98-11-040 : "ANTLR / PCCTS sono LL che rende la scrittura grammaticale più difficile, ma il il codice generato è leggibile. Yacc essendo LALR (ovviamente lo sai) facilita la scrittura della grammatica, ma il codice generato potrebbe anche essere geroglifico ".
Don Wakefield,

72
Ho appena completato il supporto immediato per la ricorsione a sinistra per ANTLR prossima versione v3.4. Gestisce regole di espressione LR e cose simili come le regole del dichiaratore C. :)
Terence Parr,

117

La differenza più significativa tra YACC / Bison e ANTLR è il tipo di grammatiche che questi strumenti possono elaborare. YACC / Bison gestiscono grammatiche LALR, ANTLR gestisce grammatiche LL.

Spesso, le persone che hanno lavorato con le grammatiche LALR per molto tempo, troveranno più difficile lavorare con le grammatiche LL e viceversa. Ciò non significa che le grammatiche o gli strumenti siano intrinsecamente più difficili da lavorare. Lo strumento che trovi più facile da usare dipenderà principalmente dalla familiarità con il tipo di grammatica.

Per quanto riguarda i vantaggi, ci sono aspetti in cui le grammatiche LALR presentano vantaggi rispetto alle grammatiche LL e ci sono altri aspetti in cui le grammatiche LL presentano vantaggi rispetto alle grammatiche LALR.

YACC / Bison genera parser guidati da tabella, il che significa che la "logica di elaborazione" è contenuta nei dati del programma parser, non tanto nel codice del parser. Il risultato è che anche un parser per un linguaggio molto complesso ha un footprint di codice relativamente piccolo. Ciò era più importante negli anni '60 e '70, quando l'hardware era molto limitato. I generatori di parser guidati da tabelle risalgono a questa era e il footprint di codice ridotto era un requisito fondamentale a quei tempi.

ANTLR genera parser di discesa ricorsivi, il che significa che la "logica di elaborazione" è contenuta nel codice del parser, poiché ogni regola di produzione della grammatica è rappresentata da una funzione nel codice del parser. Il vantaggio è che è più facile capire cosa sta facendo il parser leggendo il suo codice. Inoltre, i parser di discesa ricorsivi sono in genere più veloci di quelli guidati da tabella. Tuttavia, per linguaggi molto complessi, l'impronta del codice sarà maggiore. Questo è stato un problema negli anni '60 e '70. All'epoca solo linguaggi relativamente piccoli come Pascal, per esempio, erano implementati in questo modo a causa di limitazioni hardware.

I parser generati da ANTLR sono in genere nelle vicinanze di 10.000 righe di codice e altro ancora. I parser di discesa ricorsivi scritti a mano sono spesso nello stesso campo. Il compilatore Oberon di Wirth è forse il più compatto con circa 4000 righe di codice inclusa la generazione di codice, ma Oberon è un linguaggio molto compatto con solo circa 40 regole di produzione.

Come qualcuno ha già sottolineato, un grande vantaggio per ANTLR è lo strumento grafico IDE, chiamato ANTLRworks. È un laboratorio completo di progettazione grammaticale e linguistica. Visualizza le tue regole grammaticali mentre le digiti e se trova dei conflitti ti mostrerà graficamente qual è il conflitto e cosa lo causa. Può anche refactoring e risolvere automaticamente conflitti come la ricorsione a sinistra. Una volta che hai una grammatica libera da conflitti, puoi consentire ad ANTLRworks di analizzare un file di input della tua lingua e creare un albero di analisi e AST per te e mostrarlo graficamente nell'IDE. Questo è un grande vantaggio perché può farti risparmiare molte ore di lavoro: troverai errori concettuali nella progettazione del tuo linguaggio prima di iniziare a scrivere codice! Non ho trovato nessuno strumento simile per le grammatiche LALR, sembra che non esistano strumenti del genere.

Anche per le persone che non desiderano generare i loro parser ma che li codificano manualmente, ANTLRworks è un ottimo strumento per la progettazione / prototipazione del linguaggio. Molto probabilmente il miglior strumento disponibile. Sfortunatamente, questo non ti aiuta se vuoi costruire parser LALR. Passare da LALR a LL semplicemente per trarre vantaggio da ANTLRworks può essere utile, ma per alcune persone, cambiare tipo di grammatica può essere un'esperienza molto dolorosa. In altre parole: YMMV.


4
piace perché spiega la storia dietro i diversi meccanismi che rendono immediatamente comprensibili le persone
tintinnio il

35

Un paio di vantaggi per ANTLR:

  • può generare parser in varie lingue - Java non è richiesto per eseguire il parser generato.
  • La straordinaria GUI semplifica il debug della grammatica (ad es. Puoi vedere gli AST generati direttamente nella GUI, non sono necessari strumenti extra)
  • Il codice generato è in realtà leggibile dall'uomo (è uno degli obiettivi di ANTLR) e il fatto che genera parser LL sicuramente aiuta in questo senso.
  • la definizione di terminali è anche libera dal contesto (al contrario di regex in (f) lex) - permettendo così, ad esempio, la definizione di terminali contenenti parentesi chiuse correttamente

I miei 0,02 $


9

Un altro vantaggio di ANTRL è che puoi usare ANTLRWORKS , anche se non posso dire che questo sia un vantaggio rigoroso, poiché potrebbero esserci strumenti simili anche per altri generatori.


9
  • Bison e Flex comportano un ingombro di memoria ridotto, ma non hai IDE grafico.
  • antlr utilizza più memoria, ma hai antlrworks, un IDE grafico.

L'uso della memoria Bison / Flex è in genere un mbyte o giù di lì. Contrastalo con antlr - supponendo che utilizzi 512 byte di memoria per ogni token nel file che vuoi analizzare. 4 milioni di token e la memoria virtuale è esaurita su un sistema a 32 bit.

Se il file che si desidera analizzare è di grandi dimensioni, antlr potrebbe esaurire la memoria, quindi se si desidera solo analizzare un file di configurazione, sarebbe una soluzione praticabile. Altrimenti, se vuoi analizzare un file con molti dati, prova Bison.


7
Sono curioso. Potete indicare la documentazione che descrive il consumo di 512 byte di memoria per token? Non ricordo di aver visto quella discussione. La mia scelta delle parole chiave di Google non mi sta dando soddisfazione ...
Don Wakefield,

2
Stai parlando dell'impronta di memoria del generatore di parser durante la generazione di un parser o stai parlando dell'impronta di memoria del parser generato mentre analizza l'input per la lingua di origine? Milioni di token in una grammatica sarebbero assolutamente pazzi. Dovresti essere rinchiuso in un istituto mentale se hai seriamente cercato di vendere un'idea del genere. Per quanto riguarda i file di input per il parser stesso, potrebbero esserci casi in cui questi possono avere un numero estremamente elevato di token, ma la maggior parte delle lingue sono modulari, non si analizza l'intero input in un singolo file, i singoli moduli sono più piccoli.
trijezdci,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.