Parser top-down. Top-Down Parsing

Documenti analoghi
Analisi sintattica. Analisi sintattica. albero. sintattico. parser. scanner. Errori sintattici

Analisi sintattica. Syntax Analysis. albero. sintattico. parser. scanner. Errori sintattici

albero sintattico parser scanner Errori sintattici

Automi e Linguaggi Formali

Analisi sintattica. Analisi sintattica

Analisi sintattica (parser)

Linguaggi formali e compilazione

ANALISI SINTATTICA LUCIDI DI F. D'AMORE E A. MARCHETTI SPACCAMELA

ANALISI SINTATTICA LUCIDI DI F. D'AMORE E A. MARCHETTI SPACCAMELA

Linguaggi e Traduttori: Analisi sintattica

ANALISI SINTATTICA AUTOMI PUSHDOWN. v x y. input u t w. tabella controllo. pila LUCIDI DI F. D'AMORE E A. MARCHETTI SPACCAMELA.

Linguaggi context free. Analizzatori sintattici e alberi di analisi

Applicazioni alla traduzione e compilazione

Analisi Sintattica. Maria Rita Di Berardini. Universitá di Camerino Ruolo del parser

Linguaggi e Traduttori: Analisi sintattica

Esempio. Grammatica E! T E!! T! *F T " F! (E) i. procedure E. ! if cc in FIRST (TE )! then T; E!!! else ERRORE (1); E! T E

Dispensa 1. Da un punto di vista logico l architettura di un compilatore si può suddividere in due parti: Analisi e Sintesi.

Schema generale parser LR

Contenuti del corso. Parsing: esempio. Cosa aggiungiamo in questo corso. Parsing. Data una grammatica: E T T + E

Automa deterministico con prospezione 1. < {q}, Σ, Σ V, δ, q, S, Φ > δ(a, X) = α R. se a Gui(X α) senza spostamento della testina.

Grammatiche context-free

Precisiamo il problema di SLR. Tabelle LR. Soluzione. Esempio. Item LR(1) Item LR(1) validi. Costruzione delle tabelle di parsing LR canoniche

Linguaggi e Traduttori: Analisi sintattica

Bottom-up Parsing. Viable Prefixes, conflitti e formato delle tabelle per il parsing LR

Parser bottom-up. Esempio. V = {S, A, B, C} T = {a, b, d, e} P = { S aa R1 A BaA R2 A e R3 B ac R4 B AdC R5

Gestione degli errori

1. Calcolare FIRST e FOLLOW dei simboli non terminali della seguente grammatica:

Linguaggi di Programmazione Corso C. Parte n.9 Analisi Sintattica. Nicola Fanizzi

20/11/2013 PARSER BOTTOM-UP EXAMPLE. V = {S, A, B, C} T = {a, b, d, e} P = { S aa. What means built the syntatic tree in a bottom-up fashion?

Costruzione dell insieme dei Follow

PROLOG E ANALISI SINTATTICA DEI LINGUAGGI PROLOG E ANALISI SINTATTICA DEI LINGUAGGI PROLOG E ANALISI SINTATTICA DEI LINGUAGGI ESEMPIO

Traduttore diretto dalla sintassi (seconda parte) Giuseppe Morelli

Parsing. Parsing: example. Parsing. What we add in these lectures. From a grammar: E T T + E

Linguaggi formali e compilazione

Pumping lemma per i linguaggi Context-free

Analisi sintattica. Scopi Tecniche Strumenti ANTLR-Yacc. L3 - Introduzione ai compilatori - UNINA

Linguaggi di Programmazione e Compilatori

PROLOG E ANALISI SINTATTICA DEI LINGUAGGI Quando si vuole definire in modo preciso la sintassi di un linguaggio si ricorre a una grammatica G=(V n,v t

Grammatiche libere da contesto. Grammatiche libere da contesto

1. Calcolare FIRST e FOLLOW dei simboli non terminali della seguente grammatica:

Dispensa 2. Data una grammatica context free esistono tre metodi diversi per costruirne la parsing table per un parser LR:

Analizzatori sintattici a discesa ricorsiva

Tabelle LALR. Costruzione delle tabelle di parsing LALR. Maria Rita Di Berardini

POLITECNICO DI TORINO. Laboratorio di Compilatori Corso di Linguaggi e Traduttori. Esercitazione 2. a.a 2010 / 2011

Riconoscitori e analizzatori sintattici. Scanning e parsing. Funzionamento di un parser: la tecnica Shift/Reduce. Esempio

Corso di Linguaggi di Programmazione

Esercizio 1. Codificare il parser a discesa ricorsiva del linguaggio definito dalla seguente EBNF:

Tabelle SLR. Costruzione di tabelle di Parsing SLR

Tabelle SLR. Metodo simple LR. Potenza del metodo. Item LR(0) Idea Centrale del metodo SLR. Item LR(0) Costruzione di tabelle di Parsing SLR

Linguaggio Formale 2

Yet Another Compiler-Compiler. Generazione automatica di analizzatori sintattici

Grammatiche libere da contesto. Grammatiche libere da contesto

Elementi lessicali. Lezione 4. La parole chiave. Elementi lessicali. Elementi lessicali e espressioni logiche. Linguaggi di Programmazione I

Linguaggi e Traduttori: Analisi lessicale

come segue: data una collezione C di elementi e una un elemento che verifica la proprietà P

Parser Bottom UP. Giuseppe Morelli

Verificare se una grammatica e LL(1) e costruirne la tabella di parsing. Verificare se una grammatica e LR(0) e costruirne la tabele ACTION e GOTO

Analisi Sintattica Top-down

Corso di Linguaggi di Programmazione

Corso di Linguaggi di Programmazione

Esercitazioni di Linguaggi e Traduttori

Programmazione II. Lezione 3. Daniele Sgandurra 26/10/2010.

Proprietà dei linguaggi non contestuali

Progetto Laboratorio Programmazione Parte 2: Analizzatore sintattico di espressioni

Linguaggi di Programmazione Corso C. Parte n.2 Introduzione ai Linguaggi Formali. Nicola Fanizzi

Backus Naur Form. Paolo Bison. Fondamenti di Informatica 1 A.A. 2004/05 Università di Padova. BNF, Paolo Bison, A.A ,

Compilatori. Compilers. You can t live with them.. You can t live without them Sounds familiar?

Espressività e limitazioni delle grammatiche regolari

7. Automi a Pila e Grammatiche Libere

Linguaggi Liberi dal Contesto. Linguaggi Liberi dal Contesto

Analizzatore lessicale

acuradi Luca Cabibbo e Walter Didimo Esercizi di Informatica teorica - Luca Cabibbo e Walter Didimo 1

Grammatiche. Rosario Culmone, Luca Tesei. 20/11/2006 UNICAM - p. 1/49

Linguaggi Liberi dal Contesto. Linguaggi Liberi dal Contesto

Fondamenti d Informatica: Grammatiche. Barbara Re, Phd

Grammatiche libere da contesto. Grammatiche libere da contesto

Grammatiche e Linguaggi Liberi da Contesto

Definizioni syntax-directed

Non determinismo e grammatiche. Achille Frigeri Dipartimento di Matematica Francesco Brioschi Politecnico di Milano

Parte n.7 Automi a Pila e Grammatiche Libere

Proprieta dei linguaggi liberi da contesto. Proprieta dei linguaggi liberi da contesto

Definire tramite una grammatica ad attributi il

Grammatiche Parse trees Lezione del 17/10/2012

Linguaggi e Ambienti di Programmazione

Analizzatore lessicale o scanner. Lo scanner rappresenta un'interfaccia fra il programma sorgente e l'analizzatore sintattico o parser.

Verifica se un Linguaggio Regolare è vuoto

Lezioni del corso di Progetto di Linguaggi e Traduttori

Automi e Linguaggi Formali Automi a stack (Pushdown automata)

POLITECNICO DI TORINO. Laboratorio di Compilatori Corso di Linguaggi e Traduttori. Esercitazione 3. a.a 2010 / Uso avanzato di Cup

In questa lezione Strutture dati elementari: Pila Coda Loro uso nella costruzione di algoritmi.

Linguaggi di Programmazione

Dispensa 3. Se in uno stato c è l LR(0) item A α. (ossia un item col punto alla fine) è invocata una riduzione per ogni terminale a in Follow(A)

LR Parser II Parte. Giuseppe Morelli

Sintassi. Linguaggi. 4: Sintassi. Claudio Sacerdoti Coen. Universitá di Bologna 24/02/2011. Claudio Sacerdoti Coen

GRAMMATICHE DEI LINGUAGGI DI PROGRAMMAZIONE. Cosimo Laneve

Quiz sui linguaggi CF

Informatica e Laboratorio di Programmazione Automi Alberto Ferrari. Alberto Ferrari Informatica e Laboratorio di Programmazione

Alberi e alberi binari I Un albero è un caso particolare di grafo

Transcript:

Parser top-down Top-Down Parsing Il parse tree è creato dalla radice alle foglie. Il parser puo essere realizzato Recursive-Descent Parsing Il Backtracking è necessario (se una scelta di una regola non risulta quella corretta) È una tecnica di parsing generale ma di norma non viene utilizzata. Non è efficente Predictive Parsing no backtracking Efficente Recursive Predictive Parsing è una forma speciale di parser discendente ricorsivo senza backtracking. Sono necessarie forma particolari di grammatiche 1

Una grammatica left-recursive può portare a un loop infinito un parser discendente ricorsivo (anche con backtracking) Per poter applicare parsing predittivo (senza backtracking) in molti casi basta scrivere una grammatica con attenzione, eliminarne la leftrecursion e applicare il left-factoring Recursive-Descent Parsing (uso del backtracking) È necessario il Backtracking. Cerca di trovare una left-most derivation. S abc S S B bc b a B c a B c input: abc b c Fallisce e esegue un backtrack b 2

Predictive Parser (esempio) istr if... while... begin... for... Quando troviamo il non-terminale istr se il token è uguale ad if scegliamo la prima regola se il token è uguale ad while scegliamo la seconda regola etc Grammatiche LL(1) Un grammatica si dice LL(1) se Scorre la frase da sinistra (Left) a destra produce derivazioni Leftmost usa un solo simbolo di lookahead ad ogni passo del parsing Tutti i parser LL(1) operano in un tempo lineare utilizzando un spazio lineare. LL(k): LL(1) possono essere estese con l utilizzo di k simboli di look-ahead, in modo che attraverso l utilizzo di più simboli le grammatiche restino predittive.. 3

LL(1) Parser input buffer Stringa di cui effettuare l analisi sintattica. Assumeremo che essa termini con un simboli di fine stringa $. stack Contiene i simboli terminali del linguaggio Alla fine della pila c è il simbolo speciale di fine stringa $. Inizialmente lo stack coontiene il simbolo speciale $ e l assioma S. Quando lo stack è vuoto il parsing è completato. output Una produzione rappresenta un passo della sequenza di derivazioni (left-most derivation) della stringa in un input buffer parsing table È un array bidimenzionale M[A,a] Ogni riga contiene un simbolo non-terminalel Ogni colonna un simbolo terminale o $ Ogni entry contiene una produzione. Detti LL(1) Parser Parser Actions X Il simbolo in cima alla pila (nota che X {T V $ a il simbolo di ingresso Sono possibili quattro diverse azioni: 1. X = $ ansd a = $ parser termina (successful completion) 2. X = a a X $ pops() e a = nexttoken() 3. X V il parser esamina M[X,a]. 1. If M[X,a] contiene una produzione X Y 1 Y 2...Y k, 2. {pops(); 3. pushes Y k,y k-1,...,y 1 into the stack. 4. outputs la produzione X Y 1 Y 2...Y k per rappresentare un passo di derivazione. 4. non dei casi sopra error Tutte le caselle vuote della parser table corrispondono ad errori X T e X a, error 4

S aba LL(1) Parser Example1 B bb ε stack input output $S abba$ S aba $aba abba$ $ab bba$ B bb $abb bba$ $ab ba$ B bb $abb ba$ $ab a$ B ε $a a$ $ $ S a S aba b $ B B ε B bb LL(1) Parser Esempio1 Outputs: S aba B bb B bb B ε Derivation(left-most): S aba abba abbba abba S parse tree a B a b B b B ε 5

LL(1) Parser Example2 E TE E +TE ε T FT T *FT ε F (E) id id + * ( ) $ E E TE E TE E E +TE T T FT T FT T T ε T *FT E ε T ε E ε T ε F F id F (E) LL(1) Parser Example2 stack input output $E id+id$ E TE $E T id+id$ T FT $E T F id+id$ F id $ E T id id+id$ $ E T +id$ T ε $ E +id$ E +TE $ E T+ +id$ $ E T id$ T FT $ E T F id$ F id $ E T id id$ $ E T $ T ε $ E $ E ε $ $ accept 6

Costruzione della Parser Table LL(1) Abbiamo definito le funzioni FIRST FOLLOW FIRST(α) è l insieme dei simboli terminali che possono occupare la prima posizione nella stringa che si ottime dalla derivazione di α dove α è una stringa di simboli di T e V. Se α deriva ε, allora ε FIRST(α). FOLLOW(A) è l insieme dei simboli terminale che si trovano immediatamente dopo (follow) il non-terminale A nelle stringhe derivate dall assioma a FOLLOW(A) iff $ FOLLOW(A) iff S * αaaβ S * αa FIRST Example E TE E +TE ε T FT T *FT ε F (E) id FIRST(F) = {(,id FIRST(TE ) = {(,id FIRST(T ) = {*, ε FIRST(+TE ) = {+ FIRST(T) = {(,id FIRST(ε) = {ε FIRST(E ) = {+, ε FIRST(FT ) = {(,id FIRST(E) = {(,id FIRST(*FT ) = {* FIRST(ε) = {ε FIRST((E)) = {( FIRST(id) = {id 7

FOLLOW Example E TE E +TE ε T FT T *FT ε F (E) id FOLLOW(E) = { $, ) FOLLOW(E ) = { $, ) FOLLOW(T) = { +, ), $ FOLLOW(T ) = { +, ), $ FOLLOW(F) = {+, *, ), $ Algoritmo per la costruzione della Parser Table LL(1) A α della grammatica G a FIRST(α) aggiungere A α in M[A,a] If ε FIRST(α) a FOLLOW(A) aggiungere A α in M[A,a] If ε FIRST(α) e $ FOLLOW(A) Aggiungere A α in to M[A,$] 8

Definizione di Predict di una produzione E possibile definire un insieme detto insieme dei predict di una produzione come l insieme dei look-ahead tokens che indicano che una produzione deve essere applicata. Data una grammatica non contestuale G(V,T,P,S) si definisce Predict(P) il seguente insieme di terminali: Data una P: A α First(α) se non esiste α ε Predict(A α) = {First(α) Follow(A) se esiste α ε Esempio E TE FIRST(TE )={(,id E TE into M[E,(] and M[E,id] E +TE FIRST(+TE )={+ E +TE into M[E,+] E ε FIRST(ε)={ε none but since ε in FIRST(ε) and FOLLOW(E )={$,) E ε into M[E,$] and M[E,)] T FT FIRST(FT )={(,id T FT into M[T,(] and M[T,id] T *FT FIRST(*FT )={* T *FT into M[T,*] T ε FIRST(ε)={ε none but since ε in FIRST(ε) and FOLLOW(T )={$,),+ T ε into M[T,$], M[T,)] and M[T,+] F (E) FIRST((E) )={( F (E) into M[F,(] F id FIRST(id)={id F id into M[F,id] 9

T = {a, b, c V = {S, A, B P = { (1) S ABc Predict(1) = First(Abc) = {a, b,c (2) A a Predict(2) = First(a) = {a (3) A ε Predict(3) = Follow(A) = {b,c (4) B b Predict(4) = First(b) = {b (5) B ε Predict(5) = Follow(B) = {c S = S T = {a, b V = {S, A, B P = { 1. S Ab Predict(1) = First(Abc) = {a, b 2. A a Predict(2) = First(a) = {a 3. A B Predict(3) = First(B) = {b 4. A ε Predict(4) = Follow(A) = {b 5. B b Predict(5) = First(b) = {b 6. B ε Predict(6) = Follow(B) = {b S = S 10

Grammatiche LL(1) Una grammaticha che ha una parse table semza entry multiple è una grammatica LL(1). Condizione necessaria e sufficiente perché una grammatica sia LL e che l insieme dei predict delle produzioni che hanno la stessa parte sinistra sia disgiunto Ogni grammatica LL(1) è non ambigua Grammatiche non LL(1) Eliminazione ricorsioni sinistre Fattorizzazione 11

Grammatiche non LL(1) Una grammatica ricorsiva sinistra (left recursive) non pui essere LL(1) A Aα β x FIRST(β) anche x FIRST(Aα) poichè Aα βα. If β = ε, x FIRST(α) anche x FIRST(Aα) e x FOLLOW(A). Una grammatica non puo essere fattorizzata (not left factored) se A αβ 1 αβ 2 x FIRST(αβ 1 ) anche x FIRST(αβ 2 ). Una grammatica ambigua non può esssere LL(1). T = {a, b, c, d, e, V = {S, B, C P = {(1) S ase Predict (S ase) = First(aSe) = {a (2) S B Predict (S B) = First(B) = {b, c, d (3) B bbe Predict (B bbe) = First(bBe) = {b (4) B C Predict (B C) = First(C) = {c, d (5) C cce Predict (C cse) = First(cCe) = {c (6) C d Predict (C d) = First(d) = {d S = S 12

Esempio a + b * c Simboli Terminali: T = {a, b, c,..., z {+, -, *, $, (, ) Simboli Non-terminali: V = {E, T, F, P (E: espressione, T: termine, F: fattore, P: primary) Assioma: E Rules: E E + T T T T * F F F P $ F P P (E) -P a... z // left associative // left associative // right associative Nota che noi possiamo codificare le precedenze (P ha la massima precedenza, seguita da F, T e E) e le associatività nella grammatica. Esempio Predict (E E + T) = First(E + T) = First(T) = First(F)) = { (, -, a,. Predict (E T) = First(T)= First(F)) = { (, -, a,. Predict (T T * F) = First(T* F) = First(F)) = { (, -, a,. Predict (T F) = First(F) = { (, -, a,. Predict (F P $ F) = First(P $ F) = First(P) = { (, -, a,. Predict (F P) = First(P) = { (, -, a,. Predict (P (E) = First((E)) = {( Predict (P -P) =First(-P) = {- Predict (P a) = First(a) = {a 13

E E + T T // left associative T T * F F // left associative F P $ F P // right associative P (E) -P a... z E T E' E' + T E' ε T F T' T' * F T' ε F P $ F P P (E) - P a... z Parser LL(1) Discesa ricorsiva cablato sulla grammatica Parsetable codice indipendente dalla grammatica 14

L'implementazione di un parser TopDown a discesa ricorsiva è costituito da un insieme di procedure, una per ogni non terminale. Ogni procedura è responsabile dell'analisi di una sequenza di token derivabili dai non-terminali. Ad esempio, una procedura di analisi, A, quando invocata dovrebbe chiamare lo scanner e far corrispondere una sequenza di token derivabile da A. Partrndo dall assioma si dovrebbe far corrispondere l'intero input, che deve essere derivabile Questo approccio è chiamato a discesa ricorsiva perché le procedura di parsing sono in genere ricorsive Algoritmo per costruire una parsing table predittiva per una grammatica G 1. Per ogni produzione A α della grammatica, ripetere i passi 2 e 3 2. Per ogni terminale a in FIRST( α ) inserire nella tabella come elemento M[ A, a] la produz. A α 3. Se ε è in FIRST( α ) inserire nella tabella come elemento M[ A, b] la produz. A α per ogni terminale b che appartiene a FOLLOW( A) Se ε è in FIRST( α ) inserire nella tabella come elemento M[ A,$] la produz. A α se $ appartiene a FOLLOW( A) ogni entry viene contrassegnata con error 15

Recursive Predictive Parsing Ogni non-terminale corrisponde ad una produzione Esempio A abb proc A { 1. matching del token corrente con a 2. Leggi il token successivo 3. B; 4. Matching del token corrente con b Recursive Predictive Parsing (cont.) A abb bab proc A { case token corrente { a : { matching del token corrente con a Leggi il token successivo B; Matching del token corrente con b b : { matching del token corrente con b Leggi il token successivo A; B; 16

Recursive Predictive Parsing (cont.) A aa bb ε Se tutte le produzioni falliscono noi possiamo applicare produzioni ε. Se ad esempio il token non è ne a ne b, possiamo applicare la produzione ε. Noi dobbiamo applicare la produzione ε per il non-terminale A quando il token corrente è uno dei terminali che puo seguire A Recursive Predictive Parsing (Esempio) A abe A cbd A C B bb B ε C f boolean A(){ switch (symbol) { case = 'f' : return C(); case = 'a' : {symbol = scanner(); if (B()) if (symbol == 'e') { symbol = scanner(); return true; else return false; return false; case = 'c' : {symbol = scanner(); if (B()) if (symbol == 'd'){ symbol = scanner(); return true; else return false; return false; default : return false; 17

Recursive Predictive Parsing (Esempio) A abe cbd C B bb ε C f boolean B() { switch (symbol) { case = 'b': {symbol = scanner(); return B(); case = 'd' 'e': return true; default return false; Recursive Predictive Parsing (Esempio) A abe cbd C B bb ε C f boolean C() { switch (symbol) { case = 'f': {symbol = scanner(); return true; default : return false; 18

Grammatica LL(1) S A a {b,d,a A B D {b, d, a B b { b B ε {d, a D d { d D ε { a boolean S(){ switch (symbol) { symbol in {b,d,a : { if (A()) { symbol = scanner(); if (symbol == 'a') return true; else return false; else return false; default : return false; boolean A(){ switch (symbol) { symbol in {b,d,a : { if (B()) if (D()) return true; else return false; else return false; default : return false; 19

boolean B() { switch (symbol) { symbol = 'b' : {symbol = scanner(); return true; symbol in {d, a : return true; default :return false; boolean D() { switch (symbol) { symbol = 'd' : {symbol = scanner(); return true; symbol = 'a' : return true; default :return false; Prog { Stmts Eof { { Stmts Stmt Stmts {id,if Stmts ε { Stmt id = Expr ; { id Stmt if ( Expr ) Stmt { if Expr id Etail { id Etail + Expr { + Etail -Expr - { - Etail ε { ), ; 20

Parser LL(1) Data la seguente grammatica : E T E' E' + T E' ε T F T' T' * F T' ε F P $ F P P (E) - P a... z si possono scrivere un insieme di procedure mutuamente ricorsive, una per ogni non terminale, che consentono di analizzare una frase e segnalare gli errori. Esempio T = {+, *, -, ^, (, ), a,..., z V = {E, E', T, T', F, P P = { 1. E T E' 2. E' + T E' 3. E' ε 4. T F T' 5. T' * F T' 6. T' ε 7. F P $ F 8. F ε 9. P (E) 10. P -P 11. P a b... z S = E 21

Una grammatiche che non è LL(1) S i C t S E a FOLLOW(S) = { $,e E e S ε FOLLOW(E) = { $,e C b FOLLOW(C) = { t FIRST(iCtSE) = {i FIRST(a) = {a FIRST(eS) = {e FIRST(ε) = {ε FIRST(b) = {b S E C a S a b C b e E e S E ε i S ictse t $ E ε 22

Svantaggi dei parser discendenti ricorsivi Sono castomizzati rispetto alla grammatica Utilizzo della ricorsione che non è efficiente Algoritmo di parsing LL(1) public boolen parser (){ Tabella ParseTable; Pila P; Produzione Pro; Simbolo C; P.push(S); C=scanner(); While (!p.empty()&&c!= $ ){ X = P.pop(); if (x == C) C = scanner() else {(if C.terminale) return false Pro = ParseTable.get(C,X); if (Pro.vuota()) return false p.push(pro); if (p.empty()&&c= $ ) return true else return false 23