Trattamento degli errori

Transcript

Trattamento degli errori
Trattamento degli errori
Trattamento degli errori
„ Un parser deve essere in grado di scoprire,
diagnosticare e correggere gli errori in maniera
efficiente, per riprendere l’analisi e scoprire nuovi
errori.
„ I parser LL e LR hanno la proprietà “viable prefix”:
sono in grado di rilevare un errore non appena si
presenta perché sono in grado di riconoscere i
prefissi validi del linguaggio
„ Scoperta degli errori
„ Diagnosi dell’errore
„ Recupero e ripresa
1
Strategie di riparazione
„ panic mode”:scoperto l’errore il parser
riprende l’analisi in corrispondenza di alcuni
token selezionati (es.: delimitatori begin end)
scartando alcuni caratteri. Svantaggi: può
essere scartato molto input
„ “phrase level” correzioni locali ottenute
inserendo/modificando/ cancellando alcuni
terminali per poter riprendere l’analisi (es.:
‘,’scambio’;’) Svantaggi:possibili loop,
difficoltà quando la distanza dall’errore è
notevole
Strategie di riparazione
„ “error productions” Uso di produzioni che
estendono la grammatica per generare gli
errori più comuni. Metodo efficiente per la
diagnostica.
„ global correction” Si cerca di “calcolare” la
migliore correzione possibile alla derivazione
errata (minimo costo di interventi
perinserzioni/cancellazioni/). Metodo globale
poco usato in pratica, ma tecnica usata per
ottimizzare strategia “phrase level”
2
„ Trattamento degli errori
„ Analisi
ascendente
Riparazione locale
„ Produzione di errori
„
„ Analisi
discendente
Albero connesso
„ Predecessori e successori
„ Sincrotriple
„
Attenzione
„ L’analizzatore sintattico può accorgersi dell’errore
con grande ritardo della presenza di un errore. Infatti
l’errore può produrre un sintomo solo quando il
prefisso analizzato con è piu completabile in modo
da derivare una frase del linguaggio
„ Esempio
„ L = ab*aa ∪ cb*cc
„ Data la frase abncc
„
„
Primo errore scoperto dopo abn
Correzione a distanza minima
3
Gestione degli errori in parser
predittivi
„ Un errore può verificarsi in un parser predittivo (LL(1))
Se il simbolo terminale in cima alla pila non corrisponde
con il simbolo di ingresso
„ Se il simbolo in cima alla pila e un simbolo non terminale
A, e il simbolo di ingresso e a, e M[A,a] è vuoto.
„ Cosa deve fare il parser quando si verifica un errore?
„ Il parser dovrebbe essere capace di fornire un messaggio
di errore (più veritiero possibile).
„ Dovrebbe recuperare l’errore e dovrebbe essere capace
di continuare il parsing della stringa d’ingresso
„
Metodo dell’albero connesso
„ È del tipo (p, T-, i, T-)
„ Scoperto un errore
„ cerca una ripresa ipotizzando la
mancanza di una sottostringa nella pila.
„ se fallisce tenta una correzione saltando
uno o più caratteri fino a quando l’analisi
può riprendere.
„ È equivalente a (i, T+, i, T-)
4
void errore {
do {
do {
if (la configurazione è valida)
{ stampa dignostico
rerurn}
scarta il simbolo in cima alla pila
} while (pila non è vuota)
ripristina la pila
avanza la testina di lettura
} while la stringa è terminata
}
Metodo delle sincrotriple
Definire per ogni non terminale la sincrotripla
(marca di apertura, non terminale, marca
di chiusura)
Scartare tutti i caratteri fino a quando si
trova una simbolo specificatamente un
simbolo finale di una stringa darivabile da
A
2. Se c’è specificatamente il caratteri iniziale
di una stringa
1.
5
Scelta delle sincrotriple
„ Marca di apertura
„ First
(A)
„ Marca di chiusura
„ Follow(A)
„ Sincrotriple degeneri
Scelta dei token di sincronizzazione
„ Tecniche “panic mode” per la scelta dei token di sincronizzazione:
„
„
„
„
„
Per i non terminali A: FOLLOW(A) - si scartano tutti i terminali fino
a trovarne uno in FOLLOW(A), quindi si fa pop(A)
E’ possibile considerare altri simboli, che terminano il costrutto
corrente (es.: ‘;’ dopo assegnamento). Altri esempi: per le
espressioni le keyword delle istruzioni (if <expr> then …), per le
istruzioni i blocchi, ecc.
Durante la ricerca dei token di sincronizzazione, l’analisi può
riprendere in corrispondenza di un simbolo in FIRST(A) con l’analisi
di A, e dopo continuare la scansione
Se un non terminale A deriva e, la produzione può essere usata
come default per ridurre i terminal da analizzare in caso di errore
se un terminale in cima allo stack non corrisponde a quello letto
può essere scartato e prodotto un messaggio “simbolo non atteso
…”
6
Errori nell’analisi discendente
„ La tavola di parsing può essere completata
con i token di sincronizzazione M[A,a]=sync
se FOLLOW(A)=a.
„ Se M[A,a]=‘ ‘skip a; errore
„ se M[A,a]=sync pop(A) - ripresa da errore
„ se il terminale a in cima allo stack non
corrisponde a quello letto, skip a - errore
„ Tecnica Phrase level: le caselle vuote della
tavola di parsing vengono riempite con
procedure di ricovero
Riparazione locale
1. Strategia (p, T-)
Sfogliare la pila fino ad incontrare uno stato
da cui si esce con un non terminale A
andando allo stato j. Si esegue tale
transizione putche da j sia definita una
mossa sotto b. Altrimenti si continua a
sfogliare la pila
2. Strategia (p, T+)
a Prova ad inserire prima di b un carattere
terminale a scekta La correzione è accettata
se la j puo proseguire
a
7
Analisi LR -Trattamento degli errori panic mode
„ Tecnica “panic mode” isolare la frase che contiene l’errore e
riprendere l’analisi non appena possibile.
„ Quando scopre un errore l’automa percorre lo stack verso il basso
fino e un non terminale sullo stack per cui goto[A,a]=s; pone s sullo
stack e continua l’analisi.
„ Se si scorre tutta la pila, si passa al prossimo carattere di input, e
così via
„ La scelta dei simboli può essere fatta in modo da isolare il tipo di
frase (es.: ‘;’ per le espressioni)
Analisi LR -Trattamento degli errori phrase level
„ Tecnica “phrase level” cercare di ripristinare l’analisi
apportando correzioni “locali” alla frase errata.
„ Quando scopre un errore su un carattere a l’automa
cerca di inserire un carattere b per cui è definita la
“goto”: la riparazione è accettata se l’analisi può
riprendere da b, altrimenti si ripristina la pila iniziale.
„ La tabella di parse “action[A,a]” può contenere
esplicitamente il riferimento ad una funzione di
gestione errore adatta al contesto, negli spazi che
non sono ne spostamento ne di riduzione.
8
Esempio error recovery- SLR(1)
1. E’ → E
2. E → E+T
3. E → T
4. T → T*F
5. T → F
6. F → (E)
7. F → id
E1) messaggio
“missing
operand” ; azione
inserimento id
fittizio
Produzione di errore
„ Inserimento di produzioni fittizie
A → errore α
„ Il simbolo errore viene inserito nella stringa
quando viene riscontrata una situazione di
errore. L’analizzatore in tale situazione scarta
dallla pila tutti gli stati finchè incontra
A → • errore α
9