Sto cercando di imparare a ridurre l'analisi. Supponiamo di avere la seguente grammatica, utilizzando le regole ricorsive che ordine delle operazioni fanno rispettare, ispirate al ANSI C Yacc grammar:Shift-reduce: quando smettere di ridurre?
S: A;
P
: NUMBER
| '(' S ')'
;
M
: P
| M '*' P
| M '/' P
;
A
: M
| A '+' M
| A '-' M
;
e vogliamo analizzare 1 + 2 usando shift-ridurre l'analisi. Innanzitutto, il 1 viene spostato come NUMERO. La mia domanda è, è ridotta a P, quindi a M, quindi A, infine a S? Come sa dove fermarsi?
Supponiamo che riduca fino a S, quindi cambia "+". ora avremmo una pila contenente:
S '+'
Se Shift '2', potrebbero essere le riduzioni:
S '+' NUMBER
S '+' P
S '+' M
S '+' A
S '+' S
Ora, su entrambi i lati l'ultima riga, S potrebbe essere P, M, A o NUMBER, e sarebbe comunque valido nel senso che qualsiasi combinazione sarebbe una rappresentazione corretta del testo. Come funziona il parser "conoscere" per renderlo
A '+' M
Così che può ridurre l'intera espressione ad A, allora S? In altre parole, come fa a smettere di ridurre prima di spostare il prossimo token? È questa una difficoltà chiave nella generazione del parser LR?
Edit: Un'aggiunta alla domanda segue.
Supponiamo ora di analizzare 1+2*3
. Alcune operazioni di spostamento/riduzione sono le seguenti:
Stack | Input | Operation
---------+-------+----------------------------------------------
| 1+2*3 |
NUMBER | +2*3 | Shift
A | +2*3 | Reduce (looking ahead, we know to stop at A)
A+ | 2*3 | Shift
A+NUMBER | *3 | Shift (looking ahead, we know to stop at M)
A+M | *3 | Reduce (looking ahead, we know to stop at M)
È corretto (concesso, non è ancora completamente analizzato)? Inoltre, guarda avanti di 1 simbolo ci dice anche di non ridurre A+M
a A
, in quanto ciò provocherebbe un inevitabile errore di sintassi dopo aver letto *3
?
non '1 + 2' produce uno spostamento/riduzione del conflitto per il grammer che hai fornito? – mcabral
No. Bison lo accetta senza lamentarsi (dopo averlo completato con% token NUMBER \ n %% \ n ... \ n %%, ovviamente). –