Linguaggi Formali e Compilatori. Premessa



Похожие документы
Dispensa YACC: generalità

LINGUAGGI DI PROGRAMMAZIONE LINGUAGGI DI BASSO LIVELLO

Progetto Automi e Linguaggi Parser svliluppato con JLex e cup

Introduction. The Structure of a Compiler

Question 1: introduction to computer programming

Analizzatore lessicale o scanner

Stored Procedures. Massimo Mecella Dipartimento di Ingegneria informatica automatica e gestionale Antonio Ruberti Sapienza Università di Roma

Implementazione di un Compilatore e di una Macchina Virtuale per la Compilazione e l Esecuzione di un Linguaggio Simple

Fondamenti di Informatica e Laboratorio T-AB T-16 Progetti su più file. Funzioni come parametro. Parametri del main

PROTOTIPAZIONE DI UN TRADUTTORE DA SORGENTE PLC AD ASSEMBLY DI UNA MACCHINA VIRTUALE

Introduzione a Dev-C++

Assembler di Spim. Assembler di SPIM. Struttura di un programma assembler. Direttive

Fondamenti di Programmazione

Codifica: dal diagramma a blocchi al linguaggio C++

Le command line di Java

con ANTLR tesi di laurea Anno Accademico Relatore Ch.mo prof. Porfirio Tramontana Candidato Fabio Canova Matr

Fasi di creazione di un programma

Corso di Informatica (Programmazione) Lezione 6 (31 ottobre 2008)

INFORMATICA 1 L. Mezzalira

Operazioni di input e output in Fortran 90

Cos è un Calcolatore?

Breve introduzione al Javadoc

GDB. The GNU Debugger

Linguaggi e Paradigmi di Programmazione

Corso di Informatica

Principi dell ingegneria del software Relazioni fra

COS È UN LINGUAGGIO? LINGUAGGI DI ALTO LIVELLO LA NOZIONE DI LINGUAGGIO LINGUAGGIO & PROGRAMMA

Sistemi Operativi. Interfaccia del File System FILE SYSTEM : INTERFACCIA. Concetto di File. Metodi di Accesso. Struttura delle Directory

Introduzione alla programmazione in C

Introduzione al MATLAB c Parte 2

Java Server Pages (JSP) JSP o Servlet? Java Server Pages (JSP) Java Server Pages Costituiscono un estensione della tecnologia delle servlet

Descrizione di un algoritmo

Introduzione a GCC: GNU Compiler Collection

ToolChain: Come Generare Applicazioni in Linguaggio Macchina

La prima applicazione Java. Creazione di oggetti - 1. La prima applicazione Java: schema di esecuzione. Gianpaolo Cugola - Sistemi Informativi in Rete


Metodologie di programmazione in Fortran 90

Come ragiona il computer. Problemi e algoritmi

3 - Variabili. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo

Strumenti e metodi per la redazione della carta del pericolo da fenomeni torrentizi

FONDAMENTI di INFORMATICA L. Mezzalira

Modulo. Programmiamo in Pascal. Unità didattiche COSA IMPAREREMO...

Generazione Automatica di Asserzioni da Modelli di Specifica

Reflection in Java. Linguaggi Corso M-Z - Laurea in Ingegneria Informatica A.A

API e socket per lo sviluppo di applicazioni Web Based

Capitolo Quarto...2 Le direttive di assemblaggio di ASM Premessa Program Location Counter e direttiva ORG

Introduzione ai Web Services Alberto Polzonetti

Makefile. Un target in generale e' un file. Usando.PHONY: target specifichiamo a make che il target non e' un file

LINGUAGGI DI PROGRAMMAZIONE

Laboratorio di Programmazione 1. Docente: dr. Damiano Macedonio Lezione 18 31/03/2014

Funzioni. Il modello console. Interfaccia in modalità console

Corso di INFORMATICA 2 (Matematica e Applicazioni)

Laboratorio di Informatica Lezione 2

Un esempio di compilatore realizzato con flex e bison

GERARCHIE RICORSIVE - SQL SERVER 2008

COMPILAZIONE DI UN APPLICAZIONE. 1) Compilare il file (o i file se più d uno) che contengono il testo del programma. compilatore

Stefania Marrara - Esercitazioni di Tecnologie dei Sistemi Informativi. Integrazione di dati di sorgenti diverse

A.A. 2006/2007 Laurea di Ingegneria Informatica. Fondamenti di C++ Horstmann Capitolo 3: Oggetti Revisione Prof. M. Angelaccio

Software di base. Corso di Fondamenti di Informatica

Il Software. Il software del PC. Il BIOS

Una metodologia di progettazione di applicazioni web centrate sui dati

Linguaggi di programmazione

Laboratorio di Informatica

Sistema operativo: Gestione della memoria

Introduzione al Python

Sommario. Definizione di informatica. Definizione di un calcolatore come esecutore. Gli algoritmi.

Corso di Laurea in Matematica. Seminario C/C++ Lorenzo Dusty Costa. Università degli Studi di Milano Dipartimento di Matematica

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica

Dynamic Linking. Introduzione Creazione di una libreria dinamica Uso di una libreria dinamica

Cos'é Code::Blocks? Come Creare un progetto Come eseguire un programma Risoluzione problemi istallazione Code::Blocks Che cos è il Debug e come si usa

Esercitazione 05. Sommario. Packet Filtering [ ICMP ] Esercitazione Descrizione generale. Angelo Di Iorio (Paolo Marinelli)

DISPENSE. sull uso di GRASS e QGIS per l analisi del territorio

Analisi di massima: L utente dovrà inserire un numero limite, e tramite vari calcoli verrà stampato a video la sequenza.

Eclipse - Nozioni Base

Esercitazioni di Progettazione del Software. Esercitazione (Prova al calcolatore del 17 settembre 2010)

Introduzione alla programmazione Java. Dott. Ing. M. Banci, PhD

Il sistema operativo UNIX/Linux. Gli script di shell

Breve introduzione curata da Alessandro Benedetti. Struts2-Introduzione e breve guida

Compilatori GNU in Linux: gcc e g++

Realizzazione di una classe con un associazione

Volumi di riferimento

SARA DHANA. RELAZIONE NEGOZIO A.BASSI a.s.2013/2014

Compilatore risorse display grafico LCD serie IEC-line

Object Oriented Programming

Programmazione Orientata agli Oggetti in Linguaggio Java

Транскрипт:

Corso di Laurea Magistrale in Ingegneria Informatica A.A. 2013-2014 Linguaggi Formali e Compilatori Premessa Le pagine che seguono hanno lo scopo di presentare una sintesi dei principali elementi utili alla realizzazione del tema d anno, che, come è noto, rappresenta il principale oggetto di colloquio e valutazione nel corso dell esame. Nel seguito, perciò, si riportano schemi, figure e brani contenuti nelle letture e nei testi consigliati, oltre che suggerimenti e considerazioni del docente circa i principali aspetti di alcuni temi d anno svolti negli scorsi anni accademici da alcuni studenti. G. Piscitelli pag. 1 di 28

A language translator (or compiler) A language translator (or compiler) is a program which translates programs written in a source language into an equivalent program in an object language. The source language is usually a high-level programming language and the object language is usually the machine language of an actual computer. From the pragmatic point of view, the translator defines the semantics of the programming language, it transforms operations specified by the syntax into operations of the computational model to some real or virtual machine. G. Piscitelli pag. 2 di 28

The phases of a language translator (1/3) Linguaggi Formali e Compilatori: Il tema d anno Lamperti, Università di Brescia G. Piscitelli pag. 3 di 28

The phases of a language translator (2/3) The typical compiler consists of several phases each of which passes its output to the next phase: The lexical phase (scanner) groups characters into lexical units or tokens. The input to the lexical phase is a character stream. The output is a stream of tokens. Regular expressions are used to define the tokens recognized by a scanner (or lexical analyzer). The scanner is implemented as a finite state machine. Lex and Flex are tools for generating scanners: programs which recognize lexical patterns in text. Flex is a faster version of Lex. The parser groups tokens into syntactical units. The output of the parser is a parse tree representation of the program. Context-free grammars are used to define the program structure recognized by a parser. The parser is implemented as a push-down automata. Yacc and Bison are tools for generating parsers: programs which recognize the structure grammatical structure of programs. Bison is a faster version of Yacc. The semantic analysis phase analyzes the parse tree for context-sensitive information often called the static semantics. The output of the semantic analysis phase is an annotated parse tree. Attribute grammars are used to describe the static semantics of a program. This phase is often combined with the parser. During the parse, information concerning variables and other objects is stored in a symbol table. The information is utilized to perform the context-sensitive checking. G. Piscitelli pag. 4 di 28

The phases of a language translator (3/3) Linguaggi Formali e Compilatori: Il tema d anno The intermediate code generator transforms the simplified annotated parse tree into intermediate code using rules which denote the semantics of the source language. The code generator may be integrated with the parser. The intermediate code optimizer applies semantics preserving transformations (machine independent code improvements) to the annotated parse tree to simplify the structure of the tree and to facilitate the generation of more efficient code. The code generator transforms the optimized intermediate code into object code using the target machine intructions. The peep-hole optimizer examines the object code, a few instructions at a time, and attempts to do machine dependent code improvements. In contrast with compilers an interpreter is a program which simulates the execution of programs written in a source language. Interpreters may be used either at the source program level or as an object code for an idealized machine. This is the case when a compiler generates code for an idealized machine whose architecture more closely resembles the source code. G. Piscitelli pag. 5 di 28

Trasformazione del Programma Sorgente Linguaggi Formali e Compilatori: Il tema d anno Le fasi della trasformazione Stessa computazione espressa secondo diversi livelli di astrazione Lamperti, Università di Brescia G. Piscitelli pag. 6 di 28

La trasformazione nell analisi lessicale Analisi lessicale id1 := id2 + 20 * id3 Lamperti, Università di Brescia G. Piscitelli pag. 7 di 28

La trasformazione nell analisi sintattica Linguaggi Formali e Compilatori: Il tema d anno Analisi sintattica Lamperti, Università di Brescia G. Piscitelli pag. 8 di 28

Analisi semantica La trasformazione nell analisi semantica» Rivisitazione dell albero per controllare i vincoli semantici» Eventuale decorazione/alterazione dell albero Lamperti, Università di Brescia G. Piscitelli pag. 9 di 28

La trasformazione nella generazione del codice intermedio Generazione del codice intermedio una istruzione per ogni operatore dell albero sintattico Codice intermedio = programma scritto nel linguaggio di una macchina astratta (virtuale) Proprietà: facile da produrre e da tradurre in codice target Natura: svariata, tipicamente: codice a tre indirizzi (quadruple) Assembler in cui le locazioni di memoria sono assimilabili a registri al più un operatore esplicito (oltre all assegnamento) sequenzializzazione delle operazioni Generazione di temporanei per i risultati intermedi Non necessariamente tre operandi (anche meno, es: toreal) Lamperti, Università di Brescia G. Piscitelli pag. 10 di 28

La trasformazione nell ottimizzazione del codice intermedio Ottimizzazione del codice intermedio Lamperti, Università di Brescia G. Piscitelli pag. 11 di 28

La trasformazione nell ottimizzazione del codice intermedio Generazione di codice Tipo di codice target Mapping Assembler (tipicamente) Macchina rilocabile variabili trasformate in locazioni di memoria istruzioni istruzioni macchina equivalenti variabili registri Lamperti, Università di Brescia G. Piscitelli pag. 12 di 28

Symbol Table Struttura dati contenente informazioni sugli identificatori (catalogo) Deve permettere accesso efficiente agli attributi di un identificatore in lettura scrittura aggiornamento incrementale degli attributi Lamperti, Università di Brescia G. Piscitelli pag. 13 di 28

Gestione Errori fase F gestione degli errori pertinenti ad F Lamperti, Università di Brescia G. Piscitelli pag. 14 di 28

Bootstrapping & Porting L coinvolti nella realizzazione di un compilatore sorgente target implementazione (host) L macchina nei primi compilatori Cross-compilatore: quando Comp(β) gira su macchina target target = Intel Comp(β) su Motorola Lamperti, Università di Brescia G. Piscitelli pag. 15 di 28

LEX / FLEX Lex is a lexical analyzer generator developed at AT&T Bell Laboratories. The input to Lex/Flex is a file containing tokens defined using regular expressions. Lex/Flex produces an entire scanner module that can be compiled and linked to other compiler modules. Lex/Flex generates a file containing the function yylex() which is called from the function yyparse() and returns an integer denoting the token recognized. An input file for Lex is of the form: C and scanner declarations %% Token definitions and actions %% C subroutines first section second section third section G. Piscitelli pag. 16 di 28

%{ #include y.tab.h /* The tokens */ %} DIGIT [0-9] ID [a-z][a-z0-9]* %% Token definitions and actions %% C subroutines An example of first section of FLEX The first section of the Lex file contains the C declaration to include the file (y.tab.h) produced by Bison which contains the definitions of the multi-character tokens. The routine is supposed to return the type of the next token as well as putting any associated value in the global yylval. The function yyparse expects to find the textual location of a token just parsed in the global variable yylloc. So yylex must store the proper data in that variable. The data type of yylloc has the name yyltype. To use Flex with BISON, one specifies the -d option to yacc to instruct it to generate the file y.tab.h containing definitions of all the `%tokens' appearing in the yacc input. The first section also contains Lex definitions used in the regular expressions. In this case, DIGIT is defined to be one of the symbols 0 through 9 and ID is defined to be a lower case letter followed by zero or more letters or digits. G. Piscitelli pag. 17 di 28

C and scanner declarations An example of second section of FLEX (1/2) %% := { return(assgnop); } {DIGIT}+ { return(number); } do { return(do); } else { return(else); } end { return(end); } fi { return(fi); } if { return(if); } in { return(in); } integer { return(integer); } let { return(let); } read { return(read); } skip { return(skip); } then { return(then); } while { return(while); } write { return(write); } {ID} { return(identifier); } [ \t\n]+ /* blank, tab, new line: eat up whitespace */. { return(yytext[0]); } %% C subroutines G. Piscitelli pag. 18 di 28

Riconoscimento di simboli lessicali in un linguaggio di programmazione %{ #include <stdlib.h> #include "def.h" /* IF, THEN, ELSE, ID, NUM, RELOP, LT, LE, EQ, NE, GT, GE */ int lexval; %} delimitatore [ \t\n] spaziatura {delimitatore}+ lettera [A-Za-z] cifra [0-9] id {lettera}({lettera} {cifra}) num {cifra}+ %% {spaziatura} ; if {return(if);} then {return(then);} else {return(else);} {id} {lexval = assegna_id(); return(id);} {num} {lexval = atoi(yytext); return(num);} "<" {lexval = LT; return(relop);} "<=" {lexval = LE; return(relop);} "=" {lexval = EQ; return(relop);} "<>" {lexval = NE; return(relop);} ">" {lexval = GT; return(relop);} ">=" {lexval = GE; return(relop);} %% assegna_id() /* tabella di simboli senza keywords */ { int riga; if((riga=cerca(yytext)) == 0) riga = inserisci(yytext); return(riga); } G. Piscitelli pag. 19 di 28

An example of second section of FLEX (2/2) Linguaggi Formali e Compilatori: Il tema d anno The second section of the Lex file gives the regular expressions for each token to be recognized and a corresponding action. Strings of one or more digits are recognized as an integer and thus the value INT is returned to the parser. The reserved words of the language are strings of lower case letters (upper-case may be used but must be treated differently). Blanks, tabs and newlines are ignored. All other single character symbols are returned as themselves (the scanner places all input in the string yytext). The values associated with the tokens are the integer values that the scanner returns to the parser upon recognizing the token. There is a global variable yylval accessible by both the scanner and the parser and is used to store additional information about the token. G. Piscitelli pag. 20 di 28

The third section of FLEX The third section of the file may contain C code associated with the actions. Compiling the Flex file with the command flex file.lex results in the production of the file lex.yy.c which defines the C function yylex(). On each invocation, the function yylex() scans the input file and returns the next token. G. Piscitelli pag. 21 di 28

Leggere par. 1.1 1.4 1.6 1.7 2.1 (2.1.1 2.1.7) 2.5 (2.5.1 2.5.3) Uso accorto del manuale di BISON Manuale BISON del GNU by Charles Donnelly and Richard Stallman october 23, 2013; Bison Version 3.0.2 Tenere presente Appendix A Bison Symbols Appendix B Glossary G. Piscitelli pag. 22 di 28

Le fasi dell uso di BISON The actual language-design process using Bison, from grammar specification to a working compiler or interpreter, has these parts: 1. Formally specify the grammar in a form recognized by Bison (see Chapter 3 [Bison Grammar Files]). For each grammatical rule in the language, describe the action that is to be taken when an instance of that rule is recognized. The action is described by a sequence of C statements. 2. Write a lexical analyzer to process input and pass tokens to the parser. The lexical analyzer may be written by hand in C or it could also be produced using Flex. 3. Write a controlling function that calls the Bison-produced parser. 4. Write error-reporting routines. To turn this source code as written into a runnable program, you must follow these steps: a) Run Bison on the grammar to produce the parser. b) Compile the code output by Bison, as well as any other source files. c) Link the object files to produce the finished product. G. Piscitelli pag. 23 di 28

I temi d anno da considerare Ricci, Valle SIMPLE compile&execute VM Prendono l esempio (linguaggio SIMPLE) riportato nella lettura consigliata di Anthony A. Aaby (Compiler Construction using Flex and Bison) e, costruendo le due necessarie macchine virtuali, sviluppano l intero compilatore fino all effettiva esecuzione del codice sorgente. Dibitonto, Fiorella, Leoci C dialect analyzer C-Analyzer consente di effettuare l analisi lessicale, sintattica e semantica di un codice scritto nel linguaggio di programmazione C, in particolare in un dialetto del C. La caratteristica saliente è che il software fa uso di NetBeans, un ambiente di sviluppo che ha consentito di realizzare un interessante interfaccia grafica in Java. G. Piscitelli pag. 24 di 28

Campese - da ADA a C Realizzazione del Front-End di un Compilatore dedicato all analisi ed alla traduzione di un linguaggio ADA-like. Il progetto del Compilatore si è articolato nello sviluppo di vari moduli. Interessante è l uso di 6 symbol table (mediante il package uthash- 1.9.3) e di un Traduttore di alto livello che genera codice C. Source File *.ada Error Handler Scanner Parser tokens AST Symbol Tables Semantic Checker aast C Code Generator Error Notifications verbose mode annotate d AST Target File *.c Ambiente Linux - Ubuntu 10.10 Maverick Meerkat, distribuzione in cui sono inclusi i tools di sviluppo Flex e Bison Uthash, scritta da Troy Hanson, è composto da un header file da includere nel sorgente dove utilizzare l Hash Table implementata in C; supporta operazioni di aggiunta, ricerca e rimozione su strutture dati C. G. Piscitelli pag. 25 di 28

Il progetto del Compilatore si è articolato nello sviluppo di vari moduli: un analizzatore lessicale (Scanner); un analizzatore sintattico (Parser); un analizzatore semantico (Semantic Checker); sei Tabelle dei Simboli (Symbol Tables); un Gestore degli errori (Error Handler); un Traduttore di alto livello che genera codice C. Ci sono due modi per compilare ed ottenere l eseguibile finale. Il primo è procedere per passi generando e compilando i singoli file uno per volta ed eseguendo quindi il link dei file-oggetto creati; l altro consiste nell eseguire lo script esistente che contiene una sequenza preimpostata di tutti i comandi precedenti necessari alla creazione dell eseguibile. Chiaramente se si vuole specificare particolari flag, opzioni di compilazione o scegliere il file eseguibile finale, è consigliabile la prima modalità. G. Piscitelli pag. 26 di 28

bison -d parser.y gcc -c parser.tab.c flex scanner.l gcc -c lex.yy.c gcc -o A2C parser.tab.o lex.yy.o -lm In sintesi occorre innanzitutto generare il parser tramite il comando bison -d parser.y dove parser.y è il file che contiene le direttive specificate dalla grammatica del linguaggio; viene usata l opzione -d per istruire BISON della generazione di un file header contenente i codici dei token associati alla grammatica, che sarà incluso e utilizzato dallo scanner. BISON genera quindi il file parser.tab.c contenente il codice C che è in grado di eseguire l analisi sintattica. Si compila il file, gcc -c parser.tab.c e si istruisce il compilatore con l opzione -c a creare il relativo file oggetto. Possiamo ora occuparci della generazione dello scanner con il comando flex scanner.l e relativa compilazione del file lex.yy.c generato da Flex e creazione del file oggetto, gcc -c lex.yy.c G. Piscitelli pag. 27 di 28

A questo punto sono stati ottenuti i file oggetto che devono essere sottoposti ad operazione di linking per la generazione del file eseguibile finale gcc -o A2C parser.tab.o lex.yy.o lm che nello script è chiamato A2C; l opzione -lm indica al compilatore di cercare le funzioni matematiche specificate nel codice. Ottenuto il file eseguibile è pertanto possibile usare il compilatore da linea di comando inserendo il nome del file eseguibile e il percorso del sorgente ADA-like da tradurre. Il compilatore mostrerà a video gli eventuali errori di compilazione e genererà il relativo file di traduzione in codice C, salvandolo nella cartella di lavoro. diagramma a blocchi della generazione del Compilatore parser. y Bison parser.tab.c GC C parser.tab.o Adaprova.ada parser.tab. h GC C A2C scanner.l Flex lex.yy.c E possibile anche utilizzare il Compilatore in modalità verbose, specificando l opzione -v. In questa modalità oltre al classico output il Compilatore mostrerà a video alcuni dei simboli non terminali più significativi che ha riconosciuto nella costruzione dell albero sintattico insieme all arricchimento di attributi semantici che si hanno con le operazioni sulle Symbol Tables. GC C lex.yy.o compiled output G. Piscitelli pag. 28 di 28