Quando usare ANTLR e quando usare una libreria di analisi

6

Ho sempre voluto imparare come scrivere un compilatore - Ho deciso di usare ANTLR e sto attualmente leggendo il libro (è molto buono tra l'altro)

Sono abbastanza nuovo in questo, quindi andate piano, ma il jist sembra essere che scrivete la vostra grammatica, trasformatela in una struttura dati (di solito un AST) e poi percorretela una o più volte effettivamente eseguendo l'operazione. carne 'di qualsiasi cosa tu voglia che il tuo programma faccia.

Se il mio "linguaggio" di input era qualcosa come JSON o XML, cioè qualcosa che probabilmente ha una libreria che può trasformarlo in un grafico di pojos - questo nega la necessità di fare il lexing e l'analisi con un compilatore come ANTLR ? chiaramente se il mio input è molto personalizzato allora ho bisogno di scrivere il mio lexer / parser - ma potrei e dovrei abbreviare se la mia lingua di input è già ampiamente utilizzata.

Sarebbe giusto dire che potresti analizzare, dire json, con Jackson, in POJO e poi guidare il tuo codice dei pojos risultanti? - o in questo caso, un compilatore compilatore "appropriato" offre qualche vantaggio?

Modificato (in base alle risposte) per aggiungere

Probabilmente avrei dovuto far notare che la mia domanda era leggermente ipotetica - non avrei mai provato a costruire un linguaggio di programmazione in XML!

Quindi immagino che l'accordo sia AST! = Pojo - e i tree walker che ti danno sono più utili nel caso in cui tu abbia bisogno di "camminare" sulla struttura dei dati ed eseguire il codice.

    
posta phatmanace 26.03.2015 - 23:46
fonte

4 risposte

8

Potresti usare entrambi per eseguire entrambe le attività. La differenza è ciò per cui ciascuno è destinato. Puoi disegnare immagini o diagrammi in Excel se vuoi, ma puoi anche disegnare un'immagine in qualcosa costruito per quello scopo.

Le librerie JSON e XML sono progettate per il caricamento generalizzato di documenti, estraendone parti o trasformandone le strutture in strutture diverse, ecc.

ANTLR d'altra parte è uno strumento progettato per generare parser per compilatori . È adattato specificamente per soddisfare le esigenze di tale compito.

Se usi un parser xml o json per analizzare uno di questi, alla fine finirai per scrivere un mucchio di codice che trasforma il tuo input in un AST di qualche tipo, da elaborare. Quindi, se vuoi scrivere e fare il debug di tutto questo, o usare qualcosa che ti dà in anticipo, dipende da te.

    
risposta data 27.03.2015 - 00:03
fonte
1

Se il tuo input è serializzato come XML o JSON, allora dovresti preferire un parser XML o JSON esistente. Ciò rende in definitiva più probabile che il parser sia corretto e che aiuti la compatibilità e l'interoperabilità con altri sistemi. Si noti che XML non è realmente una lingua, ma un sistema per la definizione di nuove lingue che condividono la sintassi comune. Scrivere un parser XML o YAML corretto e performante è altamente banale, e anche JSON ha un paio di problemi minori.

Una volta che il parser restituisce una struttura dati (ad esempio il DOM in caso di XML), è abbastanza semplice tradurlo in una rappresentazione AST che si adatta alle tue esigenze, molto più semplice della scrittura di un parser di tua proprietà, poiché la creazione dell'AST sarebbe far parte del parser comunque.

Nella mia esperienza, i formati di serializzazione dei dati non sono molto adatti come formato di input primario per un linguaggio interessante (tuttavia, potrebbero essere molto adatti per la serializzazione AST). Mentre XML e JSON sono leggibili, sono difficili da scrivere a mano. Ad esempio, JSON non ha nemmeno commenti e XML ha una sintassi molto dettagliata. Mentre - in una certa misura - la sintassi non è ciò che alla fine fa o rompe una lingua, una buona sintassi può spesso aiutare a trasmettere chiaramente l'intento, e un buon linguaggio si mapperà bene al suo dominio problematico sia in semantica che in sintassi.

    
risposta data 27.03.2015 - 12:41
fonte
1

In realtà sto discutendo esattamente di questo. Il mio problema è che voglio dare ai nostri utenti documenti YAML davvero belli da modificare a mano e poi ricaricarli nel nostro software - qualcosa di simile a ciò che CircleCI fa con il loro circle.yml file .

Siamo sulla JVM e SnakeYAML è un serializzatore / deserializzatore YAML molto bello, quindi posso semplicemente aggiungerlo al mio progetto e iniziare, ma ciò significa che devo passare dal vari oggetti del nostro dominio al serial-friendly POJO ('surrogati') oggetti e di nuovo indietro. E questo ha alcune conseguenze abbastanza disastrose, tra cui circa 300 linee per gestire i soli assegni nulli (sono un sacco di controlli nulli, e sono sicuro che ne ho persi alcuni e continuerò a mancarli mentre aggiungo funzionalità).

Se vado con ANTLR e faccio in modo che il nostro documento di configurazione non sia un vero documento YAML, invece un sottoinsieme ristretto di YAML I può inserire quei controlli nulli nel parser. Ma ora ho una nuova serie di problemi: la mia grammatica gestirà correttamente i riferimenti di YAML? avrò bug nella mia gestione degli spazi bianchi (YAML è un linguaggio di documento sensibile agli spazi bianchi come il linguaggio di programmazione python).

Sono molto combattuto. In questo momento i venti stanno favorendo quest'ultimo dato che la quantità di convalida del buggy che stiamo facendo sta diventando troppo ampia.

Alcune domande / pensieri che ho chiesto / avuto a me stesso che sono stati ragionevolmente utili:

  • Quali problemi specifici incontrerai nell'usare un serializzatore?
  • Quanto è complessa la tua lingua di arrivo? Che tipo di hashas ha per il tuo parser (ad es. Direttive preprocessore, commenti (con semantica?), Gestione spazi bianchi)
  • L'esperienza con grammatiche, parser e visitatori è l'esperienza con strumenti sofisticati e riutilizzabili, l'esperienza nella scrittura di null-checks e domainType.x = surrogateType.x no. Anche conoscere intimamente un serializzatore può essere utile, ma generalmente non è trasferibile dal tuo attuale linguaggio / stack tecnologico.
  • È possibile iniziare con serializzatori e parser-generatori in modo abbastanza semplice, il che significa che non è impossibile provarli entrambi. Guarda come sono sofisticate le tue classi POJO prima che il tuo serializzatore si inarcri e vedi quale tipo di albero di analisi viene generato da una semplice grammatica su un sottoinsieme della lingua che stai guardando.
risposta data 27.01.2016 - 21:16
fonte
0

@Groostav, rispondendo piuttosto che commentando così posso dire un po 'di più.

Post interessante. Da quando ho fatto la mia domanda, ho fatto un po 'più di progressi, quindi ho un po' più di prospettiva.

Penso che Id prova a utilizzare inizialmente qualcosa di standard come YAML o JSON. Quindi, se ritieni di allungare il limite di ciò che può fare il sistema di gestione della configurazione, solo allora creo un DSL.

Che cosa significa " stretching the boundary "? - Beh, penso che sia come cercare di formare idiomi di programmazione in cose come JSON - ad esempio, se provi a riempire un ciclo for in un documento json , probabilmente sei passato oltre il punto in cui dovrebbe essere un DSL piuttosto che un soluzione di file di configurazione standard.

Tocchi il secondo punto con la tua osservazione 'Null checks'. se fai un DSL e una grammatica, puoi applicare alcuni vincoli dello schema come

node 'shape' should always have a subnode called 'edges' 

che ti allevia da parte di questo fardello, in quanto la grammatica lo farà per te, anche se potresti dover lavorare per ottenere dei buoni messaggi di errore "user friendly".

Detto questo - JSON ha validatori di schemi, e scommetto che qualcuno ne ha fatto uno anche per YAML.

TL; DR è che penso che sia più arte che scienza ... per il tuo caso d'uso, con le informazioni che hai fornito ... Mi limiterei a YAML.

    
risposta data 27.01.2016 - 23:39
fonte

Leggi altre domande sui tag