Trasformazione grammaticale delle espressioni aritmetiche


9

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:

  1. 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
  2. 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.

  3. Riscrivo quelle prime due produzioni partendo dalla produzione non ricorsiva a L (che è semplicemente Pl'espressione primaria) e seguendola dalla coda opzionale T, che definisco come il resto della produzione originale meno il primo nonterminale ricorsivo a sinistra (cioè solo B E) seguito dalla coda T, o che potrebbe essere vuoto:

    E --> P T
    T --> B E T |

    (nota l'alternativa vuota per la coda).

  4. Queste due produzioni ora posso riscrivere in EBNF in questo modo:

    E --> P {B E}

    che è quasi ciò che l'autore ottiene, ma ho Einvece Plì 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 Einvece Pnella prima produzione per P.

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 Pper E, ma io non conosco nessun trasformazione giuridica per giustificarla. Forse sai qual è l'ultimo passaggio mancante?


Si consiglia di utilizzare LaTeX per la formattazione. Vedi qui per un primer . (Vedi qui per una discussione sull'idoneità di LaTeX in questo caso.)
Raffaello

Risposte:


8

Il passo mancante:

E --> P T
T --> B E T |

riscrivi E in T:

E --> P T
T --> B P T T | 

Semplifica T:

E --> P T
T --> B P T | 

Equivalente a:

E --> P T
T --> {B P}

Ed eccoti qui.


1
Grazie per una buona risposta :-) Ora vedo cosa mi sono perso: l'ho sostituito al contrario e questo era il problema. Ma ancora non capisco un piccolo pezzo: come fai a sapere che puoi unire tranquillamente le Ts in una T? C'è qualche regola per quello? (Sospetto che potrebbe essere in qualche modo simile alla regola nella logica algebrica booleana che dice "aa = a".)
SasQ

A proposito, perché questo post è stato spostato qui da cstheory.sx e qual è la differenza? Mi piacerebbe sapere per evitare errori in futuro.
SasQ,

2
@SasQ CSTheory è solo per domande a livello di ricerca nell'informatica teorica, vedere la FAQ di CSTheory per i dettagli.
Juho,

1
TxTTεxTxTεLL=LLεL+L+L+

@Raphael: Ha qualcosa a che fare con la regola dell'idempotenza *? Ho visto in "Dragon Book" (3.3, p.91) che x** = x*. È la stessa regola che hai usato?
SasQ
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.