Linguaggi Formali e Compilazione: Parsing

Embed Size (px)

Text of Linguaggi Formali e Compilazione: Parsing

  1. 1. LFCParsing dilinguaggi liberiIntroduzioneParsing top-downParsing bottom-upLinguaggi formali e compilazione Corso di Laurea in InformaticaA.A. 2008/2009
  2. 2. LFC Linguaggi formali e compilazioneParsing dilinguaggi liberiIntroduzioneParsing top-downParsing bottom-up Parsing di linguaggi liberiIntroduzioneParsing top-downParsing bottom-up
  3. 3. LFC Linguaggi formali e compilazioneParsing dilinguaggi liberiIntroduzioneParsing top-downParsing bottom-up Parsing di linguaggi liberiIntroduzioneParsing top-downParsing bottom-up
  4. 4. LFC Parsing di linguaggi liberi Ogni linguaggio libero pu essere riconosciuto in Parsing di linguaggi liberi tempo proporzionale al cubo della lunghezza della Introduzionestringa in input. Parsing top-down Parsing bottom-up Lalgoritmo che stabilisce questo limite di complessit, basato su una classica applicazione della programmazione dinamica, tuttavia inutilizzabile in applicazioni reali. Gli algoritmi di parsing utilizzati nella pratica sono generalmente classicati base alla strategia utilizzata per la costruzione (anche solo ideale) del parse-tree, top-down o bottom-up. Allinterno di queste due categorie generali, gli algoritmi si differenziano in base a scelte strategiche pi dettagliate. Tali algoritmi non possono analizzare tutti i linguaggi context-free.
  5. 5. LFC Tipi di parserParsing dilinguaggi liberiIntroduzioneParsing top-down In concreto, i tipi di parser pi diffusi includono: Parsing bottom-up parser a discesa ricorsiva (top-down), parser di tipo LR (bottom-up), parser a precedenza di operatori (bottom-up). Nel parsing top-down si cerca una derivazione canonica per la stringa/programma in input partendo dallassioma iniziale. La costruzione top-down dellalbero di derivazione corrisponde in modo naturale al riconoscimento di un blocco/procedura/espressione in termini delle parti costituenti.
  6. 6. LFC Tipi di parser (continua)Parsing dilinguaggi liberiIntroduzioneParsing top-downNel parsing bottom-up si cerca una derivazione Parsing bottom-up canonica per la stringa/programma in input partendo dalla stringa stessa e applicando riduzioni successive. Una riduzione non nientaltro che lapplicazione in senso contrario di una produzione della grammatica. La costruzione bottom-up dellalbero di derivazione corrisponde in modo naturale al riconoscimento di singole porzioni di un programma e alla loro composizione in parti pi complesse.
  7. 7. LFC Non determinismo Parsing di linguaggi liberi Introduzione In entrambi i tipi di parser (top-down o bottom-up) Parsing top-down Parsing bottom-up possibile (anche se non desiderabile) che la scelta della produzione da utilizzare, in una delle due direzioni, non sia determinabile con certezza. Se la scelta di una produzione errata il riconoscimento fallisce. In tal caso, prima di dichiarare che la stringa sintatticamente errata, necessario operare un backtracking sullinput, ritornando al punto di scelta. Per i parser a discesa ricorsiva (e implementati mediante ricorsione) ci pu essere sufcientemente agevole, anche se computazionalmente pesante.
  8. 8. LFC Linguaggi formali e compilazioneParsing dilinguaggi liberiIntroduzioneParsing top-downParsing bottom-up Parsing di linguaggi liberiIntroduzioneParsing top-downParsing bottom-up
  9. 9. LFC Parsing a discesa ricorsiva (recursive descent) Parsing di linguaggi liberi Introduzione Parsing top-down Parsing bottom-upUn parser a discesa ricorsiva (d.r.) pu essere realizzato come collezione di procedure (mutuamente) ricorsive, una per ogni simbolo non terminale della grammatica. Siano A 1 . . . k le produzioni relative al ii nonterminale A, e sia i = X1 . . . Xni , i = 1, . . . , k. La procedura relativa al simbolo A illustrata nel seguente algoritmo, in cui (per semplicit di notazione) evitiamo i doppi indici e supponiamo che il simbolo corrente di input sia contenuto nella variabile globale x.
  10. 10. LFCParsing dilinguaggi liberiIntroduzioneParsing top-down Algorithm 1 Procedura per il nonterminale AParsing bottom-up 1: Scegli opportunamente una produzione A X1 X2 . . . Xk (Xj V)2: for j = 1, . . . , k doif Xj N then3:Xj ()4:else if Xj = x then5:x read()6:else7:error()8:
  11. 11. LFC Backtracking La scelta della produzione da applicare (riga 1Parsing di linguaggi liberi dellalgoritmo 1) pu essere meno critica se, nel caso IntroduzioneParsing top-downdi fallimento, viene effettuato backtracking sullinput. Parsing bottom-upLalgoritmo deve essere modicato in modo tale da dichiarare fallimento solo quando tutte le produzioni per il nonterminale A sono state provate senza successo. Deve per essere disposto un meccanismo per riposizionare il puntatore di input su quello che era il simbolo corrente al momento della chiamata della procedura. Ne consegue che: o il parser bufferizza linput ricevuto dallo scanner, oppure questultimo che deve essere opportunamente programmato per la ripetizione di certe sequenze di token.
  12. 12. LFC Scelta della produzione Fortunatamente, in molti casi concreti il backtracking Parsing di linguaggi liberi non necessario perch la scelta della produzioneIntroduzione Parsing top-down pu essere fatta con lookahead limitato (cio Parsing bottom-up guardando pochi token a partire dalla posizione corrente di input). Consideriamo la semplice grammatica: A aA | bBB | bBPer entrambi i non terminali, la scelta della produzione da usare pu essere fatta guardando il prossimo simbolo x in input. Per A: se x = a, usa la produzione A aA; se x = b, usa la produzione A bB. Per B. se x = $ (end of input), usa la produzione B ; se x = b, usa la produzione B bB;
  13. 13. LFC Grammatiche inadatte al parsing a discesa ricorsivaParsing di Alcune produzioni sono inadatte al r.d. parsing. linguaggi liberi IntroduzioneProduzioni con ricorsioni a sinistra, che possono Parsing top-downParsing bottom-upcausare cicli inniti, come nella grammatica E +T | T E T F | F T id | (E )F Produzioni con pressi comuni (come il noto caso del dangling else), che rendono non limitabile a priori la quantit di lookahead. Un altro esempio (articiale) A aB | aCB aB | bC aC | c Come sappiamo, esistono opportune trasformazioni per risolvere questi problemi.
  14. 14. LFC FIRST e FOLLOWData una grammatica G, limplementazione di parserParsing dia d.r. per G utilizza (secondo le teorie pi accettate) linguaggi liberiIntroduzionedue funzioni, dette FIRST e FOLLOW , cheParsing top-downParsing bottom-updeterminano la scelta della produzione da utilizzare.Data G = (N , T , P, S) e data una stringa (N T ) , si denisce FIRST () linsieme deisimboli terminali con cui pu iniziare una frasederivabile da , pi eventualmente se :FIRST () = {x T | x, T } {} , se .Per ogni nonterminale A N si denisceFOLLOW (A) linsieme dei terminali che si possonotrovare immediatamente alla destra di A in unaqualche forma di frase. In altri termini,x FOLLOW (A) se S Ax, con e opportuni.
  15. 15. LFC Calcolo di FIRST () Parsing di linguaggi liberi Introduzione Deniamo innanzitutto come si calcola FIRST () nel Parsing top-down Parsing bottom-up caso in cui sia un singolo simbolo della grammatica, cio = X con X N T . Se X un terminale, si pone naturalmente FIRST (X ) = {X }; se X un nonterminale poniamo innanzitutto FIRST (X ) = {}. Se esiste la produzione X X1 . . . Xn , e risulta FIRST (Xj ), j = 1, . . . , k 1, poniamo FIRST (X ) = FIRST (X ) {x} per ogni simbolo x FIRST (Xk ). Inne, se esiste la produzione X oppure FIRST (Xj ), j = 1, . . . , k , poniamo FIRST (X ) = FIRST (X ) {}.
  16. 16. LFC EsempiSi consideri nuovamente la grammaticaParsing dilinguaggi liberi (E ) E | id E EIntroduzioneParsing top-downParsing bottom-up E + E E | E E | Per questa grammatica risultaFIRST (E) = {( , id} FIRST (E ) = {+, , } Si consideri ora la grammatica per an bm ckA aA | BC | B bB | C cC | Per questa grammatica risultaFIRST (C) = {c, } FIRST (B) = {b, } FIRST (A) = {a, b, c, }
  17. 17. LFC EsempioParsing dilinguaggi liberiIntroduzioneParsing top-down Si riconsideri la grammatica per le espressioni che Parsing bottom-upforza la precedenza di operatori: E +T | T E T F | FT id | (E )F Per questa grammatica risultaFIRST (F ) = {( , id}; FIRST (T ) = FIRST (F ); FIRST (E) = FIRST (T ).
  18. 18. LFC Calcolo di FIRST () (continua)Parsing dilinguaggi liberiIntroduzioneIl calcolo di FIRST (), dove = X1 . . . Xn unaParsing top-down Parsing bottom-upgenerica stringa di terminali e nonterminali, pu ora essere svolto nel modo seguente a FIRST () se e solo se, per qualche indice k 1, . . . n 1, risulta a Xk e Xj , j = 1, . . . , k 1 (si suppone sempre FIRST (X0)). Se inoltre FIRST (Xj ), j = 1, . . . , n, allora FIRST (). Ad esempio, nel caso della seconda grammatica del lucido precedente risulta: FIRST (aA) = {a} e FIRST (BC) = {b, c, }.
  19. 19. LFC Calcolo di FOLLOW (A) Parsing di linguaggi liberi IntroduzioneIl calcolo di FOLLOW (A), per un generico non Parsing top-down Parsing bottom-upterminale A, pu essere svolto in questo modo. Se A = S, si inserisce il simbolo speciale $ (marcatore di ne input) in FOLLOW (A). Se esiste la produzione B A, tutti i terminali in FIRST () si inseriscono in FOLLOW (A); inoltre, se FIRST (), tutti i terminali che stanno in FOLLOW (B) si inseriscono in FOLLOW (A) . Analogamente, se esiste la produzione B A, tutti i terminali che stanno in FOLLOW (B) si inseriscono in FOLLOW (A) .
  20. 20. LFC EsempioParsing diConsideriamo la solita grammaticalinguaggi liberiIntroduzioneParsing top-down (E ) E | id E EParsing bottom-up +E E | E E | E Possiamo subito stabilire che FOLLOW (E ) include ilsimbolo $ e il simbolo ); inoltre contiene i simboli inFIRST (E ) (eccetto ) e cio + e .FOLLOW (E ) include FOLLOW (E ), a causa (adesempio) della produzione E idE .La produzione