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

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

Riconoscitori e analizzatori sintattici

Esercitazioni di Linguaggi e Traduttori

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

POLITECNICO DI TORINO. Laboratorio di Compilatori Corso di Linguaggi e Traduttori. Esercitazione 5. a.a 2010 / Controllo dei tipi

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

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

Scopo del progetto è la costruzione di un compilatore per il linguaggio descritto qui di seguito.

Yet Another Compiler-Compiler. Generazione automatica di analizzatori sintattici

Linguaggi e Traduttori: Analisi sintattica

Corso di Linguaggi di Programmazione

Generatori di analizzatori sintattici

Linguaggi di Programmazione

Data una specifica sintassi (come uno grammatica context-free), il parser si occupa di leggere i token e di ragrupparli in strutture linguistiche.

GENERATORI DI ANALIZZATORI SINTATTICI. Generatori di parser

Dispensa YACC. 1.1 YACC: generalità

Linguaggi e Traduttori: Analisi lessicale

Linguaggi e Ambienti di Programmazione

Dispensa YACC: generalità

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

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

Primi passi con JFlex

Linguaggi e Traduttori

Linguaggi e Traduttori: Analisi sintattica

Schema generale parser LR

Unità A1 Funzioni MODULO Java 2

Analizzatori Lessicali con JLex. Giuseppe Morelli

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

Progetto Automi e Linguaggi Parser svliluppato con JLex e cup

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

Parser Bottom UP. Giuseppe Morelli

Corso sul linguaggio Java

Programmazione I - corso B a.a prof. Viviana Bono

INTRODUZIONE ALLA PROGRAMMAZIONE AD ALTO LIVELLO IL LINGUAGGIO JAVA. Fondamenti di Informatica - D. Talia - UNICAL 1. Fondamenti di Informatica

INTRODUZIONE ALLA PROGRAMMAZIONE AD ALTO LIVELLO IL LINGUAGGIO JAVA. Fondamenti di Informatica - Programma

Funzioni, Stack e Visibilità delle Variabili in C

Generareanalizzatori sintattici conbison

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

IL LINGUAGGIO JAVA. Introduzione alla sintassi di Java La sintassi formalizza le regole sintattiche per scrivere frasi ben formate

Alberi. Strutture dati: Alberi. Alberi: Alcuni concetti. Alberi: definizione ricorsiva. Alberi: Una prima realizzazione. Alberi: prima Realizzazione

Traduzione guidata dalla sintassi

JAVA - I/O System. Il JAVA considera tutte i flussi da e verso l esterno, come stream di byte. Questi possono essere di ingresso o di uscita:

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

L intero è o il valore zero o una stringa di cifre che inizia con una cifra diversa sa zero.

Funzioni, Stack e Visibilità delle Variabili in C

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

Fondamenti teorici e programmazione

Grammatiche context-free

Corso di Linguaggi di Programmazione

Semantica e traduzione guidata dalla sintassi (cenni)

Esercitazione n 4. Capacità di analisi e di estensione di progetti esistenti Il concetto di filtro Linguaggio Java:

Pumping lemma per i linguaggi Context-free

Definizioni syntax-directed

Le basi del linguaggio Java

Le classi in java. Un semplice programma java, formato da una sola classe, assume la seguente struttura:

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

Linguaggi e Traduttori Esercitazione di laboratorio N.2 - soluzione

Laboratorio di Programmazione 1. Docente: dr. Damiano Macedonio Lezione 4 24/10/2013

Laboratorio di Informatica I

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

ESECUZIONE DI PROGRAMMI C SU MACCHINE REALI. Docente: Giorgio Giacinto AA 2009/2010

Automi e Linguaggi Formali

Programmazione. Cognome... Nome... Matricola... Prova scritta del 11 luglio 2014

Il Modello di un Compilatore. La costruzione di un compilatore per un particolare linguaggio di programmazione e' abbastanza complessa.

Pumping lemma per i linguaggi Context-free

Elaborazione di documenti XML

Il Modello di un Compilatore. La costruzione di un compilatore per un particolare linguaggio di programmazione e' abbastanza complessa.

Programmazione M.A. Alberti. Comunicazione digitale AA 2009/ Classi in Java 1. Le classi in Java. Oggetti. Classi. Classi. Visibilità dei dati

Automi e Linguaggi Formali

Esempio su strutture dati dinamiche: ArrayList

Linguaggi e Traduttori: Analisi sintattica

Corso di Linguaggi di Programmazione

Analisi sintattica (parser)

Fondamenti di Programmazione Prof.ssa Elisa Tiezzi. Programmazione orientata a oggetti

Corso di Linguaggi di Programmazione

ESECUZIONE DI PROGRAMMI C SU MACCHINE REALI. Docente: Giorgio Giacinto AA 2008/2009. formalizzazione degli algoritmi in linguaggio C

Corso di Linguaggi di Programmazione

COMPILATORI: MODELLO La costruzione di un compilatore per un particolare linguaggio di programmazione è complessa. La complessità dipende dal linguagg

Corso: Fondamenti di Informatica (Canale 5) a.a Corsi di laurea: Ing. Settore Informazione

Linguaggi di Programmazione e Compilatori

Esempio su strutture dati dinamiche: ArrayList

INTRODUZIONE ALLA PROGRAMMAZIONE AD ALTO LIVELLO IL LINGUAGGIO JAVA. Struttura di un programma Java

Linguaggio C: Variabili e assegnamento e semplici comandi di I/O

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

LINGUAGGI DI ALTO LIVELLO

Fondamenti di informatica 2 Claudio Biancalana. Esercitazione capitolo 19 Array

Traduttore diretto dalla sintassi (seconda parte) Giuseppe Morelli

Analisi sintattica e lessicale in Haskell

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

Modulo 2: Strutture fondamentali della programmazione Java

Corso sul linguaggio Java

Alla fine del documento (pagina 10) sono riportate le richieste comuni ai due progetti.

1

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

Analisi lessicale (scanner)

POLITECNICO DI TORINO. Laboratorio di Compilatori Corso di Linguaggi e Traduttori. Esercitazione 1. a.a 2010 / Linguaggi?

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

Transcript:

POLITECNICO DI TORINO Laboratorio di Compilatori Corso di mail: stefano.scanzio@polito.it sito: a.a 2010 / 2011 Riconoscitori e analizzatori sintattici Data una grammatica non ambigua ed una sequenza di simboli in ingresso, un riconoscitore è un programma che verifica se la sequenza appartiene o no al linguaggio i definito it dalla grammatica. Un analizzatore sintattico (parser) è un programma che è in grado di associare alla sequenza di simboli in ingresso il relativo albero di derivazione. Gli algoritmi di analisi possono essere top-down (dalla radice alle foglie) bottom-up (dalle foglie alla radice) : CUP 3 1

Scanning e parsing Ingresso: 3+2= 3*(8-4)= Scanner (JFlex) NUM PIU NUM UG NUM PER TO NUM MENO NUM TC UG Grammatica (G): E ::= E + T E ::= E - T Parser (Cup) Appartiene a G Non Appartiene a G 4 Definizione di grammatica Context-Free Una grammatica CF è descritta da: T, NT, S, PR T: Simboli terminali /T Tokens passati dallo scanner NT: Simboli non terminali Denotano un set di stringhe generate dalla grammatica S: Simbolo distintivo della grammatica S NT Definisce tutte le stringhe possibili della grammatica PR: Regola di produzione Indica come i simboli T e NT sono combinati al fine di generare delle stringhe NT ::= T NT 5 2

Esempio Derivazione: Produzioni (regole grammaticali): assign_stmt ::= ID UG expr PV; expr ::= expr operatore term; expr ::= term; term ::= ID; term ::= REAL; term ::= INT; operator ::= PIU; operator ::= MENO; Una sequenza di regole grammaticali che, applicate, trasformano un simbolo non terminale (NT) in una sequenza di simboli terminali (T) che prendono il nome di tokens 6 Funzionamento di un parser: la tecnica Shift/Reduce Si usa uno stack, inizialmente vuoto, per memorizzare i simboli richiesti dal parser allo scanner. I simboli terminali vengono immessi sullo stack (azione di shift), fino a che la cima dello stack non contiene un handle (parte destra della regola). Quando ciò avviene, l handle viene ridotto (azione di reduce) e sostituto con il simbolo non-terminale relativo. Si ha successo se esaminati tutti i simboli in ingresso, lo stack contiene solo il simbolo distintivo della grammatica. 7 3

Alberi di derivazione e tecnica Shift/Reduce Stringa di ingresso: a1, a2, a3 Scanner: a1, a2, a3 ::= EL VIR EL VIR EL Grammatica Ricorsiva Sinistra List ::= List VIR EL List ::= EL Azione: Stack: Albero di derivazione ε List Shift: EL Reduce: List List Shift: List VIR Shift: List VIR EL List Reduce: List Shift: List VIR EL VIR ELVIR EL Shift: List VIR EL Reduce: List 8 Introduzione a Cup Cup è un generatore di analizzatori sintattici che trasforma la descrizione di una grammatica context-free in un programma Java che riconosce ed analizza la grammatica stessa. Oltre alle regole sintattiche, è possibile specificare quali azioni devono essere eseguite in corrispondenza del riconoscimento dei vari simboli della grammatica. È necessario integrare il parser così generato con un analizzatore lessicale: alcune convenzioni permettono di eseguire l integrazione di Cup con lo scanner JFlex in modo semplificato. Manuale Ufficiale: /risorse/manualecup.html 9 4

Il formato del file di ingresso Il file di ingresso di Cup ha una sintassi molto simile a quella di un programma Java Può essere idealmente diviso i nelle seguenti sezioni: i Setup Terminali e Non Terminali Precedenze (Prossima esercitazione) Regole Possono essere introdotti commenti racchiusi dai simboli /* e */ o preceduti dal simbolo // 10 Sezione di Setup Vengono specificate tutte le direttive utili ad un corretto funzionamento del parser Inclusione della libreria i di Cup e di altre librerie: i import java_cup.runtime.*; Codice utente: (Prossima esercitazione) Ridefinizione di funzioni interne a Cup Integrazione con scanner diversi da JFlex 11 5

Sezione dei Terminali / Non-Terminali Vengono definiti Simbolo distintivo della grammatica Simboli terminali: passati da Jflex Simboli Non-Terminali Simbolo distintivo della grammatica: start with <nome_non_terminale>; Rappresenta la radice dell albero di derivazione E lecita una sola occorrenza di questa parola chiave 12 Sezione dei Terminali / Non-Terminali Simboli Terminali terminal <simbolo_terminale_1>,,<simbolo_terminale_n>; <simbolo_terminale> i l : Un nome formato da lettere, _,. e cifre (non iniziali). I simboli terminali vengono passati da Jflex o da un altro scanner quando richiesti dal parser Simboli Non-Terminali non terminal <simbolo_non_terminale_1>,,<simbolo_non_terminale_n>; <simbolo_non_terminale> : Un nome formato da lettere, _,. e cifre (non iniziali). 13 6

Sezione dei Terminali / Non-Terminali D VL V Va V Va T P ID QO NUMQC PV char * argv [ 10 ] ; Produzioni (regole grammaticali): D ::= T Vl PV VL ::= V VL ::= VL VIR V V ::= P V V ::= Va Va ::= Va QO NUM QC Va ::= ID Stringa di ingresso: char * argv[10]; 14 Sezione dei Terminali / Non-Terminali D VL V V Simbolo distintivo della grammatica start with D; Simboli Non-Terminali non terminal D, VL, V, Va; (NB Il simbolo distintivo della grammatica è un simbolo non terminale) Va Va T P ID QO NUMQC PV char * argv [ 10 ] ; Simboli Terminali terminal T, P, ID, NUM; terminal QO, QC, VIR, PV; (Passati da JFlex) Sequenza di ingresso 15 7

Sezione della Regole La sezione delle regole è costituita da una o più regole del tipo: <simbolo_non_terminale> ::= CorpoDellaRegola ; dove CorpoDellaRegola è una sequenza di 0 o più simboli. Ad ogni regola grammaticale può essere associata un azione racchiusa tra i simboli {: e :} NB. L azione viene effettuata subito prima dell operazione di reduce Es: D ::= T VL PV {: System.out.println( Riconosciuta una dichiarazione di tipo"); :} ; 16 Sezione della Regole (2) Se per un dato non terminale esistono più produzioni, queste possono essere raggruppate tra loro e separate dal carattere Es: funz ::= ; tipo ID TO VL TC PV {: System.out.println( Riconosciuto prototipo funzione"); :} tipo ID TO VL TC GO stmt_list GC {: System.out.println( Riconosciuta funzione"); :} NB: A tutti gli effetti queste due regole è come se fossero due regole separate, quindi se volessi eseguire la stessa azione per entrambe le regole, dovrei scrivere due azioni uguali, una per regola 17 8

Sezione della Regole: Esempio //Sezione dei Terminali / Non-Terminali terminal T, P, ID, NUM, PV, VIR, QO, QC; non terminal D, V, VL, Va; start with D; //Sezione delle regole D ::= T VL PV; VL::= V VL VIR V; V ::= P V Va; Va::= Va QO NUM QC Va; Produzioni (regole grammaticali): D T VL PV VL V VL VL VIR V V PV V Va Va Va QO NUM QC Va ID 18 Integrazione di JFlex e Cup Parser e scanner devono accordarsi sui valori associati ai token (simboli terminali della grammatica) Lo scanner, ogni volta riconosciuto un simbolo terminale lo deve passare al parser Tale simbolo è una classe di tipo Symbol i cui costruttori fondamentali sono i seguenti: public Symbol( int sym_id) public Symbol( int sym_id, int left, int right) public Symbol( int sym_id, Object o) public Symbol( int sym_id, int left, int right, Object o) La classe Symbol si trova nel seguente file dell installazione di cup: java_cup/runtime/symbol.java Quando si dichiara un simbolo terminale per mezzo della parola chiave terminal, Cup associa a tale simbolo un valore intero Contenuti nel file sym.java generato da cup durante la compilazione 19 9

Integrazione di JFlex e Cup Nel caso in cui nel parser siano dichiarati i seguenti simboli terminali: terminal T, P, ID, NUM, PV, VIR, QO, QC; Potranno essere passarli da scanner a parser, quanto il parser li richiede, nel seguente modo: %% %% [a-za-z_][a-za-z0-9_]* {return new Symbol(sym.ID);} \[ {return new Symbol(sym.QO);} \] {return new Symbol(sym.QC);} 20 Integrazione di JFlex e Cup scanner.flex jflex Yylex.java Yylex.class sym.java sym.class parser.cup parser.java parser.class Main.java Main.class 21 10

scanner.flex Modifiche allo scanner List List VIRGOLA EL List EL Includere la libreria di Cup ( java_cup.runtime.* ) nella sezione del codice Attivare la compatibilità con Cup tramite la direttiva %cup nella sezione delle dichiarazioni import java_cup.runtime.*; %% %cup %% [a-z]+ {return new Symbol(sym.EL); }, {return new Symbol(sym.VIRGOLA); } 22 parser.cup Il parser Cup import java_cup.runtime.*; terminal EL, VIRGOLA; non terminal Lista, List; List List VIRGOLA EL List EL start with Lista; Lista ::= List {: System.out.println( Lista riconosciuta correttamente"); :} {: System.out.println( Lista vuota"); :} ; List ::= List VIRGOLA EL ; List ::= EL ; 23 11

Main.java Programma principale: Main import java.io.*; public class Main { static public void main(string argv[]) { try { /* Istanzio lo scanner aprendo il file di ingresso argv[0] */ Yylex l = new Yylex(new FileReader(argv[0])); /* Istanzio il parser */ parser p = new parser(l); /* Avvio il parser */ Object result = p.parse(); parse(); } catch (Exception e) { e.printstacktrace(); } } } 24 Compilazione scanner.flex jflex Yylex.java Yylex.class parser.cup sym.java parser.java sym.class parser.class Main.java Main.class jflex scanner.jflex java java_cup.main parser.cup Nel caso di conflitti shift/reduce o reduce/reduce: java java_cup.main -expect <numero_conflitti> parser.cup java java_cup.maindrawtree parser.cup Può essere usata in laboratorio o installando una versione modificata di cup scaricabile dal sito del corso Lanciando il programma verrà generato anche l albero di derivazione (funzione utilissima per il debugging della grammatica) 25 12

Compilazione scanner.flex jflex Yylex.java Yylex.class parser.cup sym.java parser.java sym.class parser.class Main.java Main.class Yylex.java sym.java parser.java Main.java O semplicemente *.java Per compilare tutti i file del progetto java Main <file> Per eseguire il programma su <file> 26 13