La presentazione ĆØ in caricamento. Aspetta per favore

La presentazione ĆØ in caricamento. Aspetta per favore

Implementazione di Linguaggi 2

Presentazioni simili


Presentazione sul tema: "Implementazione di Linguaggi 2"ā€” Transcript della presentazione:

1 Implementazione di Linguaggi 2
Massimo Ancona Testo: A.V. Aho, R. Sethi, J.D.Ullman Compilers Principles,Techniques and Tools, Addison Wesley

2 Diagramma del processo di compilazione

3 Strumenti associati al compilatore: il Linker

4 Contesto/ambiente di un cmp
Programming Environment Un ambiente grafico interattivo per lo sviluppo, il testing e la manutenzione dei programmi: integra e gestisce gli strumenti e i meccanismi seguenti Strumenti e meccanismi correlati ai compilatori Sistemi per le compilazioni separate Sistemi per il controllo delle versioni Meccanismi per le ricompilazioni efficienti Macroprocessori e Preprocessori Linker loader Interpreti debugger profiler

5 Processo Di Compilazione
Nella sua forma piu' astratta il processo di compilazione e' descritto nella figura seguente: il compiler e' una funzione che mappa un programma in linguaggio sorgente in un programma equivalente in linguaggio oggetto.

6 Fasi e Passi (Passate) Sono due concetti ortogonali:
Le fasi denotano trasformazioni sul programma eseguite da tutti i compilatori. I passi si riferiscono al numero di processi successivi, in cui e' suddiviso un compilatore (il loro numero dipende in parte dal linguaggio). Il compilatore in una passata, legge il codice sorgente o una sua forma intermedia equivalente, raffinando il processo di treduzione e producendo una nuova rappresentazione intermedia, fino ad arrivare al codice target, nellā€™ultima passata.

7 Fasi Di Compilazione Una fase denota il tipo di operazione effettuata. Fasi e passate sono concetti ortogonali anche se una struttura canonica del compilatore tende ad incapsulare una (o piu') fasi, in una specifica passata. La divisione piu' grossolana prevede due fasi: analisi e sintesi. Con la prima il programma sorgente viene suddiviso nelle parti costituenti ottenendone una rappresentazione intermedia. Nella seconda si costruisce il programma target nel linguaggio oggetto.

8 Analisi e Sintesi Strumenti che eseguono lā€™analisi dellā€™input
Editori di testo, Formattatori e Sistemi Ipertestuali (HTML, XML, PDF, TEX) Silicon Compilers (sintetizzatori di circuiti e componenti Hardware) Query Interpreters Motori di Ricerca e strumenti correlati

9 Analisi e Sintesi Analisi e Sintesi Analisi
divide il pgm sorgente nelle parti costituenti creando una rappresentazione intermedia. Sintesi costruisce il programma oggetto dalla rappresentazione intermedia.

10 Dettaglio Delle Fasi ELenco completo delle possibili fasi di compilazione: Concettualmente un compilatore opera in fasi, e ogni fase trasforma il programma sorgente da una rappresentazione ad unā€™altra. Questa ĆØ una tipica DECOMPOSIZIONE di un compilatore. Le fasi sulla ragruppate sulla sinistra ā€œlessicale sintattica e semanticaā€ rappresentano la porzione di analisi del compilatore, mentre le restanti tre fasi sulla destra rappresentano la sintesi del compilatore, in cui viene effettivamente costruito il codice oggetto partendo dalla rappresentazione intermedia.

11 Rappresentazioni Intermedie
sorgente primo := base + 53 * delta; out lessicale id[1] op= id[2] op+ ci=53 op* id[3] out sintattico op= id[1] op+ id[2] op* id[3]

12 Rappresentazioni Intermedie (e Finali)
out semantica op= id[1] op+ id[2] op* float id[3] 53 Il risultato della fase lessicale viene detto parse tree, ma una rappresentazione interna piĆ¹ comune ĆØ data dal SYNTAX TREE. Che ĆØ una rappresentazione compressa del parse tree in cui gli operatori a

13 Rappresentazioni Intermedie
codice intermedio tmp1 = float(53) tmp2 = id[3] op* tmp1 tmp3 = id[2] op+ tmp2 id[1] = tmp3 Ottimizzazione di codice (intermedio) tmp1 = id[3] op* 53.00 id[1] = id[2] op+ tmp1 Dopo la fase di analisi alcuni compilatori generano una rappresentazione intermedia esplicita del sorgente. Questa rappresentazione intermedia deve avere 2 caratteristiche: Essere facile da produrre E facile da tradurre nel codice oggetto. Il codice intermedio puĆ² avere varie forme ā€“ la rappresentazione utilizzata qui ĆØ detta THREE ADDRESS CODE. Consiste di una serie di istruzioni, ognuna delle quali ha al piĆ¹ tre operandi. La fase di ottimizzazione del codice cerca di migliorare il codice intermedio per renderlo di piĆ¹ veloce esecuzione. Di solito nel codice intermedio viene generata 1 istruzione per ogni operatore presente della rappresentazione ad albero dopo lā€™analisi semantica

14 Rappresentazione Finale
codice macchina: movf id3, rf2 mulf #53.00, rf2 movf id[2], rf1 addf rf2, rf1 movf rf1, id[1] Supponiamo di utilizzare solamente due registri rf1 e rf2. Lā€™ultima fase del compilatore ĆØ la generazione del codice target, assembly. Per prima cosa viene selezionata una locazione di memoria per ogni variabile utilizza nel programma, ogni istruzione intermedia viene tradotta in una sequenza di istruzioni macchina che compiano lo stesso task. Un aspetto cruciale ĆØ lā€™ASSEGNAMENTO DELLE VARIABILI AI REGISTRI. Il primo operando di ogni istruzione specifica il sorgente ed il secondo la destinazione, la F presente in ogni istruzione indica che stiamo lavorando con numeri floating-point.

15 Tipi di Compilatori Vi sono diversi tipi di compilatori
Ad un sol passo Multi-passo Load_and_go Debugging Optimizing Compiler-Interpreter Effettuano una sola passata sul codice sorgente. Eseguono piĆ¹ passate del codice sorgete o del albero sintattico I compilatori load-and-go traducono in codice sorgente in istruzioni macchina che vengono direttamente memorizzate nella memoria del computer, una volta tradotto il programma ĆØ eseguito.

16 Introduzione alla Compilazione
Un compilatore in due passate

17 Le fasi di analisi del sorgente
Analisi Lessicale. I caratteri del codice sorgente vengono letti left-to-right e raggruppati in Token. Analisi Sintattica. I caratteri o token sono raggruppati in frasi grammaticali. Analisi Semantica. Vengono effettuati controlli per trovare errori semantici e raccogliere informazioni per la generazione di codice.

18 Le fasi di analisi del sorgente Analisi Lessicale.
Token Source Program Lexical analyzer Parser Get next Token La fase di analisi lessicale ĆØ la prima fase del compilatore, il compito principale ĆØ leggere i caratteri in input e produrre in output una serie di token che il parser utilizzerĆ  per lā€™analisi sintattica. Come compito secondario: Toglie i commenti dal programma sorgente Toglie i caratteri degli spazi bianchi, tab e new line PuĆ² tenere traccia del numero di linee, in questo modo il numero di linea puĆ² essere associato ai messaggi di errore. Alcune volte lā€™analizzatore lessicale ha anche il compito di copiare il programma sorgente con gli errori marcati Alcuni analizzatori lessicali sono suddivisi in due fasi a cascata: prima fase detta scanning e seconda fase analisi lessicale. Symbol Table

19 Le fasi di analisi del sorgente Analisi Lessicale.
Eseguita dallo Scanner Ad esempio lā€™istruzione: alpha:=beta+gamma*100; viene codificata nei seguenti TOKEN: <ID:ā€™alphaā€™><OP::=><ID:ā€™betaā€™><OP:ļƒ…><ID:ā€™gammaā€™><OP:ļƒ„><VAL:ā€™100ā€™> Gli spazi ridondanti, i fine linea ecc. che separano i token vengono eliminati.

20 Le fasi di analisi del sorgente Analisi Sintattica.
Ogni linguaggio di programmazione ha delle regole che descrivono la struttura sintattica di un programma ben formato. La sintassi di un linguaggio di programmazione puĆ² essere descritta da una grammatica libera da contesto

21 Le fasi di analisi del sorgente Analisi Sintattica.
Token Source Program Lexical analyzer Parser Parse Tree Get next Token Nel nostro modello, il parser ottiene in input una sequenza di token dallā€™analizzatore lessicale, e verifica che tale sequenza di token possa essere generata dalla grammatica del linguaggio sorgente. Symbol Table

22 Le fasi di analisi del sorgente Analisi Sintattica.
Eseguita dal Parser Agisce dopo lā€™analisi lessicale. Raggruppa i token in frasi grammaticali che si rappresentano con un parse tree. Parse tree di: alpha := beta + gamma * 100 (<:=>) <EXP:ID> <EXP: ļƒ…> <ID:ā€™alphaā€™> <EXP:ID> <EXP: ļƒ„> <ID:ā€™betaā€™> <EXP:ID> <EXP:VAL> <ID:ā€™gammaā€™> <VAL:ā€™100ā€™>

23 Le fasi di analisi del sorgente Analisi Semantica.
Controlla il codice sorgente alla ricerca di errori semantici e raccoglie informazioni sui tipi per la fase di generazione di codice Type checking ĆØ la componente piĆ¹ importate di questa fase: Controlla che gli operatori abbiano operandi permessi dalla specifica del linguaggio.

24 Relazione tra le Fasi La suddivisione tra analisi lessicale e sintattica ĆØ piuttosto arbitraria (come per le altre fasi della compilazione); Uno dei metodi usati per discriminarle si basa sulla ricorsione: i costrutti descrivibili senza ricorsione si assegnano allā€™analisi lessicale; quelli sostanzialmente ricorsivi a quella sintattica.

25 Sintassi Formale dei Linguaggi di Programmazione
La si specifica tramite: diagrammi sintattici; equazioni BNF EBNF; grammatiche non contestuali (context free) Tutte forme sostanzialmente equivalenti. La sintassi dei linguaggi di programmazione viene in generale specificata mediante DIAGRAMMI SINTATTICI o EQUAZIONI BNF, o tramite GRAMMATICHE LIBERE DA CONTESTO.

26 Grammatiche Libere da Contesto (CFG)
Le Context Free Grammar sono una notazione per specificare la sintassi di un linguaggio. Una CFG ha 4 componenti: Un insieme di token, detti simboli terminali Un insieme di non-terminali Un insieme di produzioni, dove ogni produzione consiste di un non-terminale (left side), una freccia e una sequenza di token e/o non-terminali (right side) Lā€™indicazione di un non-terminale come simbolo iniziale I token o simboli terminali sono ad esempio le parole chiave del linguaggio. I non-terminali sono di variabili sintattiche che denotano un insieme di stringhe. Le produzioni specificano il modo in cui i terminali ed i non-terminali possono essere combinati per formate stringhe.

27 Grammatiche Libere da Contesto Esempio
Vediamo un esempio di produzioni che definiscono semplici espressioni aritmetiche: expr ļ‚® expr op expr expr ļ‚® ( expr ) expr ļ‚® id op ļ‚® + op ļ‚® - op ļ‚® * op ļ‚® / op ļ‚® ļ‚­ Simboli terminali: id + - * / ļ‚­ ( ( Simboli non-terminali: expr op Simbolo iniziale: expr

28 Grammatiche Libere da Contesto Esempio
Scrivere la grammatica context free per esprimere zero o piĆ¹ volte il simbolo (terminale) thing. List ļ‚® List ļ‚® thing List List ļ‚® List ļ‚® thing List ļ‚® List List List ļ‚® List ļ‚® List thing

29 Grammatiche Libere da Contesto (CFG): Definizione Formale
Alfabeto T (ļ“) : ĆØ un insieme finito non vuoto, e gli elementi di T (ļ“) vengono chiamati simboli o caratteri. Useremo le lettere V, T, N, ļ“ per indicare alfabeti

30 Grammatiche Libere da Contesto (CFG): Definizione Formale
Parola di lunghezza kļ‚³0, su un alfabeto T: ĆØ una sequenza finita w=x1x2ā€¦xk di elementi di T, k, denotata anche k=|w| ĆØ detta lunghezza di w, e la parola di lunghezza zero, detta parola vuota, eā€™ indicata ļ„.

31 Grammatiche Libere da Contesto (CFG): Definizione Formale
Lā€™insieme delle parole su T (linguaggio), indicato con T* monoide: con legge di composizione concatenazione di parole Date w1,w2ļƒŽT, w1= x1x2ā€¦xk, w2= y1y2ā€¦yl w= w1.w2= x1x2ā€¦xky1y2ā€¦yl, di lunghezza k+l, ĆØ detta concatenazione di w1 e w2. Il monoide (T*,.) ĆØ detto monoide libero su T.

32 Parentesi Algebrica: Monoide
Un monoide ĆØ un insieme M munito di una singola operazione binaria, chiamata prodotto, che ad ogni coppia di elementi a, b di M associa un elemento ab, rispettando i seguenti assiomi: per ogni a, b appartenenti a M, il loro prodotto ab appartiene ancora a M, vale a dire, M ĆØ chiuso rispetto al prodotto. Il prodotto ĆØ associativo: dati a, b, c appartenenti a M, vale (ab)c = a(bc). Esiste in M un (unico) elemento neutro e tale che ae = ea = a.

33 Grammatiche Libere da Contesto (CFG): Definizione Formale
Una CFG formalmente ĆØ una quadrupla G=(N,T,P,S) con Nļƒ‡T=ļƒ† e V=NļƒˆT, dove: T ĆØ un alfabeto di simboli terminali di G. N ĆØ un alfabeto di simboli non-terminali di G. P ĆØ un insieme finito di produzioni di G. SļƒŽN ĆØ detto simbolo iniziale di G.

34 Grammatiche Libere da Contesto (CFG): Definizione Formale
Notazione utilizzata per le produzioni ļ°ļƒŽNļ‚“V*: a,b,c,ā€¦,+,-,ā€¦,0,1,ā€¦,(,[,{,ā€¦ indicano elementi di T (= terminali) A,B,C,ā€¦ indicano elementi di N (= non-terminali) U,V,X,Y,Z indicano elementi di V=TļƒˆN u,v,x,y, indicano elementi di T*(= stringhe di terminali) ļ”,ļ¢,ļ£,ā€¦,ļ· indicano elementi di V* (= stringhe di simboli grammaticali) ļ°=(A,ļ”)ļƒŽNļ‚“V* ĆØ indicata da Aļ‚®ļ”

35 Linguaggi Context Free
Linguaggio generato da G: L(G)=ļ»wļƒŽT*| S ļƒž* wļ½ Un linguaggio L ļƒ T* ĆØ libero da contesto se esiste G=(N,T,P,S) CFG tale che L=L(G)

36 ļ”Aļ¢ ļƒž ļ”ļ·ļ¢ (Derivazione)
Forme Sentenziali Data G=(N,T,P,S) una forma sentenziale di G ĆØ definita ricorsivamente, come segue: S ĆØ una forma sentenziale di G, se ļ”Aļ¢ ĆØ una forma sentenziale di G e Aļ‚®ļ· ĆØ una produzione di G allora ļ”ļ·ļ¢ ĆØ una forma sentenziale di G. La relazione tra ļ”Aļ¢ e ļ”ļ·ļ¢ al punto precedente viene indicata: ļ”Aļ¢ ļƒž ļ”ļ·ļ¢ (Derivazione)

37 Derivazioni Dirette e Non
ļ”Aļ¢ ļƒž ļ”ļ·ļ¢ esprime che ļ”ļ·ļ¢ deriva direttamente da ļ”Aļ¢ o che ļ”Aļ¢ genera direttamente ļ”ļ·ļ¢. Le notazioni ļƒž* ļƒž+ indicano rispettivamente la chiusura transitiva-riflessiva e transitiva di ļƒž ļ” ļƒž* ļ¢ denota che ļ”=ļ¢ oppure ļ€¤ ļ”i i=1..n ļ”=ļ”1 ļƒž ļ”2 ļƒž ā€¦ ļƒž ļ”n = ļ¢ e n>0. ļ” ļƒž+ ļ¢ denota che ļ”=ļ”1 ļƒž ļ”2 ļƒž ā€¦ ļƒž ļ”n = ļ¢ e n>0. Idea di base: le produzioni di una grammatica possono essere viste come REGOLE DI RISCRITTURA in cui il NON-TERMINALE a sinistra viene rimpiazzato dalla stringa della parte destra della produzione.

38 Derivazioni - Esercizio
La stringa ā€“ ( id + id ) ĆØ una sentenza della grammatica G? E ļƒž - E ļƒž - ( E ) ļƒž - ( E + E ) ļƒž - ( id + E ) ļƒž - ( id + id ) G: E ļ‚® E + E E ļ‚® E * E E ļ‚® ( E ) E ļ‚® - E E ļ‚® id E ļƒž* - ( id + id )

39 Derivazioni canoniche
Una derivazione ļ” ļƒž*ļ¢ eā€™ detta canonica destra e indicata ļ” ļƒžrm* ļ¢, se ad ogni passo di derivazione si espande il simbolo non-terminale piĆ¹ a destra. ļ” ļƒžrm* ļ¢ se ļ€¢ i si ha ļ”i=ļ¢iAixi, ļ”i+1=ļ¢iļ·ixi, Aiļ‚® ļ·i, ļ”=ļ”1 ļƒž ļ”2 ļƒž ā€¦ ļƒž ļ”n = ļ¢ i=1,ā€¦,n

40 Derivazioni canoniche
Una derivazione ļ” ļƒž*ļ¢ eā€™ detta canonica sinistra e indicata ļ” ļƒžlm* ļ¢, se ad ogni passo di derivazione si espande il simbolo non-terminale piĆ¹ a sinistra. ļ” ļƒžlm* ļ¢ se ļ€¢ i si ha ļ”i=xiAi ļ¢i, ļ”i+1=xiļ·i ļ¢i, Aiļ‚® ļ·i, ļ”=ļ”1 ļƒž ļ”2 ļƒž ā€¦ ļƒž ļ”n = ļ¢ i=1,ā€¦,n

41 Derivazioni Canoniche Esempio
Non-terminali terminali G=({E,T,P}, {(,),a,b,c,*,+,-}, P, E) P={Eļ‚®E +T |E -T |T, T ļ‚®T *P |P, P ļ‚® (E ) | a | b | c} Data (a-b) ā€“ c la derivazione: E ļƒž E -T ļƒž T -T ļƒž P -T ļƒž (E )-T ļƒž (E - T )-T ļƒž (T - T )-T ļƒž (P - T )-T ļƒž (a - T )-T ļƒž (a - P )-T ļƒž (a - b )-T ļƒž (a - b )-P ļƒž (a - b ) - c ƈ canonica sinistra.

42 Esempio Sia G=({E,T,P}, {(,),a,b,c,*,+,-}, P, E) dove
P={Eļ‚®E+T | E-T | T, T ļ‚®T*P | P, P ļ‚® (E) | a | b |c} La derivazione: E ļƒžE-T ļƒž E-P ļƒž E-c ļƒžT-c ļƒžP-c ļƒž(E)-c ļƒž (E-T)-c ļƒž(E-P)-c ļƒž(E-b)-c ļƒž(T-b)-T ļƒž(P-b)-c ļƒž (a-b)-c ĆØ canonica destra, confrontandola con la canonica sinistra: E ļƒžE-T ļƒž T-T ļƒžP-T ļƒž(E)-T ļƒž (E-T)-T ļƒž(T-T)-T ļƒž(P-T)-T ļƒž(a-T)-T ļƒž(a-P)-T ļƒž (a-b)-T ļƒž(a-b)-P ļƒž(a-b)-c Si vede che differiscono solo per lā€™ordine di applicazione delle produzioni. Entrambe applicano le stesse produzioni alle stesse istanze di non terminali

43 Parsing Tree Tutte le derivazioni che differiscono solo per lā€™ordine di applicazione delle produzioni sono sostanzialmente equivalenti e possono essere rappresentate da unā€™unica derivazione canonica destra, unā€™ unica derivazione canonica sinistra o da un unico albero etichettato detto Parsing Tree. Il parse tree puĆ² essere visto come una rappresentazione grafica della derivazione, che filtra le scelte fatte a riguardo dellā€™ordine di applicazione delle produzioni.

44 Parsing Tree - Definizione
La radice ĆØ etichettata da S Ogni foglia dellā€™albero ĆØ etichettato da ļ„ o da un simbolo di T (terminale) Ogni nodo interno ĆØ etichettato da un simbolo di N (non terminale) Se A etichetta un nodo interno e X1,X2,ā€¦, Xn sono le etichette dei figli, allora Aļ‚®X1X2ā€¦Xn ļƒŽ P

45 Parsing Tree - Esempio Derivazione: - (id + id) E - E ( E ) E + E

46 Esempio di Parsing Tree
Derivazione di: (a ā€“ b ) ā€“ c Grammatica: Eļ‚®E +T |E -T |T T ļ‚®T *P |P, P ļ‚® (E ) | a | b | c}

47 Classificazione di Chomsky
ƈ una classificazione dei linguaggi basata sulla complessitƠ delle produzioni delle grammatiche che li generano. I linguaggi di tipo 0 sono generati da grammatiche a struttura di frase. I linguaggi di tipo 1 sono generati da grammatiche dipendenti dal contesto. I linguaggi di tipo 2 sono generati da grammatiche libere dal contesto. I linguaggi di tipo 3 sono generati da grammatiche lineari (o regolari).

48 Classificazione di Chomsky
Grammatiche a struttura di frase. Le produzioni sono del tipo ļ” A ļ· ļ‚® ļ¢ Grammatiche dipendenti dal contesto. Le produzioni sono del tipo ļ” A ļ· ļ‚® ļ” ļ¢ ļ· dove ļ”, ļ·ļƒŽV*, AļƒŽN e ļ¢ļƒŽV* . Grammatiche libere dal contesto. Le produzioni sono del tipo Aļ‚®ļ¢, dove ļ¢ļƒŽV* . Grammatiche lineari (o regolari). Le produzioni sono del tipo Aļ‚®uB oppure Aļ‚®u, dove u ļƒŽ ļ“* e A, B ļƒŽ N.

49 Classificazione di Chomsky
Ogni grammatica di tipo n ĆØ anche una grammatica di tipo n āˆ’ 1. Un linguaggio ĆØ di tipo n se ĆØ generato da una grammatica di tipo n, ma non di tipo n + 1. Esempi: - Linguaggio di tipo 3: L = {ambn : m, n ļ‚³ 0}. - Linguaggio di tipo 2: L = {anbn : n ļ‚³ 0}. - Linguaggio di tipo 1: L = {anbncn : n ļ‚³ 0}. - Linguaggio di tipo 0: L = {an : n ĆØ numero primo}.

50 Grammatiche e Linguaggi Ambigui
Una grammatica G ĆØ ambigua se: ļ€¤ wļƒŽL(G) con due parsing tree diversi Un linguaggio ĆØ inerentemente ambiguo se per ogni G tale che L=L(G) si ha che G eā€™ ambigua.

51 Tecniche per Disambiguare
Inserire regole di precedenza per gli operatori. Utilizzare associativitĆ  a sinistra o a destra. Manipolare la grammatica.

52 Grammatica Ambigua Esempio
G=({S}, {if, then, else, s, b}, P={S ļ‚® if b then S | if b then S else S | s}, S) Sļƒžrm if b then S ļƒžrm if b then if b then S else S ļƒžrm if b then if b then S else s ļƒžrm if b then if b then s else s S ļƒžrm if b then S else S ļƒžrm if b then S else s ļƒžrm if b then if b then S else s ļƒžrm if b then if b then s else s if b then if b then s else s

53 Grammatica Ambigua Esempio
Grammaticha ambigua: G=({S}, {if, then, else, s, b}, P={S ļ‚® if b then S | if b then S else S | s}, S) Grammatica disambiguata: G=({S, S1, S2}, {if, then, else, s, b}, P={S ļ‚® S1, S1 ļ‚® if b then S1 | if b then S2 else S1 | s, S2 ļ‚® if b then S2 else S1 | s},

54 Grammatica non ambigua con proprietĆ  opportune
Nota: la gramamtica ĆØ context free, e mostriamo solo le produzioni. Grammatica di espressioni non ambigua con prioritĆ  di operatori e associativitĆ  cablate Eļ‚®E+T | E-T | T Tļ‚®T*F | T/F | F Fļ‚®P^F | P P ļ‚®(E) | I | N I ļ‚® a|b|c|d N ļ‚® 0 | 1 | 2 G per espressioni, semplice ma ambigua Eļ‚®EOE|(E)|a|b|c|d Oļ‚®+|-|*|^

55 Altri esempi di grammatiche
G0 di espressioni non ambigua con prioritĆ  di operatori e associativitĆ  cablate Eļ‚®E+T | E-T | T |-T|+T Tļ‚®T*F | T/F | F F ļ‚®(E) | I | N I ļ‚® a|b|c|d N ļ‚® 0 | 1 | 2 G1 per espressioni, semplice, non ambigua ma flat Eļ‚®EOT|T|-T|+T T ļ‚®(E)|a|b|c|d|0|1|2 Oļ‚®+|-|*|/

56 Derivazione canonica di G0
Data a-b*c e G0 abbiamo: EļƒžrmE-T ļƒžrmE-T*F ļƒžrmE-T*I ļƒžrmE-T*c ļƒžrmE-F*c ļƒžrmE-I*c ļƒžrmE-b*c ļƒžrmT-b*c ļƒžrmF-b*c ļƒžrmI-b*c ļƒžrma-b*c Eļ‚®E+T | E-T | T |-T|+T Tļ‚®T*F | T/F | F F ļ‚®(E) | I | N I ļ‚® a | b | c | d N ļ‚® 0 | 1 | 2

57 Parse tree (G0) Derivazione Canonica: EļƒžrmE-T ļƒžrmE-T*F
ļƒžrmE-T*I ļƒžrmE-T*c ļƒžrmE-F*c ļƒžrmE-I*c ļƒžrmE-b*c ļƒžrmT-b*c ļƒžrmF-b*c ļƒžrmI-b*c ļƒžrma-b*c E E - T T T * F F F I I I c a b

58 Derivazione canonica di G1
Data a-b*c e G1 abbiamo: EļƒžrmEOT ļƒžrmEOc ļƒžrmE*c ļƒžrmEOT*c ļƒžrmEOb*c ļƒžrm ļƒžrmE-b*c ļƒžrm ļƒžrmT-b*c ļƒžrm a-b*c Eļ‚®EOT|T|-T|+T T ļ‚®(E)|a|b|c|d|0|1|2 Oļ‚®+|-|*|/

59 Parse tree (G1) Derivazione Canonica: EļƒžrmEOT ļƒžrmEOc ļƒžrmE*c ļƒžrmEOT*c
ļƒžrmEOb*c ļƒžrm ļƒžrmE-b*c ļƒžrm ļƒžrmT-b*c ļƒžrm a-b*c E E O T E O T * c T b a

60 Esercizio Studiare G2: Eļ‚®FOT | T Fļ‚®FOT | T | ļ„
Tļ‚®(E)| a | b | c | d | 0 | 1 | 2 Oļ‚®+ | - | * | ^

61 Esempio Documenti HTML XML: Dļ‚®Ps B Pd Psļ‚®<html> Pdļ‚®<\html>
B ļ‚® <body>L <\body> Lļ‚®E L | E | ļ„ Eļ‚®<div>R<\div> Rļ‚®rest

62 Esempio Documenti HTML XML: Dļ‚®Ps B Pd Psļ‚®<html> Pdļ‚®<\html>
B ļ‚® <body>L <\body> Lļ‚®E L | E | ļ„ Eļ‚®<div>R<\div> Rļ‚®rest

63 Esempio Documenti HTML XML: Dļ‚®Ps B Pd Psļ‚®<html> Pdļ‚®<\html>
B ļ‚® <body>L <\body> Lļ‚®E L | E | ļ„ Eļ‚®<div>R<\div> Rļ‚®rest

64 Esempio Documenti HTML XML:
Dļ‚®Ps L Pd Psļ‚®<html> Pdļ‚®<\html> Lļ‚®E L | E | ļ„ Eļ‚®<div>R<\div> Rļ‚®rest

65 Operazioni sui Linguaggi
Dati due linguaggi L, M ļƒ ļ“* definiamo prodotto di L e M, indicato LM o L.M, lā€™insieme: Lļƒ—M ={uv | u ļƒŽL & v ļƒŽM}

66 Operazioni sui Linguaggi
Definiamo chiusura di Kleene di L, indicata con L*, lā€™operazione: L0={ļ„} L1=L Li=Lļƒ—Li-1 i>0 L*=ļƒˆiļ‚³0 Li L+=ļƒˆi>0 Li

67 Operazioni sui Linguaggi - Esempi
Proprietaā€™: supponiamo T terminale e vediamo le produzioni di E G0=({E},{t,+,-},P0,E) P0={Eļ‚®E+t | E-t | t|-t|+t} L(G0)={-t,+t,t}({+,-}t)* e G1=({E,O},{t,+,-},P1,E) P1={Eļ‚®EOt|t|-t|+t,Oļ‚®+|-} Oļ‚®+|- L(G1)=L(G0)

68 Linguaggi - Esempi Esempio di linguaggio inerentemente ambiguo
L={aibjck| i=j OR j=k; i,j,kļ‚³0} Sļ‚®S1S2 | S3S4 S1ļ‚®aS1b |ļ„ S2 ļ‚® S2 c| ļ„ S4ļ‚®bS4c |ļ„ S3 ļ‚® S3 a| ļ„ Esempio di linguaggio non context free. L={anbncn| n>(ļ‚³) 0} non eā€™ un CFL

69 Syntax Tree (albero sintattico) e Parsing Tree
Una delle rappresentazioni intermedie piĆ¹ usate. PiĆ¹ astratto del parsing tree, dipende solo dal linguaggio (non dalla grammatica)

70 EBNF Usa i simboli metalinguistici ā€œ=ā€œ ā€œ|ā€ ā€œ[ā€œ ā€œ]ā€ ā€œ{ā€œ. ā€œ}ā€ ā€œ.ā€ ā€œā€ā€
[ā€¦] significa opzionalitaā€™ {ā€¦} significa ripetizione: 0 o piuā€™ volte ā€œ(ā€¦)ā€ significa raggruppamento ā€œ|ā€ indica alternativa ā€œ.ā€ termina una produzione I simboli terminali vengono racchiusi tra ā€œ ā€œ Esempio Expression = SimpleExpression [ Relation SimpleExpression ]. Relation = "=" | "<>" | "<" | "<=" | ">" | ">=" | "IN". SimpleExpression = [ "+" | "-" ] Term { AddOperator Term }. AddOperator = "+" | "-" | "OR". Term = Factor { MulOperator Factor }. MulOperator = "*" | "/" | "DIV"| "MOD" | "AND"

71 EBNF Esempio (Espressioni)
Expression = SimpleExpression [ Relation SimpleExpression ]. Relation = "=" | "<>" | "<" | "<=" | ">" | ">=" | "IN". SimpleExpression = [ "+" | "-" ] Term { AddOperator Term }. AddOperator = "+" | "-" | "OR". Term = Factor { MulOperator Factor }. MulOperator = "*" | "/" | "DIV" | "MOD" | "AND"

72 EBNF Espressioni (cont.)
Designator [ ActualParameters ] | "(" Expression ")" | NOT Factor. Set = "[" [ Element { "," Element } ] "]". Element = OrdinalConstant [ ".." OrdinalConstant]. OrdinalConstant= Char | Integer. ActualParameters = ["(" [ ExpressionList ] ")"]. Ident = IdChar { IdChar | Digit }. IdChar = Letter | "_". Number = Integer | Real.

73 EBNF Espressioni (cont. 2)
Integer = Digit { Digit } | Digit { HexDigit } "H". Real = Digit { Digit } "." { Digit } [ ScaleFactor ]. ScaleFactor = "E" [ "+" | "-" ] Digit { Digit }. HexDigit = Digit | "A" | "B" | "C" | "D" | "E" | "F". Digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9". CharConstant = "'" Char "'" | Digit { HexDigit } "X". String = ' { CharN | "''" } '. Char = CharN | "'".


Scaricare ppt "Implementazione di Linguaggi 2"

Presentazioni simili


Annunci Google