Questa è una riformulazione dei programmi grammaticali Are? precedentemente chiesto da Vag e con molti suggerimenti dai commentatori.
In che modo una grammatica può essere vista come specifica di un modello di calcolo? Se, ad esempio, prendiamo una semplice grammatica senza contesto come
G ::= '1' -> '0' '+' '1'
'1' -> '1' '+' '0'
'2' -> '2' '+' '0'
'2' -> '1' '+' '1'
'2' -> '0' '+' '2'
'3' -> '3' '+' '0'
'3' -> '2' '+' '1'
'3' -> '1' '+' '2'
'3' -> '1' '+' '2'
Supponendo che il parser non distingua tra simboli terminali e non terminali, come ho dimostrato qui, è possibile eseguire una semplice aritmetica per numeri fino a 3.
Ad esempio, prendi la stringa
"2 + 0 + 1"
L'esecuzione di un parser LR (1) su questa stringa dovrebbe fornire il seguente albero di sintassi concreto in cui il risultato del calcolo è memorizzato nella radice dell'albero:
'3'
/ | \
/ | \
'2' '+' '1'
/ | \
/ | \
'2' '+' '0'
Quindi, se prendiamo una grammatica per essere un programma e un generatore di parser per essere un compilatore , potremmo vedere il linguaggio di specifica grammaticale come un linguaggio di programmazione ?
Inoltre, potremmo costruire programmi completi di Turing specificando grammatiche simili a come potresti costruire programmi completi di Turing con automi celullari o il calcolo lambda ?
In altre parole, è noto che, nel senso del riconoscimento di una lingua, le lingue regolari corrispondono agli automi a stati finiti , le lingue senza contesto corrispondono agli automi push down e le lingue sensibili al contesto corrispondono agli automi limitati lineari . Tuttavia, se consideriamo le grammatiche come dispositivi computazionali (cioè programmi nel senso dell'esempio sopra), allora come classifichiamo la forza computazionale di ogni classe di grammatiche nella gerarchia di Chomsky?
- Grammatiche regolari
- Grammatiche senza contesto
- Grammatiche sensibili al contesto
- Grammatiche senza restrizioni (per lingue ricorsivamente enumerabili )
Inoltre, che ne dici delle sottoclassi meno conosciute di grammatiche come
- Grammatiche deterministiche senza contesto (anche LR (k) / LL (k) / SLR / LALR ecc.)
- Grammatiche di parole nidificate
- Grammatiche adiacenti agli alberi
- Grammatiche indicizzate
EDIT: A proposito, questo è un pignolo sulla mia stessa domanda, ma non ho detto che non ho dato alcun simbolo di partenza per la grammatica di esempio e ho agitato a mano la necessità di distinguere tra terminali e non terminali. Tecnicamente o tradizionalmente penso che la grammatica dovrebbe probabilmente essere scritta in una forma più complicata come questa (dove S è il simbolo iniziale e $ rappresenta il terminale di fine flusso):
G ::= S -> R0 '$'
S -> R1 '$'
S -> R2 '$'
R0 -> '0'
R0 -> R0 '+' '0'
R1 -> '1'
R1 -> R0 '+' '1'
R1 -> '1' '+' R0
R1 -> R0 '+' '1' '+' R0
R2 -> '2'
R2 -> R0 '+' '2'
R2 -> '2' '+' R0
R2 -> R0 '+' '2' '+' R0
R2 -> R1 '+' '1'
R2 -> R1 '+' '1' '+' R0
... non che cambi davvero nulla, ma pensavo di doverlo menzionare.
EDIT: Qualcos'altro che mi è venuto in mente quando ho letto la risposta di Gasche è che ogni ramo dell'albero nel mio esempio rappresenta un sottocalcolo. Se guardi ogni regola di produzione come una funzione in cui LHS rappresenta il risultato e RHS rappresenta i suoi argomenti, la struttura della grammatica determina come sono composte le funzioni.
In altre parole, il contesto del parser insieme al suo meccanismo lookahead aiuta a determinare non solo quali funzioni applicare ("kinda" come il polimorfismo parametrico) ma come dovrebbero essere composte insieme per formare nuove funzioni.
Almeno, immagino che potresti guardarlo in questo modo per CFG inequivocabili, per altre grammatiche la ginnastica mentale è un po 'troppo per me in questo momento.