Scaricare la 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 | "'".
Presentazioni simili
© 2024 SlidePlayer.it Inc.
All rights reserved.