LR Parser
II Parte
Giuseppe Morelli
Parser LR(1)
• Con il metodo SLR la tabella indica di effettuare
una riduzione attraverso una produzione A-> α,
se accade che per un certo item Ii :
– [A->α. Є Ii]
– Per ogni a Є FOLLOW(A)
• In certi casi può succedere che se βα è il
contenuto dello stack, βAα non può essere
prefisso di una forma sentenziale destra e pur
essendo a Є FOLLOW(A) la riduzione A-> α non
si può applicare
In I2 esiste un
conflitto ShiftReduce
Ovvero non esiste
una forma
sentenziale
destra che
inizia per R
• E’ possibile mantenere informazioni riguardanti i
caratteri che possono essere presenti dopo una
variabile in un dato contesto.
• Data una produzione A->α, l’idea è di includere
negli items di uno stato i simboli terminali che
possono seguire un handle α per cui è possibile
una riduzione ad A.
• La forma generale di un item, LR(1) diventa
[A->α.β,a ]
• Il significato di “a” in [A->α.,a ] è: viene
applicata la riduzione A-> α solo se il simbolo di
lookahead è a.
Insieme di item LR(1)
• Il metodo è essenzialmente lo stesso usato per
la costruzione della collezione canonica LR(0)
• Ovvero:
• Si costruisce la grammatica aumentata G’
• Si definiscono e applicano le operazioni di
– CHIUSURA
– GOTO
• La discriminante è proprio la definizione delle
due procedure.
Es.
Costruzione della tabella LR(1)
• Data G si costruisce la grammatica aumentata
G’ quindi:
– Si costruisce la collezione di insiemi di Items LR(1) C’
= {I0, I1, …. ,In} per G’
– Lo stato i è costruito da Ii. L’azione per lo stato i è
determinata come segue:
• Se [A-> α.aβ,b] è in Ii e GOTO(Ii,a) = Ij allora
ACTION[i,a] = “shift j” . a deve essere un terminale
• Se [A-> α., a] è in Ii (A<>S’ ) allora ACTION[i,a] = “reduce
A-> α.”
• Se [S’ -> S.,$] è in Ii allora ACTION[i, $] = “accept”
– GOTO deve essere costruita per tutti i non terminali
Secondo la regola se GOTO(Ii,A)=Ij allora GOTO(i,A)
=j
– Errore se vi sono entry non definite da 2 e 3
– Lo stato iniziale è quello ottenuto dall’insieme di Item
contenente [S’->.S, $]
Parser LALR
• È caratterizzato dal fatto che la tabella di
parsing ottenuta per una data grammatica è
considerabilmente più piccola della
corrispondente LR.
• L’idea di base di questo metodo è quella di
costruire la tabella di parsing a partire dagli
insieme di items LR(1) ed apportando delle
semplificazioni.
• L’algoritmo si costruzione si rifà ad alcune
definizioni e strategie già viste (kernel items,
closure etc..)
• In generale la tecnica prevede di fare il merge
in un unico insieme gli insiemi di item LR(1) che
hanno lo stesso core(primo item dell’insieme).
• L’unione si ripercuote anche sugli insiemi
GOTO(I,X) degli item I coinvolti nella “fusione”;
poiché GOTO(I,X) dipende dal core di I si può
fare il merge anche delle funzioni GOTO degli
stati merged.
• Poiché in una grammatica LR(1) non sono
presenti errori di parsing si può dimostrare che
anche nell’insieme di stati ottenuti attraverso
fusione non sono presenti errori
Tabella di parsing LALR
• Data G si costruisce la grammatica aumentata
G’ quindi:
– Si costruisce la collezione di insiemi di Items LR(1) C
= {I0, I1, …. ,In} per G’
– Trovare per ogni core di item in C, gli item con lo
stesso core e rimpiazzarli con la loro unione.
– Sia C’ = = {J0, J1, …. ,Jn} l’insieme di items
risultante. La funzione ACTIONE delle tabelle di
parsing dello stato i è costruita attraverso Ji come
fatto per la tabella LR(1).
– La funzione GOTO deve essere costruita
considerando che se J = I1 U I2 U … U Im allora i
cores di di GOTO(Ii,X) sono gli stessi dei
corrispondenti Ii (i=1...m); sia K l’unione di
GOTO(Ii,X) aventi lo stesso core allora GOTO(J,X)=K
QuickTime™ and a
decompressor
are needed to see this picture.
• La tabella derivante dall’algoritmo prima visto è
chiamata LALR parsing table e se non esistono
confilitti nella fase di parsing la grammatica
restitutia è detta LALR
• L’insieme di Item derivanti dalla fusione e dalla
nuova definzione della funzione GOTO è detto
LALR.
• La costruzione della tabella di parsing LALR
implica la costruzione dell’intera collezione
LR(1) che può richiedere troppo spazio e tempo
per essere utilizzata nella pratica.
• Servono degli espedienti per migliorare allora il
processo di costruzione
Costruzione efficiente
• Anziché considerare tutti gli insieme di Item si
considerano quelli kernel ([S’->.S,$] e con il .
non all’inizio del corpo della produzione); si
potrebbero considerare anche gli item LR(0)
senza cioè il carattere di lookahead.
• Si costruiscono gli item LALR(1) kernel
attraverso un processo di propagazione e
generazione spontanea di caratteri di lookahead
(see later)
• Da LALR(1) kernel si genera la tabella di parsing
applicando l’operazione di chiusura (CLOUSURE)
e applicando l’algoritmo adottato per la
costruzione della tabella LR(1) (def. ACTION e
GOTO)
Determinazione dei caratteri lookahead
Scarica

parser lr1 lalr