Qual è il tipo più potente di parser?


28

Come progetto collaterale, sto scrivendo una lingua usando Python. Ho iniziato usando un clone flex / bison chiamato Ply, ma sto arrivando contro i bordi nel potere di ciò che posso esprimere con quello stile di grammatica, e non mi interessa hackerare il mio linguaggio a causa di un'impedenza non corrispondente a lo strumento. Pertanto, non sono contrario a scrivere il mio.

Quindi qual è il tipo più potente di parser? Citazioni su articoli (così come altri articoli introduttivi) sarebbero i benvenuti.

(So ​​che "potente" non è definito con precisione, ma andiamo un po 'in disparte e vediamo dove vanno le risposte)


1
Downvoted: non livello di ricerca.
Warren Schudy,

3
@Warren: ho controllato le FAQ prima di chiedere - che non sembra essere un requisito.
Paul Biggar,

1
ci sono in realtà due FAQ, una per il sito generale e una per CStheory. Quello di CStheory indica che le domande alle quali si può rispondere ad esempio leggendo Wikipedia sono fuori tema; vedi "Che tipo di domande sono troppo basilari?" in meta.cstheory.stackexchange.com/questions/225/… .
Warren Schudy,

1
@Warren: questa è la FAQ che ho letto. Avevo letto Wikipedia, ma sentivo che questo aveva bisogno di una vera comprensione.
Paul Biggar,

1
Vuoi dire parser in produzione o teorici, cioè quelli che coprono tipi di grammatica diversi dal CFG?
Raffaello,

Risposte:


33

Una grammatica viene generalmente definita come grammatica senza contesto : una definizione precisa viene fornita nella pagina di Wikipedia, ma funziona come in PLY, che si basa su Bison , che a sua volta si basa su yacc .

Qui dice che PLY usa un parser LALR . Questo è essenzialmente un parser LR in cui le tabelle di ricerca sono condensate, introducendo possibilmente conflitti di analisi, riducendo parte dell'espressività di una grammatica LR (ovvero una grammatica libera dal contesto che un parser LR può analizzare). Se vuoi sapere sulle limitazioni di questa particolare branca della parser e quelle di altri parser, una panoramica di tutti i tipi di tecniche di parsing (LL, LR e altri) è dato qui .

Per rispondere alla tua domanda: esistono algoritmi di analisi in grado di analizzare qualsiasi linguaggio privo di contesto, anche se il linguaggio è ambiguo (ovvero, esiste più di un modo per interpretare l'input):

Il primo algoritmo di questo tipo era l' algoritmo CYK , che purtroppo ha un tempo di esecuzione di , dove n è la lunghezza della stringa di input e | G | è la dimensione della grammatica ed è quindi poco pratico per l'analisi delle lingue.O(n3|G|)n|G|

Il secondo algoritmo è l' algoritmo Earley . Questo algoritmo è anche in grado di analizzare qualsiasi grammatica libera dal contesto. Sebbene l'algoritmo abbia bisogno di tempo per analizzare un linguaggio ambiguo, richiede solo tempo O ( n 2 ) per analizzare un linguaggio non ambiguo. Inoltre, sembra funzionare in tempo lineare per la maggior parte delle grammatiche LR e funziona particolarmente bene su grammatiche ricorsive a sinistra.O(n3)O(n2)

Qui puoi trovare un documento che discute un'implementazione pratica dell'algoritmo Earley (un adattamento). Concludono: "Data la generalità dell'analisi di Earley rispetto all'analisi LALR (1) ((che è approssimativamente ciò che fa PLY)), e considerando che anche il peggio dei PEP ((la loro implementazione dell'algoritmo di Earley)) non sarebbe evidente da un utente, questo è un risultato eccellente ".

L'ultimo tipo di parser è il parser GLR . Questa è una versione generalizzata dell'analisi LR, in grado di analizzare qualsiasi linguaggio privo di contesto.

Un'implementazione matura di GLR è ASF + SDF . Bison può anche generare un parser GLR, sebbene le sue implementazioni siano leggermente diverse dall'algoritmo GLR "standard". L' algoritmo Elkhound è un algoritmo ibrido GLR / LALR. Usa LALR quando possibile e GLR quando necessario, per essere veloce e capace di analizzare qualsiasi grammatica.

Oltre alle grammatiche libere dal contesto ci sono grammatiche sensibili al contesto , ma queste sono generalmente difficili da analizzare e non aggiungono molta espressività: puoi fare di più con loro, ma per la maggior parte delle applicazioni gli usi extra non sono rilevanti, a meno che tu non stia analizzando un linguaggio naturale.

Come ultimo passo ci sono grammatiche senza restrizioni . A questo punto la grammatica è completa di Turing, quindi non c'è alcun limite che uno possa dedicare da quanto tempo ci vorrà per analizzare una determinata lingua, il che è indesiderabile per la maggior parte delle applicazioni di analisi. La potenza extra non è quasi mai necessaria. Se vuoi usare tutta quella potenza, c'è la macchina della lingua disponibile.

Infine, implementare il proprio generatore di parser non è una faccenda banale, in particolare per renderlo veloce. Personalmente ho appena finito di creare la mia versione di flex (il generatore di lexer), e mentre questo sembrava un esercizio in problemi algoritmici relativamente semplici, è diventato abbastanza complesso da ottenere, in particolare quando ho provato a supportare Unicode. Prendi in considerazione l'utilizzo di un'implementazione già esistente invece di scriverne una tua.


1
Ottima risposta !! Qualche idea su come si adattano i PEG?
Paul Biggar,

2
I PEG sono "diversi" rispetto ai CFG: ci sono CFG che non sono PEG e viceversa. Ti rimando qui: stackoverflow.com/questions/1857022/… .
Alex ten Brink,


1
In realtà, i generatori di parser più comuni (yacc, Antlr, bisonte) consentono concetti non CF mediante predicati o codice arbitrario che verifica se è possibile applicare una regola. decidere la precedenza. Questo può essere usato per implementare la semantica statica principalmente perché la sintassi di base rimane sostanzialmente libera dal contesto.
Raffaello,

1
Le lingue ricorsive sono precisamente le lingue decidibili fermando sempre le macchine di Turing. Qualsiasi linguaggio sensibile al contesto è quindi anche ricorsivo, ma poiché le lingue sensibili al contesto sono decidibili in tempi esponenziali, ci sono lingue ricorsive che non sono sensibili al contesto. Le grammatiche senza restrizioni sono ancora più potenti: il problema dell'arresto può essere descritto da una grammatica senza restrizioni, ma non è un linguaggio ricorsivo.
Alex ten Brink,

15

Un documento all'ICFP 2010 di quest'anno, Total Parser Combinators , descrive una libreria combinatrice di parser che si chiude in modo dimostrabile e stabilisce anche che in questa libreria "i combinatori di parser sono il più espressivi possibile" dato che il parser è garantito per terminare. Sfortunatamente non ricordo la spiegazione fornita dall'autore per ciò che significa "il più espressivo possibile", ma sembra certamente pertinente alla tua domanda sul "potere".


1
Ho un'auto che non inquina, in realtà non si muove neanche ... Quindi la domanda è: che tipo di linguaggio viene analizzato da questa biblioteca? Non significa che questo lavoro non sia interessante, ovviamente.
babou,

2

Se vuoi andare oltre le grammatiche senza contesto per l'analisi dei linguaggi di programmazione, ma ancora analizzandoli in tempi polinomiali, puoi ricorrere all'analisi delle grammatiche di espressione o grammatiche booleane : queste ultime sono disponibili anche in LL e LR (vedi qui ). Nella teoria del linguaggio formale, vengono studiati anche i linguaggi Church-Rosser potenti ma riconoscibili nel tempo lineare , ma non sono a conoscenza di generatori di parser implementati per questi.

Nell'elaborazione del linguaggio naturale, i gusti sono diversi, ad esempio, per quanto riguarda l'ambiguità (anche: l'ambiguità intrinseca) e l'ordine delle parole libero gioca un ruolo molto importante. Qui le parole chiave linguaggi leggermente sensibili al contesto e riavvio degli automi potrebbero aiutarti a iniziare a leggere.


1
Considerando il modo in cui è stata posta la domanda e il reclamo per il fatto che la CF sia troppo restrittiva, la tua risposta è chiaramente la migliore. Così va ...
babou,

0

Strumenti del generatore di parser:

ANTLR è molto buono. In alternativa, puoi dare un'occhiata a JavaCC


Non sono un esperto di informatica (nonostante ciò che dice la mia laurea;), quindi le mie parole potrebbero pesare leggermente qui. Sono d'accordo con Sazzad - ANTLR è uno strumento molto potente. È molto completo e non ho ancora trovato alcun problema con il generatore di parser (LL (k) se ricordo bene). D'altra parte, devo ancora implementare un compilatore per una grammatica alquanto complessa ...
Jörgen Sigvardsson,

5
Penso che ti manchi il punto della domanda, e forse l'intero sito. Si tratta di analizzare la teoria, non di implementazioni e strumenti.
Paul Biggar,
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.