Nell'articolo Parsing Expressions di Recursive Descent di Theodore Norvell (1999) l'autore inizia con la seguente grammatica per le espressioni aritmetiche:
E --> E "+" E | E "-" E | "-" E | E "*" E | E "/" E | E "^" E | "(" E ")" | v
che è abbastanza male, perché è ambiguo e ricorsivo a sinistra. Quindi inizia a rimuovere la ricorsione sinistra da essa, e il suo risultato è come tale:
E --> P {B P}
P --> v | "(" E ")" | U P
B --> "+" | "-" | "*" | "/" | "^"
U --> "-"
Ma non riesco a capire come sia arrivato a questo risultato. Quando provo a rimuovere personalmente la ricorsione sinistra, la sto facendo nel modo seguente:
In primo luogo, raggruppo le produzioni che non hanno lasciato la ricorsione in un gruppo e l'altra (sinistra ricorsiva) in un altro gruppo:
E --> E "+" E | E "-" E | E "*" E | E "/" E | E "^" E // L-recursive E --> v | "(" E ")" | "-" E
Successivamente, li chiamo e fattore per manipolazioni più facili:
E --> E B E // L-recursive; B stands for "Binary operator" E --> P // not L-recursive; P stands for "Primary Expression" P --> v | "(" E ")" | U E // U stands for "Unary operator" B --> "+" | "-" | "*" | "/" | "^" P --> "-"
Ora devo occuparmi solo delle prime due produzioni, che ora sono più facili da gestire.
Riscrivo quelle prime due produzioni partendo dalla produzione non ricorsiva a L (che è semplicemente
P
l'espressione primaria) e seguendola dalla coda opzionaleT
, che definisco come il resto della produzione originale meno il primo nonterminale ricorsivo a sinistra (cioè soloB E
) seguito dalla codaT
, o che potrebbe essere vuoto:E --> P T T --> B E T |
(nota l'alternativa vuota per la coda).
Queste due produzioni ora posso riscrivere in EBNF in questo modo:
E --> P {B E}
che è quasi ciò che l'autore ottiene, ma ho
E
inveceP
lì all'interno del modello di ripetizione zero-o-più (la coda). Le altre produzioni che ottengo sono le stesse di lui:P --> v | "(" E ")" | U E B -> "+" | "-" | "*" | "/" | "^" U -> "-"
ma anche qui ho
E
inveceP
nella prima produzione perP
.
Quindi, la mia domanda è: cosa mi sto perdendo? Quale trasformazione algebrica sulla sintassi devo procedere ora per ottenere la stessa forma esatta dell'autore? Ho provato a sostituire E
, ma mi porta solo in loop. Ho il sospetto che ho bisogno in qualche modo di sostituire P
per E
, ma io non conosco nessun trasformazione giuridica per giustificarla. Forse sai qual è l'ultimo passaggio mancante?