- Teacher: Sproston Jeremy
- PDF Version
- Prova di laboratorio (progetto, interrogazione singola anche in caso di progetto di gruppo con gruppi da 3)
-
Sostenibile dopo aver superato Teoria 1/3 del voto
-
Testi
Compilatori
Principi tecniche e strumenti
Automi
Automi, Linguaggi e Calcolabilita’
Fasi Compilatore
-
NB
Analisi Lessicale
sequenze di caratteri | token o lessemi
Si passa da
- Programma come sequenza di caratteri
- Programma come sequenza di token
Token
Costante numerica intera sequenza non vuota di cifre decimali, preceduta da + o - Costante numerica con virgola due sequenza (almeno 1 non vuota) di cifre decimali separate da . Identificatore sequenza on vuota di lettere numeri e _ e non inizia con un numero
Lexer
Analizzatore lessicale —-> Codice <—- La visione del programma passa da “carattere per carattere” a “token per token”
- spazi e commenti vengono scartati dal lexer
- * *
- //
- finiscono con a capo o EOF
- Token
- Identificatori
- non comincia con un numero
- non é composto solamente dal simbolo _
- Ovvero corrisponde all’espressione regolare
- ([a-zA-Z] | (()*[a-zA-Z0-9])) ([a-zA-Z0-9] | _)*
- Identificatori
Analisi Sintattica
Vedi: Parser Top-Down e Codice Parser a Discesa Ricorsiva
- Prende input dall’analizzatore lessicale
- Crea un Albero Sintatico
- che sará utilizzato poi dal Analizzatore Semantico
- vedi Analisi Semantica
- che sará utilizzato poi dal Analizzatore Semantico
- In caso l’input non corrisponda ad un albero lessicale
- deve restituire un errore
- Espressioni Booleane
- RELOP
- Separatore
- punto e virgola
- non un terminatore di istruzione
- punto e virgola
- Produzioni
- In caso di rami annullabili attenzione ai FOLLOW
- Sintassi scheme-like
- espressioni aritmetiche
- notazione prefissa
- puó comprendere ID
-
operatori
- - / : binarie
- compaiono nelle espressioni booleane
- impatto sull’insieme GUIDA
- assegnamento
- notazione prefissa
- espressioni relazionali
- notazione prefissa
- espressioni aritmetiche
Analisi Semantica
- Si occupa della valutazione delle espressioni
SDD
Syntax Directed Definition Definizioni dirette dalla sintassi strumento che permette la traduzione
- consistono in
- grammatica libera
- specifica la sintassi
- gli operatori qui sono sintattici
- specifica la sintassi
- attributi
- risultati della traduzione
- sono riferiti dall’analizzatore lessicale
- (nome, valore)
- rappresentano una qualunque informazione associata ad un nodo
- risultati della traduzione
- regole semantiche
- come calcolare gli attributi
- specificano regole di calcolo e assegnamento tra attributi per ogni produzione
- gli operatori qui sono semantici/matematici
- sono valutate in ordine arbitrario
- richiedono la costruzione di un albero sintattico annotato
- grammatica libera
Con cui si definisce un albero sintattico annotato
- i cui nodi possono essere annotati con 0 o piú attributi
-
Attributi
- Sintetizzati Il suo valore dipende da quello di attributi dei figli ed eventualmente da altri attributi di se stesso
- Ereditati Il suo valore dipende da quello dal padre e dai fratelli del nodo
-
Grafo delle dipendenze Alcuni attributi dipendono da altri, questo impone un’ordine tra questi
- se il grado contiene dei cicli non é possibile trovare un’ordine di valutazione degli attributi
-
S-attribuite Contiene solo attributi sintetizzati
- ogni S-attribuita é a sua volta L-attribuita
-
L-attribuite Per ogni produzione e ogni attributo ereditato la regola semantica che definisce il valore di dipende solo da
- attributi ereditati da
- attributi sintetizzati ed ereditati dai simboli alla sinistra di
SDT
Syntax-Directed Translation scheme Schema di traduzione, variante SDD che rende esplicito l’ordine di valutazione degli attributi
- grammatica in cui le produzioni sono arricchite da frammenti di codice
- azioni semantiche
- eseguite nel momento che i simboli alla loro sinistra sono stati riconosciuti
- simili alle regole semantiche degli SDD
- specificano il calcolo degli attributi ma anche codice arbitrario
- l’ordine di esecuzione é esplicito a differenza delle regole semantiche
- essendo eseguite da sinistra verso destra non richiedono la costruzione dell’albero sintattico annotato
- azioni semantiche
-
da SDD L-attribute a SDT data
- subito prima di
- azione semantica che calcola il valore degli attributi ereditati
- che possono solo dipendere da attributi ereditati di e attributi dei nodi fratelli alla sua sinistra
- azione semantica che calcola il valore degli attributi ereditati
- in fondo alla produzione a. azione semantica che calcola il valore degli attributi sintetizzati di
- subito prima di
Traduzione on the fly
Attributi sintetizzati principali
- il loro valore include sempre la concatenazione dei valori dello stesso attributo per tutte le variabili nel corpo di ogni produzione oltre che eventuali variabili ausiliarie
- la concatenzazione rispetta l’ordine delle variabili nel corpo delle produzioni Es, trasformazione da forma infissa a postfissa
Questo viene tradotto on the fly in { print(”…”) }
Automi
Esempio
automa: riconosce stringhe stati finiti: memoria finita input: stringa output: “si” se riconosciuta “no” altrimenti
L’automa ha visione locale e limitata , legge un simbolo alla volta
L’automa altera il suo stato in base al simbolo letto
Se alla fine della stringa l’automa si trova in uno stato finale la stringa é accettata, altrimenti rifiutata
Automi a stati finiti deterministici DFA
Deterministico: lo stato in cui si sposta é univocamente determinato dallo stato corrente e dal input
Quintupla composta da:
- - insieme finito di stati
- - alfabeto riconosciuto
- - funzione di transizione
- - e’ lo stato iniziale
- - insieme di stati finali
Funzione di transizione estesa
funzione definita su stringhe invece che singoli simboli definito per induzione
Linguaggio riconosciuto
Stringhe definite sull’alfabeto che per mezzo della F di transizione estesa portano ad uno stato finale dell’automa
Automi a stati finiti non deterministici NFA
Non deterministico: l’automa puo’ scegliere di spostarsi in 0 o piu’ stati possibili
- Il codominio della funzione di transizione e’ l’insieme delle parti degli stati
Quintupla composta da:
-
- insieme finito di stati
-
- alfabeto riconosciuto
-
- funzione di transizione il cui codominio e’ un’insieme delle parti di Q
-
- e’ lo stato iniziale
-
- insieme di stati finali Insiemi singoletto indicano transizioni deterministiche (da funzione di transizione estesa) Automi che possono eseguire transizioni spontanee senza leggere alcun simbolo nella stringa da riconoscere
- passa di stato anche senza consumare alcun simbolo
epsilon-chiusura
calcolare l’insieme di stati raggiungibili solo con transizioni-epsilon ECLOSE
-
la chiusura e’ transitiva
-
la chiusura di q include q ECLOSE(S) = Unione di ECLOSE(qi) Gli NFA sono un caso particolare di epsilon-NFA in cui non ci sono transizioni epsilon
- il potere riconoscitivo degli epsilon-NFA e’ almeno pari a quello dei DFA/NFA
- Teorema Dato un eNFA E esiste un DFA D tale che L(D) = L(E)
Passaggio da DFA a NFA e viceversa
Da NFA a DFA sono possibili fino a stati
Da un DFA con piu’ stati finali e’ possibile ricavare un e-NFA equivalente con un unico stato finale
Espressioni regolari RE
Sono un approccio generativo alle classi di Linguaggi E’ sempre possibile creare un e-NFA a partire da una RE
Denotano un Linguaggio con Definito per induzione
// la stringa vuota // chiusura di Kleene
precedenza
- *
- concatenazione
- +
Proprietá
- Unione
- Commutativa
- Associativa
- Idempotenza
- Identitá
- Concatenazione
- Associativa
- Identitá
- Assorbimento
- distributivitá
- Chiusura di Kleene
- Idempotenza
Indistinguibilitá tra stati
Equivalenza (relazione riflessiva, simmetrica e transitiva) Due stati hanno lo stesso potere discriminante se presa una qualunque stringa del linguaggio si arriva ad uno stato finale in entrambi i casi o no in entrambi i casi, la indichiamo con ~
- Puó esserci una stringa che
distinguei due stati - Uno stato finale é distinto da altri stati non finali dalla stringa vuota
Minimizzazione di Automi
si raggiunge un automa minimo: in cui Non esiste un automa corrispondente con meno stati dell’automa minimo
Equivalenza di Automi
Puó essere usato l’algoritmo riempi tabella per decidere se due automi sono equivalenti Si crea l’unione dei due DFA: Se e risultano indistinguibili in allora e sono equivalenti
Automi a Pila PDA
Approccio Riconoscitivo Utilizza operazioni push e pop su una pila di dimensione illimitata
- Simbolo sentinella che indica la fine della stringa, é il simbolo della pila con cui quest’ultima viene inizializzata
- Ad ogni lettura di un simbolo l’automa fa push(x) o push(b) dipendentemente dal Linguaggio
- La transizione finale puó eseguire solo se peek restituisce
- = alfabeto di input
- = alfabeto della pila
- = funzione di transizione
Descrizioni istantanee
Fissato un automa a pila
- stato in cui si trova l’automa
- ció che rimane da riconoscere nella stringa di input
- contenuto della pila dalla cima al fondo (sx a dx)
- Mosse relazioni da a chiusura riflessiva e transitiva
Linguaggio Accettato
Per stato finale: Per pila vuota:
- Per stato finale il contenuto della pila nella finale é irrilevante
- Per pila vuoto lo stato nela finale puó non essere finale
In ogni caso la stringa di input deve essere consumata completamente
Automi a Pila Deterministici
DPDA Strettamente meno espressivi dei PDA
- riconoscono comunque ogni Linguaggio Regolare
- riconoscono i linguaggi liberi non inerementemente ambigui
Dimostrabile:
- Per ogni CFG esiste un PDA tale che
- Per ogni PDA esiste una CFG tale che
I DPDA a paritá di stato simbolo letto e simbolo sulla pila possono fare al massimo una mossa.
- deve contenere al massimo un elemento
Mentre il linguaggio non é riconoscibile in quanto fa uso chiave del non determinismo mentre é riconoscibile grazie al simbolo sentinella
- Dim - Ogni linguagio regolare é riconosciuto da un DPDA
- dove
- per ogni
Dimostrabile
- Per ogni DPDA esiste una grammatica libera non ambigua tale che
- Il viceversa non vale
La famiglia dei linguaggi riconoscibili da DPDA é inclusa in - ma non concide con - quella dei linguaggi generabili da grammatiche libere non ambigue
Parser Top-Down
Vedi:Parser Top-Down
Grammatiche Libere
Teorema
Per ogni linguaggio regolare esiste una grammatica tale che
- dove é il linguaggio generato da
- le grammatiche possono generare tutti i linguaggi regolari
- possono anche generare linguaggi non regolari
- stringhe palindrome
- parentesi bilanciate
I linguaggi liberi includono propriamente i linguaggi regolari
LL(1)
Non LL(1)
Fattorizzazione
quindi GUIDA GUIDA
Soluzione Fattorizzare il previsso comune in una variabile a parte
Ricorsione immediata a sinistra
Soluzione Nuova variabile per spostare la ricorsione da sinistra a destra
In generale l’eliminazione della ricorsione a sinistra non garantisce che la grammatica risultante sia LL(1)
Ricorsione indiretta a sinistra
Soluzione
- si impone un ordine arbitrario alle variabili
- considerando ogni variabile nell’ordine imposto si elimina la ricorsione immediata per quella variabile e si riscrivono le occorrenze di quella variabile che compaiono nei corpi delle produzione delle variabili seguenti
Linguaggi
Linguaggio regolare
Esiste almeno un Automa A che lo riconosce
Linguaggi Regolari
def Un Linguaggio riconoscibile da un DFA
-
I linguaggi regolari sono chiusi rispetto all’operazione di unione ‘Collego’ i due automi deterministici attraverso uno stato q0 che con epsilon-transizioni passa da uno o dall’altro
-
I linguaggi regolari sono chiusi rispetto all’operazione di concatenazione ‘Collego’ lo stato finale (che non sara’ piu’ finale) del e-NFA corrispondente al primo automa con quello iniziale di quello e-NFA del successivo, con una epsilon-transizione
-
Chiusura
dimp-- Dati e
- Si dimostra che genera
- Essendo quella ancora un’espressione regolare anche il linguaggio generato sará regolare
- Simile all’unione
- si crea un automa
- abbiamo complementato l’insieme degli stati finali
- i
- Si utilizzano le leggi di De Morgan
- ci si riconduce al caso dell’unione e della complementazione
- O si construisce un automa che riconosce una simulazione dei due automi iniziali e
-
- L rovesciato
- Si ricava un per induzione Facile poi dimostrare che Tutti questi sono ancora regolari
- Dati e
Linguaggi non Regolari
Pumping Lemma
Per ogni linguaggio regolare esiste appartenente a tale che per ogni appartenente a con esistono tc :
- appartiene per ogni Abbiamo una stringa media non vuota che puó essere replicata un numero arbitrario di volte sempre ottenendo un Liguaggio Regolare.
- Esempio
- non é regolare
- Esempio
- dim
-
regolare
-
tc
-
-
tc con
-
Dopo passaggi lo stato deve essere
finaleper definizione -
Il numero di stati attraversati sará
-
implica quindi gli stati attraversati non possono essere tutti distinti
-
( ) é il primo
stato che si ripetenel cammino dell’automa Allora concludiamo identificando -
-
-
- in quanto
- in quanto é il primo stato che si ripete e sono al massimo
- appartiene a per ogni
-
Linguaggi Liberi dal Contesto
Le grammatiche libere sono un approccio generativo alle stringhe non e’ regolare:
- e’ il inguaggio delle parentesi bilanciate
e’ una grammatica libera
- variabili o simboli non terminali
- terminali
- produzioni
- testa
- corpo
- La riscrittura della in (sequenza arbitraria di simboli terminali o non) é libera dal contesto
- simbolo iniziale
Derivazioni:
- derivazione in un solo passo
- derivazione in zero o piu’ passi
Il potere riconoscitivo delle grammatiche libere e’ almeno tanto quanto quello dei linguaggi regolari
Derivazioni canoniche
- leftmost
- rightmost
-
Se esistono due derivazioni canoniche distinte (entrambe
lmorm) per la stessa stringa allora e’ambigua
-
Se esistono due derivazioni canoniche distinte (entrambe
Alberi Sintattici
Derivazioni differenti possono generare lo stesso programma
- anche imponendo regole all’ordine delle riscritture
Gli alberi sintattici (alternativa alle generazioni) astraggono dall’ordine delle riscritture e permettono di ragionare sulla struttura delle stringhe
- grammatiche ambigue
- piú alberi con lo stesso prodotto
- non é avere derivazioni distinte che mi porta ad alberi diversi e quindi ambiguitá
Data una grammatica gli alberi sintattici di :
- ogni nodo etichettato con una var in
- ogni foglia etichettata da o o
- significa unico figlio del genitore
- se un nodo i suoi figli sono etichettati (sx a dx)
- e’ una produzione in
Il prodotto é la stringa ottenuta concatenando(sx verso dx) le etichette di tutte le foglie
-
Teorema se e solo se esiste un albero sintattico di con radice e prodotto
-
Risoluzione delle ambiguitá (grammatiche in forma infissa)
-
Precedenzadegli operatori -
Associativitádegli operatori- per operatori associativi questo non é un problema
- lo é per altri operatori
Soluzione ad hocUtilizziamo associativitá a sinistra, sbilanciamo le espressioni e le stratifichiamo
-
Espressione = somma di termini
-
Termine = prodotto di fattori
-
Fattore = costante o espressione tra parentesi Nuova grammatica: Produzioni:
-
-
-
-
-
Linguaggi inerentemente ambigui
Qualunque Grammatica che genera ha sempre almeno due derivazioni canoniche distinte che generano una stringa della forma
Pumping Lemma
Chiusura
-
Unione & Concatenazione SI dati e dove costruiamo la grammatica che genera e la grammatica che genera
-
Intersezione NO tra 2 Linguaggi Liberi Sono liberi ma Non é libero, dimostrabile con il pumping lemma SI tra linguaggio Libero e linguaggio Regolare NB: L’intersezione non é piú un linguaggio regolare es. e il quale non é regolare
-
Complemento & Differenza NO Se fossero chiusi per complemento allora Contrario a ció dimostrato Il complemento é esprimibile per differenze e quindi nemmeno la differenza é chiusa
-
Inversione SI dove Si dimostra che
JVM
Vedi: IJVM, Bytecode Instruction Listing Progetto: Translator.java
- Interprete
bytecode - macchina virtuale basata su
pila - basso e alto livello (gestione della pila / oggetti)
Garbage Collector
Pipeline del corso: .lft .j .class output
Pila
Composta da Frames
- uno per ogni metodo in esecuzione
NBI metodi non statici hanno come primo argomento il riferimento all’oggetto ricevente
- argomenti e variabili riferite con il loro indirizzo nella pila
Instruction SetGestione della Pila- istore
- iload
- swap Aritmetica
- ineg
- iadd
- isub
- imul Gestione Array
- newarray
- arraylength
- iaload
- iastore Controllo del Flusso
- goto
- ificmpeq
- ificmpne
- ificmple
- ificmpge
- ificmplt
- ifcmpgt
- invokestatic
- return
- ireturn
Espressioni
Aritmetiche
Logiche
Implementazione di Valutazione Corto-Circuitata
Problemi
la compilazione di un metodo comporta il calcolo della dimensione del suo frame
- variabili locali
- pila degli operandi
inoltre deve assicurarsi che se il tipo di ritorno é diverso da void ci sia un valore restituito Questo senza eseguire il codice, utilizzando l’analisi statica del codice Nello sviluppo ci occupiamo di
- metodi statici
- con tipo di ritorno int o void
Verifica del Return
Analisi di ogni cammino per verificare che alla fine di ogni metodo ci sia una istruzione return
- l’analisi é statica in quanto non tiene conto dell’effettivo flusso di esecuzione del metodo
- non garantisce che il return sia eseguito
- in caso di ciclo infinito
- in caso di eccezione
- non garantisce che il return sia eseguito
Vengono fatte delle approssimazioni:
- non sono valutate
espressioni booleaneanche se banali: il problema éindecidibile - non viene controllato se il tipo di ritorno é giusto o meno
- necessita un’altra analisi dei tipi
Questo é implementato con un attributo
S.ret- true se l’espressione di S termina é perché esegue una return
- in caso di liste di Comandi
- l’attributo é determinato dall’OR tra i Comandi che compongono la lista:
- questa informazione puó essere utile per individuare la presenza di codice morto
- warning o errore
- questa informazione puó essere utile per individuare la presenza di codice morto
- l’attributo é determinato dall’OR tra i Comandi che compongono la lista:
Allocazione delle variabili locali
Il piú piccolo numero di slot necessari all’interno di un frame per la memorizzazione di argomenti e variabili locali
- determinare il numero massimio di variabili che sono contemporaneamente attive
- tener conto della localitá delle variabili
Questo é implementato con un attributo
S.locals- max{ S1.locals, S2.locals }
- nel caso di if else o liste di comandi
- max{ S1.locals, S2.locals }
Calcolo dimensione massima della pila
Numero massimo di slot occupati sulla pila degli operandi durante l’esecuzione di un metodo
- tenendo conto del codice prodotto
- approssimare per eccesso la dimensione massima della pila
Implementato con l’attributo stack per E, B, S
E.stack- >= 1
E_list.stack- >= 0
NB L’associativitá a sinistra mantiene la pila piccola perché le sottoespressioni vengono valutate man mano che si incontrano da sinistra verso destra