Laboratorio di Compilatori

Dimensione: px
Iniziare la visualizzazioe della pagina:

Download "Laboratorio di Compilatori"

Transcript

1 1 3 Analisi lessicale Laboratorio di Compilatori a.a. 1999/2000 Esercitazioni in aula Marco Torchiano Dipartimento di Automatica e Informatica Tel. ( ) torchiano@polito.it Espressioni regolari Lex Espressioni regolari in Lex Azioni associate alle espressioni regolari La struttura di un programma sorgente Lex Il codice generato da Lex Risoluzione delle ambiguità Dipendenza dal contesto Condizioni iniziali Eliminazione dei commenti Il file prodotto Inclusione di file Meccanismi di chiamata e definizione di simboli 2 Contenuti 4 Espressioni regolari Analisi lessicale Analisi sintattica Regole semantiche Controllo dei tipi Ambienti di esecuzione Codici intermedi Tecniche per il parsing Costituiscono un metodo semplice ed efficace per descrivere insiemi di stringhe di caratteri. Opportuni operatori consentono di indicare caratteri classi di caratteri opzionalità exp? ripetizione (0 o più volte) exp * ripetizione (1 o più volte) exp + c o anche c [a,b,c] o [a-c] alternativa exp1 exp2 concatenazione exp1 exp2 ambito di operatori ( exp ) Versione Marco Torchiano 1

2 5 Esempi di espressioni regolari numero intero positivo [0-9]+ numero intero positivo senza 0 inziali [1-9][0-9]* numero intero positivo o negativo ( + - )? [0-9]+ numero in virgola mobile ( + - )? ( ([0-9]+. [0-9]*) ([0-9]*. [0-9]+) ) 7 lex - un generatore di analizzatori lessicali Poiché la trasformazione di espressioni regolari in automi a stati finiti deterministici e la implementazione di questi ultimi sono processi meccanici (e noiosi), spesso si utilizza un generatore automatico di analizzatori lessicali. Lex è un generatore che accetta in ingresso un insieme di espressioni regolari e di azioni associate a ciascuna espressione e produce in uscita un programma che riconosce tali espressioni. gli apici consentono di distinguere un carattere in ingresso ( + ) da un operatore (+). Espressioni regolari Lex Programma C 6 Esercizi 8 Espressioni regolari in Lex Scrivere l espressione regolare che descrive un identificatore nel linguaggio C. Scrivere l espressione regolare di un numero in virgola mobile con eventuale parte esponenziale Come sopra, eliminando zeri iniziali e finali non significativi. Scrivere l espressione regolare di un commento nel linguaggio C. Il commento può contenere i caratteri * e / purché non adiacenti. Le espressioni regolari descrivono sequenze di caratteri ASCII ed utilizzano un certo numero di operatori: \ [ ] ^ -?. * + ( ) $ / { % < > Lettere e numeri del testo di ingresso sono descritti mediante se stessi: l espressione regolare val1 rappresenta la sequenza v a l 1 nel testo di ingresso I caratteri non alfabetici vengono rappresentati in Lex racchiudendoli tra doppi apici, per evitare ambiguità con gli operatori: l espressione xyz ++ rappresenta la sequenza x y z + + nel testo di ingresso. Versione Marco Torchiano 2

3 9 Espressioni regolari in Lex 11 Espressioni regolari in Lex...continua......continua... I caratteri non alfabetici possono essere anche descritti facendoli precedere dal carattere \ l espressione xyz\+\+ rappresenta la sequenza x y z + + nel testo di ingresso. Le classi di caratteri vengono descritte mediante gli operatori []: l espressione [ ] rappresenta una cifra nel testo di ingresso. Nel descrivere classi di caratteri, il segno - indica una gamma di caratteri: l espressione [0-9] rappresenta una cifra nel testo di ingresso. Il carattere di fine riga viene descritto dal simbolo \n. Il carattere di tabulazione viene descritto dal simbolo \t. L operatore? indica l espressione precedente è opzionale: ab?c indica sia la sequenza ac che abc. L operatore * indica l espressione precedente può essere ripetuta 0 o più volte: ab*c indica tutte le sequenze che iniziano per a, terminano per c e hanno all interno un numero qualsiasi di b. 10 Espressioni regolari in Lex 12 Espressioni regolari in Lex...continua......continua Per includere il carattere - in una classe di caratteri, questo deve essere specificato come primo o ultimo della serie: l espressione [-+0-9] rappresenta una cifra o un segno nel testo di ingresso. Nelle descrizioni di classi di caratteri, il segno ^ posto all inizio indica una gamma di caratteri da escludere: l espressione [^0-9] rappresenta un qualunque carattere che non sia una cifra nel testo di ingresso. L insieme di tutti i caratteri eccetto il fine riga (new line) viene descritto mediante il simbolo.. L operatore + indica l espressione precedente può essere ripetuta 1 o più volte: ab+c indica tutte le sequenze che iniziano per a, terminano per c e hanno all interno almeno un b. L operatore indica un alternativa tra due espressioni: ab cd indica sia la sequenza ab che la sequenza cd. Le parentesi tonde consentono di esprimere la priorità tra operatori: (ab cd+)?ef indica sequenze tipo ef, abef, cdddef. Versione Marco Torchiano 3

4 13 Azioni associate alle espressioni regolari continua... Ad ogni espressione regolare è associata in Lex un azione che viene eseguita all atto del riconoscimento. Le azioni sono espresse sotto forma di codice C: se tale codice comprende più di una istruzione o occupa più di una linea deve essere racchiuso tra parentesi graffe. L azione più semplice consiste nell ignorare il testo riconosciuto: si esprime un azione nulla con il carattere. 15 La struttura di un programma sorgente Lex Un file sorgente per lex è composto di tre sezioni distinte separate dal simbolo %%. La prima sezione contiene le definizioni e può essere vuota. La seconda sezione contiene le regole sotto forma di coppie espressione_regolare azione. Le azioni devono iniziare sulla stessa riga in cui termina l espressione regolare e ne sono separate tramite spazi o tabulazioni. La terza sezione contiene le procedure di cui il programmatore intende servirsi: se è vuota, il separatore %% viene omesso. 14 Azioni associate alle espressioni regolari...continua Il testo riconosciuto viene accumulato nella variabile yytext, definita come puntatore a caratteri. Operando su tale variabile, si possono definire azioni più complesse. Il numero di caratteri riconosciuti viene memorizzato nella variabile yyleng, definita come intero. Esiste un azione di default che viene eseguita in corrispondenza del testo non descritto da nessuna espressione regolare: il testo non riconosciuto viene ricopiato in uscita, carattere per carattere. 16 Definizioni continua... Per semplificare la gestione di espressioni regolari complesse o ripetitive, è possibile definire identificatori che designano sotto-espressioni regolari. Ogni riga della prima sezione il cui primo carattere non sia di spaziatura è una definizione: numero [+-]?[0-9]+ La sotto-espressione così definita può essere utilizzata racchiudendone il nome tra parentesi graffe: {numero printf( trovato numero\n ) Versione Marco Torchiano 4

5 17 Definizioni...continua 19 Risoluzione delle ambiguità lessicali Le righe che iniziano con spazio o tabulazione sono ricopiate identiche nel file di codice C generato dall esecuzione di Lex. Lo stesso avviene per tutti i caratteri compresi tra i delimitatori %{ e %. Tutte le righe presenti nella sezione delle procedure (la terza) del programma sorgente sono ricopiate nel file C generato da Lex. Esistono due tipi di ambiguità lessicali: la parte iniziale di una sequenza di caratteri riconosciuta da un espressione regolare è riconosciuta anche da una seconda espressione regolare. La stessa sequenza di caratteri è riconosciuta da due espressioni regolari distinte. Nel primo caso verrà eseguita l azione associata all espressione regolare che ha riconosciuto la sequenza più lunga. Nel secondo caso sarà eseguita l azione associata all espressione regolare dichiarata per prima nel file sorgente di lex. 18 Esercizi 20 Esempio Si scriva un programma LEX che dato in ingresso un programma C ne produca in uscita uno equivalente ma privo dei commenti. Si modifichi il programma dell esercizio precedente in modo che riconosca le direttive #include e, quando le incontra, segnali un errore e termini l analisi. Si tenga conto che: possono comparire degli spazi o tabulazioni, non interessa verificare la correttezza del path: è un controllo che dovrebbe essere effettuato ad un livello superiore. Dato il file %% for format [a-z]+ {return FOR_CMD {return FORMAT_CMD {return GENERIC_ID e la stringa di ingresso format, la procedura yylex ritorna il valore FORMAT_CMD, preferendo la seconda regola alla prima - perché descrive una sequenza più lunga, e la seconda regola alla terza - perché definita prima nel file sorgente. Versione Marco Torchiano 5

6 21 Risoluzione delle ambiguità lessicali 23 Dipendenza dal contesto Date le regole di risoluzione dell ambiguità, è necessario definire prima le regole per le parole chiave e poi quelle per gli identificatori. Il principio di preferenza per le corrispondenze più lunghe può essere pericoloso:.* {return QUOTED_STRING cerca di riconoscere il secondo apice il più lontano possibile: cosi, dato il seguente ingresso first quoted string here, second here riconoscerà 36 caratteri invece di 7. Una regola migliore è la seguente: [^ \n]+ {return QUOTED_STRING Può essere necessario limitare la validità di un espressione regolare all interno di un determinato contesto. Esistono meccanismi diversi per specificare la dipendenza dal contesto destro (cioè ciò che segue la sequenza di caratteri che si sta riconoscendo) rispetto alla dipendenza dal contesto sinistro (ciò che la precede). Fa eccezione la gestione del contesto di inizio e fine riga. 22 Esercizi 24 Contesto di inizio e fine riga Scrivere l espressione regolare di una stringa che possa contenere al proprio interno anche apici purché preceduti dal carattere \. Modificare la regola precedente affinché ritorni una copia della stringa riconosciuta, dopo aver opportunamente rimosso eventuali \ di troppo. Scrivere un programma lex che rimuova i tag da un file in formato HTML sostituendo i tag <P> e <BR> con un a-capo. Il carattere ^ all inizio di un espressione regolare indica che la sequenza descritta deve essere posta all inizio di riga. Ciò significa che o si è posizionati all inizio del file di ingresso o che l ultimo carattere letto è stato un carattere di fine riga. Il carattere $ al termine di un espressione regolare indica che la sequenza descritta deve essere seguita da un carattere di fine riga. Tale carattere non viene incluso nella sequenza riconosciuta, deve essere riconosciuto da un altra regola. Versione Marco Torchiano 6

7 25 Dipendenza dal contesto destro 27 Uso di variabili flag L operatore binario / separa un espressione regolare dal suo contesto destro. Pertanto, l espressione ab/cd indica la stringa ab, ma solo se seguita da cd. I caratteri che formano il contesto destro vengono letti dal file di ingresso ma non introdotti nel testo riconosciuto. A tale scopo viene utilizzato un apposito buffer fornito da Lex. L espressione ab$ è equivalente a ab/\n. Per esprimere la dipendenza dal contesto sinistro è possibile utilizzare variabili flag nelle azioni delle regole. Tali variabili devono essere state precedentemente dichiarate come variabili globali. La funzione REJECT può essere utilizzata per evitare corrispondenze non volute: redirige lo scanner alla seconda miglior regola che riconosce lo stesso input, oppure ad una regola che riconosca un prefisso dello stesso input. 26 Dipendenza dal contesto sinistro 28 Esempio È utile poter avere diversi insiemi di regole lessicali da applicare in porzioni diverse del file di ingresso, in genere in funzione di ciò che precede, ovvero del contesto sinistro. Esistono tre approcci distinti per affrontare il problema: uso di variabili flag. uso di condizioni iniziali sulle regole o stati. uso congiunto di più analizzatori lessicali. Il seguente programma gestisce pseudo-commenti del tipo // $var+ int flag=0 %% // {flag=1 /* begin of comment */ \n {flag=0 /* \n terminates comment */ /* ignore blanks*/ \t /* and tabs */ \$[a-za-z]+[-+] { if(flag==1) process(yytext) else REJECT... other rules Versione Marco Torchiano 7

8 29 Uso di condizioni iniziali sulle regole (stati inclusivi) 31 Esempio Le regole la cui espressione regolare inizia con <state> sono attive solo quando l analizzatore si trova nello stato state. Gli stati possibili devono essere definiti nella sezione delle dichiarazioni mediante la parola-chiave %s. Lo stato di default è lo stato 0 o INITIAL. Si entra in uno stato quando viene eseguita l azione BEGIN(state) Il seguente programma gestisce pseudo-commenti del tipo // $var+ %s comment %% <comment>\$[a-za-z]+[-+] {process(yytext) // {BEGIN(comment) \n {BEGIN(INITIAL) /* ignore blanks*/ \t /* and tabs */... other rules 30 Uso di condizioni iniziali sulle regole (stati inclusivi) continua 32 Uso congiunto di più analizzatori lessicali (stati esclusivi) Quando uno stato viene attivato, le regole dello stato si aggiungono (or-inclusivo) alle regole base dell analizzatore. Tale stato rimane attivo fino a che non se ne attiva un altro. Per tornare alla situazione iniziale si deve eseguire il comando BEGIN(0) oppure BEGIN(INITIAL) Una regola può essere preceduta dal nome di più stati, separati da virgola, per indicare che tale regola è attiva in ciascuno di essi. È possibile raggruppare un insieme di regole all interno di uno stato esclusivo. Quando l analizzatore si trova in uno stato esclusivo: le regole di default risultano disabilitate, sono attive solo le regole esplicitamente attivate nello stato. In tal modo è possibile specificare dei minianalizzatori che esaminano porzioni particolari del flusso di caratteri in ingresso, quali ad esempio i commenti o le stringhe. La parola chiave %x introduce uno stato esclusivo. Versione Marco Torchiano 8

9 33 Eliminazione dei commenti 35 Esercizi Un possibile approccio all eliminazione dei commenti del linguaggio C: %% "/*" { int c for ( ) { while ((c = input())!='*' && c!= EOF ) /* eat up text of comment */ if ( c == '*') { while ((c=input())=='*') if ( c == '/' ) break /* found the end */ if ( c == EOF ) { error( "EOF in comment" ) break Si modifichi il programma precedente affinché consenta l eliminazione di commenti annidati. Si estenda il programma precedente in modo che gestisca anche possibili pseudo-commenti della forma $var[+-] Al programma precedente aggiungere l eliminazione di commenti brevi, introdotti dal simbolo // e terminati dal carattere di fine riga. 34 Eliminazione dei commenti Questo è un analizzatore che riconosce e scarta commenti del linguaggio C, mantenendo un conteggio del numero della riga di ingresso. int line_num = 1 %x comment %% \n ++line_num "/*" BEGIN(comment) <comment>[^*\n]* <comment>"*"+[^*/\n]* <comment>\n ++line_num <comment>"*"+"/" BEGIN(INITIAL)... altre regole 36 La struttura del programma generato da Lex Lex produce un programma C, privo di main() il cui punto di accesso è dato dalla funzione int yylex(). Tale funzione legge dal file yyin e ricopia sul file yyout il testo non riconosciuto. Se non specificato diversamente nelle azioni (tramite l istruzione return), tale funzione termina solo quando l intero file di ingresso è stato analizzato. Al termine di ogni azione l automa si ricolloca sullo stato iniziale pronto a riconoscere nuovi simboli. Versione Marco Torchiano 9

10 37 Ingresso e uscita 39 Il file prodotto continua Per default, i file yyin e yyout sono inizializzati rispettivamente a stdin e stdout. Il programmatore può alterare questa situazione reinizializzando tali variabili globali. Negli analizzatori costruiti tramite il programma flex, per motivi di efficienza, vengono letti blocchi di caratteri dal file di ingresso invece che singoli valori. Questo comportamento può essere modificato alterando la definizione della macro YY_INPUT. Tale macro è definita come segue: YY_INPUT(buf,result,max_size) Essa pone nel vettore di caratteri buf un blocco la cui lunghezza è compresa tra 1 e max_size. La variabile intera result contiene il numero di caratteri letti oppure la costante YY_NULL per indicare la fine del file di ingresso. 38 Il file generato 40 Il file prodotto continua yylex() 1 2 inizializzazione del file yyin (default=stdin) scansione del file di ingresso azione esegue return elaborazione del simbolo trovato EOF yywrap() altri file? 3 si reinizializzazione del file yyin no fine dell analisi Per far avvenire la lettura un carattere alla volta si può utilizzare il codice seguente: %{ #undef YY_INPUT #define YY_INPUT(buf,result,max_size) \ { \ int c = getchar() \ result = (c == EOF)? YY_NULL : (buf[0] = c, 1) \ % Questo non si deve fare per gli analizzatori scritti con Lex, in cui la routine input() richiama direttamente la routine getchar(). Versione Marco Torchiano 10

11 41 Il file prodotto continua 43 Inclusione di file Quando l analizzatore incontra la fine del file di ingresso, chiama la funzione yywrap(). Se essa ritorna il valore 0, Lex assume che il file yyin sia stato re-inizializzato e procede con l analisi. Altrimenti, l analizzatore assume che non ci siano altri file da scandire e ritorna al chiamante restituendo il valore 0. La funzione yywrap() può essere usata per stampare tabelle e statistiche circa l analisi appena terminata. Su molti sistemi, per default, yywrap() restituisce sempre il valore 1. Negli analizzatori generati tramite il programma flex, dove il testo in ingresso è fortemente bufferizzato, è necessario adottare alcuni accorgimenti per sospendere l elaborazione del file di ingresso al fine di scandire il contenuto di un secondo file che si intende includere nel primo. Per gestire questo tipo di situazioni, viene fornito un meccanismo per creare ed attivare nuovi buffer di ingresso. 42 Regole di fine file 44 Inclusione di file continua La regola speciale <<EOF>> introduce le azioni da intraprendere alla fine del file quando yywrap restituisce non-zero. Con tale azione è possibile passare ad un altro file o terminare l esecuzione. Questa regola può essere utile unitamente alle start condition per intercettare simboli con delimitatori non bilanciati: \ { BEGIN(quote)... <quote><<eof>> { error( EOF in string ) La funzione YY_BUFFER_STATE yy_create_buffer(file *file, int size) crea un nuovo buffer, di dimensione size, relativo al file file. La funzione void yy_switch_to_buffer(yy_buffer_state new_buf) sostituisce il buffer attuale di ingresso con il buffer new_buf. Si cancella un buffer con la chiamata void yy_delete_buffer( YY_BUFFER_STATE buf) Versione Marco Torchiano 11

12 45 Inclusione di file continua 47 Inclusione di file continua Esempio di analizzatore che elabora file inclusi con annidamento. %x incl %{ #define MAX_INCLUDE_DEPTH 10 YY_BUFFER_STATE include_stack[max_include_depth] int include_stack_ptr = 0 % %% include [a-z]+ [^a-z\n]*\n? BEGIN(incl) ECHO ECHO %% int yywrap() { if ( --include_stack_ptr < 0 ) return(1) else { yy_switch_to_buffer( include_stack[include_stack_ptr]) return(0) 46 Inclusione di file continua 48 Uso della funzione yylex() <incl>[ \t]* /* eat the whitespace */ <incl>[^ \t\n]+ {/* process filename */ if (include_stack_ptr>=max_include_depth) { fprintf( stderr, "Nesting too deep" ) exit( 1 ) include_stack[include_stack_ptr++]= YY_CURRENT_BUFFER yyin = fopen( yytext, "r" ) if (! yyin ) error(... ) yy_switch_to_buffer( yy_create_buffer(yyin,yy_buf_size)) BEGIN(INITIAL) Per un normale uso all interno di un compilatore, è opportuno che la funzione yylex() restituisca il controllo ogni volta che incontra un identificatore. A tale scopo è necessario assegnare a ciascuna classe di simboli che si intende riconoscere un opportuno valore. Poiché tale valore deve essere conosciuto anche dal riconoscitore sintattico, è pratica comune creare un file di definizioni dei simboli del linguaggio ed includere tale file nella sezione delle dichiarazioni. I valori assegnati sono interi, in genere > 256. Versione Marco Torchiano 12

13 49 Lex: parametri ed opzioni 51 Grammatiche context free continua... Lex viene invocato con la seguente sintassi: lex [opzioni] file.lex Si ottiene come risultato il file lex.yy.c. Tra le opzioni, le più comuni sono: -t copia il programma generato su stdout, -v stampa una statistica circa il programma compilato, -p stampa informazioni sulle performance dello scanner, -ooutput genera il file output invece di lex.yy.c, -B(-I) genera uno scanner Batch (Interattivo), -f ottimizza le prestazioni dello scanner, -i genera uno scanner case insensitive, -d attiva i messaggi di debug nello scanner. Il concetto di ricorsione è fondamentale nella scrittura di grammatiche context-free. È lo strumento per descrivere delle sequenze lunghe a piacere. Lista (grammatica ricorsiva sinistra) : List List, Element List =Element Lista (grammatica ricorsiva destra) : List Element Tail Tail == ==, Element Tail Tail == ==ε 50 Linguaggi CF e Riconoscitori 52 Alberi di derivazione Grammatiche CF Alberi di derivazione Ambiguità Parser bottom-up Introduzione a YACC Definizione dei simboli Codifica della grammatica Integrazione con l analizzatore lessicale Formato del programma prodotto da YACC Ambiguità e conflitti Conflitti shift-reduce e reduce-reduce Definizione di operatori e gestione delle priorità in YACC Gestione degli errori sintattici Data una sequenza di simboli che appartiene al linguaggio definito da una data grammatica, è possibile definire l albero di derivazione dell espressione nel seguente modo: la radice dell albero è il simbolo iniziale della grammatica ciascun nodo dell albero è etichettato con un simbolo della grammatica le foglie dell albero sono etichettate con simboli terminali la sequenza delle foglie, lette da sinistra a destra, corrisponde alla sequenza di ingresso un nodo n domina una sequenza ordinata di nodi n 1,..., n m, se e solo se la grammatica contiene la regola n n 1... n m Versione Marco Torchiano 13

14 53 Alberi di derivazione 55 Ambiguità List List, el List =el List List List el, el, el List el Tail Tail == ==, el Tail Tail == ==ε List Tail Tail el, el, el Tail ε Una grammatica si dice ambigua se esiste almeno una sequenza di simboli del linguaggio per cui esistono due o più alberi di derivazione distinti. Esercizio: trovare gli alberi di derivazione per if (i=1) then if (j=2) then a:=0 else a:=1 data la grammatica: S I I if C then I I if C then I else I I =var := E C ( E = E ) E algebric expression 54 Costrutti Pascal-like 56 Espressioni algebriche Un frammento di programma di un linguaggio simile al Pascal può essere definito dalle seguenti regole: P begin Is end. Is Is I ε I if C then I else I I while C do I I repeat Is until C I == ==var := E I == == begin Is end C E Op E Op = > < >= <= ~= E algebric expression La grammatica che descrive le espressioni algebriche è context-free ed usa la ricorsione: S E E E + T E E - T E T T T * F T T / F T F F ( E ) F number Versione Marco Torchiano 14

15 57 Esempio 59 Separatori e terminatori I simboli T e F della grammatica algebrica servono a togliere l ambiguità sulla priorità degli operatori + e - rispetto agli operatori * e /. La grammatica per i costrutti del tipo if-then-else può essere resa non ambigua come segue: I =I 1 I 1 if C then I 1 I 1 if C then I 2 else I 1 I 1 =I 3 I 2 if C then I 2 else I 2 I 2 =I 3 I 3 =var := E Una lista, eventualmente vuota, di identificatori separati da List id_list List ε id_list id_list id id_list id Una lista, eventualmente vuota, di identificatori terminati da List List id List ε List List id List id List ε 58 Esercizi Scrivere due grammatiche di liste di 0 o più identificatori aventi l una come terminatore, l altra come separatore. Scrivere una grammatica non ambigua che descriva le espressioni logiche e che assegni l opportuna priorità agli operatori and, or e not. Costruire la grammatica per i test con un delimitatore alla fine del costrutto e verificare che non è ambigua sull esempio: if C then if C then A end else A end 60 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 definito 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). Versione Marco Torchiano 15

16 61 Riconoscitori Bottom-Up 63 La tecnica shift-reduce continua Il problema principale di un analizzatore top-down è decidere quale produzione deve essere usata per espandere un dato simbolo non terminale. Nei riconoscitori bottom-up il problema è capire quando si sono incontrati tutti i simboli del lato sinistro di una produzione così da poterli sostituire con il relativo non terminale. Il problema diventa più complesso se la grammatica non è ε-free. Se la grammatica è LR(k) si può usare un analizzatore shift-reduce. Per un corretto funzionamento bisogna: comprendere quando si è raggiunta la fine di un handle determinare la lunghezza dell handle decidere quale non terminale sostituire all handle nel caso in cui ci siano più produzioni con lo stesso lato destro. Si risolve il problema definendo un insieme di stati del parser e calcolando due tabelle Action Table: dice quale azione deve eseguire il parser (shift, reduce, terminate, error) in funzione dello stato corrente. Goto Table: descrive in quale stato deve portarsi il parser. Il modo con cui vengono calcolati stati e tabelle porta a soluzioni diverse, sia in termini di complessità che di completezza. 62 La tecnica shift-reduce continua 64 LALR(1) Si usa uno stack, inizialmente vuoto, per memorizzare i simboli già riconosciuti. La sequenza dei simboli sullo stack, seguita dai simboli in ingresso non ancora trattati costituisce sempre una forma sentenziale destra (se l input è corretto). I token vengono immessi sullo stack (azione di shift), fino a che la cima dello stack non contiene un handle: quando ciò avviene, l handle viene ridotto (reduce) con il non-terminale relativo. Si ha successo se esaminati tutti i simboli in ingresso, lo stack contiene solo il simbolo distintivo della grammatica. S. exp 0 2 exp S exp. exp. exp + T exp exp. + T + exp. T exp. NUM exp exp +. T 4 NUM NUM T T NUM. 1 exp exp + T. 5 T S exp T. 3 :: exp exp :: exp '+' '+' T T T :: NUM Versione Marco Torchiano 16

17 65 LALR(1) 67 LALR(1) T 5 exp NUM T 0 NUM NUM + NUM shift, go to state 1 eof T 5 exp NUM T 0 NUM NUM + NUM reduce ( exp T ) 0 exp eof 1 0 NUM + NUM eof exp T NUM 2 0 NUM + NUM eof 66 LALR(1) 68 LALR(1) T 5 exp NUM T 0 NUM NUM + NUM reduce ( T NUM ) 0 T eof T 5 exp NUM T 0 NUM NUM + NUM shift, go to state 4 eof T NUM 3 0 NUM + NUM eof exp T NUM NUM + NUM eof Versione Marco Torchiano 17

18 69 LALR(1) exp T NUM NUM 4 1 T 5 exp T NUM NUM + NUM shift, go to state 1 NUM + NUM eof eof 71 LALR(1) 2 exp 0 T 3 + NUM NUM 4 1 T 5 exp exp T T NUM + NUM NUM + NUM reduce ( exp exp + + T ) exp NUM + NUM eof eof 70 LALR(1) 2 exp 0 T 3 + NUM NUM 4 1 T 5 exp T T NUM NUM NUM + NUM reduce ( T NUM ) 4 2 T 0 NUM + NUM eof eof 72 Introduzione a Yacc Yacc è un generatore di analizzatori sintattici che trasforma la descrizione di una grammatica contextfree LALR(1) in un programma C 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 ne semplificano sensibilmente l integrazione con lo scanner generato da Lex. Versione Marco Torchiano 18

19 73 Il formato del file di ingresso 75 Dichiarazioni continua Il file di ingresso su cui opera Yacc è formato da tre sezioni: le dichiarazioni, le regole, le procedure Le sezioni sono separate dal simbolo %% La prima e l ultima sezione possono essere vuote. Se l ultima sezione è vuota, il secondo separatore può essere omesso. Possono essere introdotti commenti racchiusi dai simboli /* e */. La parola chiave %token definisce una lista di nomi di terminali, separati tra loro da uno o più spazi. Tale parola chiave può comparire più volte in questa sezione. I letterali non sono dichiarati. La parola chiave %start definisce il simbolo distintivo della grammatica. È lecita una sola occorrenza di questa parola chiave. Non è necessario dichiarare i simboli non terminali - tranne quando si vuole associare loro un valore semantico. 74 Dichiarazioni 76 Codifica della grammatica Un file Yacc inizia con la sezione delle dichiarazioni. In essa vengono definiti i simboli terminali, il simbolo distintivo della grammatica, le regole di associatività e precedenza tra gli operatori, alcune informazioni semantiche, codice C racchiuso tra i simboli %{ e %. I simboli non terminali della grammatica sono nomi: un nome è formato da lettere, _,. e cifre (non iniziali). I simboli terminali sono nomi o letterali: un letterale è un singolo carattere racchiuso tra apici. La sezione delle regole è costituita da una o più regole del tipo: NonTerminale : CorpoDellaRegola dove NonTerminale è un nome, e CorpoDellaRegola è una sequenza di 0 o più nomi o letterali. Se per un dato non terminale esistono più produzioni, queste possono essere raggruppate tra loro e separate dal carattere. Versione Marco Torchiano 19

20 77 Esempio 79 Formato del programma generato %token integer %start Expression %% Expression Term Factor : Expression + Term Term : Term * Factor Factor : integer ( Expression ) Il parser generato fa capo alla funzione int yyparse() Tale funzione ritorna 1 se è stato incontrato un errore nel testo in ingresso, altrimenti ritorna il valore 0. Bisogna definire il corpo per la funzione void yyerror(char *) che viene invocata quando si incontra un errore. Inoltre, il programma generato non contiene il main(), che deve essere definito dal programmatore. 78 La sezione delle procedure Tutto ciò che segue il secondo delimitatore %% forma la sezione delle procedure. Questa porzione di file viene ricopiata tale e quale in uscita. All interno di tale sezione vengono comunemente posti: le procedure semantiche usate nel corso dell analisi, l analizzatore lessicale, il corpo principale del programma. 80 Integrazione con l analizzatore lessicale Il parser generato presuppone l esistenza di una funzione che realizzi l analisi lessicale. Tale funzione deve restituire un numero intero positivo che definisce il token letto oppure 0, se è stata raggiunta la fine del file di ingresso. La funzione di analisi lessicale è così definita: int yylex() Il valore semantico, eventualmente associato al simbolo terminale, deve essere memorizzato nella variabile yylval. Tale variabile è allocata all interno di Yacc. Versione Marco Torchiano 20

21 81 Integrazione con l analizzatore lessicale continua Parser e scanner devono accordarsi sui valori associati ai token. Tali valori possono essere scelti da Yacc o dal programmatore. I terminali introdotti come letterali sono associati al codice ASCII del carattere. Quando si introduce un terminale per mezzo della parola chiave %token, yacc associa a tale simbolo un valore intero maggiore di 256, mediante il costrutto #define del pre-processore C. Se il nome del token è seguito da un numero intero, esso viene interpretato come valore da associare al token stesso. 83 Esempio: inclusione del sorgente language.y #include lex.yy.c language.l Lex Lex Yacc lex.yy.c y.tab.c #include lex.yy.c include cc cc parser.obj 82 Integrazione con l analizzatore lessicale continua 84 Integrazione con l analizzatore lessicale continua Si possono integrare i programmi generati da Lex e da Yacc in due modi: in fase di compilazione in fase di link. Nel primo caso, il file C prodotto da Lex (il file lex.yy.c ) viene incluso nel programma generato da Yacc mediante la direttiva #include posta nella sezione delle procedure. Ciò rende le definizione dei token visibili direttamente in fase di compilazione. Nel secondo caso, si chiede a Yacc (mediante l opzione -d ) di generare un file ( y.tab.h ) che contiene le definizioni dei token. Tale file deve essere incluso dallo scanner in modo che siano definiti i valori dei simboli. Di conseguenza, il file lex.yy.c, prodotto da Lex, può essere compilato dopo aver generato y.tab.c e y.tab.h tramite Yacc. Scanner e parser vengono quindi compilati separatamente ed integrati in fase di link. Versione Marco Torchiano 21

22 85 Esempio: compilazione separata 87 Conflitti shift-reduce language.y Yacc #include y.tab.h language.l -d -d y.tab.h Lex Lex y.tab.c include cc cc cc cc scanner.obj #include y.tab.h lex.yy.c parser.obj S then E if then E if Top of Stack 1) S ==if E then S 2) S ==if E then S else S 3) S ==var = E Il prossimo simbolo in ingresso è else. Possono succedere due cose: ridurre le prime quattro voci dello stack, secondo la produzione 1 introdurre else nello stack secondo quanto previsto dalla produzione 2. In queste situazioni, Yacc decide, in mancanza di altri suggerimenti, di eseguire lo shift. 86 Ambiguità e conflitti in Yacc 88 Conflitti reduce-reduce Se la grammatica è ambigua, o se non è LALR(1), possono verificarsi dei conflitti. Ciò significa che l analizzatore deve scegliere tra più azioni alternative plausibili. Il problema viene, di solito, risolto modificando la grammatica per renderla non ambigua oppure fornendo indicazioni a Yacc su come comportarsi in caso di ambiguità. La seconda ipotesi richiede una comprensione adeguata dell algoritmo di analisi, per evitare di generare comportamenti scorretti. b a Top of Stack 1) S ==a B 2) S ==B 3) B ==a b 4) B == b Il prossimo simbolo in ingresso è $. Possono succedere due cose: ridurre le prime due voci dello stack, secondo la produzione 3 ridurre la prima voce secondo quanto previsto dalla produzione 4. In queste situazioni, Yacc decide, in mancanza di altri suggerimenti, di ridurre la regola che è stata definita per prima (la n 3). Versione Marco Torchiano 22

23 89 Definizione degli operatori e gestione delle priorità In certi casi la grammatica può essere resa volutamente ambigua al fine di limitare il numero delle regole. È necessario però fornire indicazioni sulla risoluzione delle ambiguità. Un caso tipico è dato dalle espressioni algebriche: 1) E == ==E + E 2) E == ==E * E 3) E == == ( E ) 4) E == ==integer Questa grammatica è fortemente ambigua. 91 Regole di risoluzione dell ambiguità Ad ogni regola che contiene almeno un terminale definito come operatore, Yacc associa la precedenza ed l associatività dell operatore più a destra. Se la regola è seguita dalla parola chiave %prec, la precedenza e l associatività sono quelle dell operatore specificato. In caso di conflitto shift-reduce, viene favorita l azione adatta alla regola con la precedenza maggiore. Se la precedenza è la stessa, si usa l associatività: sinistra implica reduce, destra shift. 90 Operatori La regola 1 (così come la 2) è ambigua in quanto non specifica l associatività dell operatore + ( * ). Inoltre le regole 1 e 2 non specificano la precedenza tra gli operatori + e *. E possibile suggerire a Yacc come comportarsi aggiungendo due informazioni nella sezione delle dichiarazioni. La parola chiave %left introduce un operatore associativo a sinistra, %right introduce un operatore associativo a destra, %nonassoc introduce un operatore non associativo. L ordine con cui gli operatori sono dichiarati è inverso alla loro priorità. 92 Esempio %token integer %left + - /* lowest priority */ %left * / %left uminus /* highest priority */ %% E : E + E E - E E * E E / E - E %prec uminus ( E ) integer Versione Marco Torchiano 23

24 93 Gestione degli errori sintattici continua Gestione degli errori sintattici...continua... In genere quando un parser incontra un errore non dovrebbe terminare brutalmente l esecuzione Un compilatore in genere cerca di provvedere alla situazione per poter analizzare il resto del file, in modo da segnalare il maggior numero possibile di errori Per default, un parser generato da YACC, quando incontra un errore: segnala, tramite yyerror(), un parse error restituisce il valore 1 Il comportamento di default può essere accettabile per un semplice parser interattivo. Quando il parser generato da Yacc incontra un errore, comincia a svuotare lo stack fino a che incontra uno stato in cui il simbolo error è lecito. Fa lo shift del simbolo error. Se il precedente simbolo di look-ahead è accettabile procede nell analisi. Altrimenti il parser continua a leggere e scartare simboli finché non ne trova uno accettabile 94 Gestione degli errori sintattici...continua Gestione degli errori sintattici...continua... Il simbolo predefinito error indica una condizione di errore. Esso può essere usato all interno della grammatica per consentire al parser di riprendere l esecuzione dopo un eventuale errore. stmts : /* empty statement */ stmts \n stmts exp \n stmts error \n Una semplice strategia per la gestione degli errori è quella di saltare lo statement corrente: stmt : error A volte può essere utile recuperare un delimitatore di chiusura corrispondente ad uno di apertura: primary : ( expr ) ( error ) Versione Marco Torchiano 24

25 97 Gestione degli errori sintattici...continua 99 Definizioni Guidate dalla Sintassi Le strategie di recupero degli errori si basano su scommesse quando si perde la scommessa il rischio è che un errore sintattico ne produca altri spuri. Per limitare la proliferazione di errori spuri, dopo il riconoscimento di un errore, la segnalazione è sospesa finché non vengono shiftati almeno tre simboli consecutivi. È possibile riattivare immediatamente la segnalazione degli errori utilizzando la macro yyerrok. Sono una generalizzazione delle grammatiche context-free. Ad ogni simbolo viene associato un insieme di attributi: sintetizzati: calcolati in base al valore degli attributi dei figli di un nodo nell albero di derivazione, ereditati: calcolati in base al valore degli attributi dei nodi fratelli e del nodo padre nell albero di derivazione, Ad ogni produzione viene associato un insieme di regole semantiche che specificano come vengono calcolati gli attributi. 98 Regole semantiche 100 Attributi sintetizzati Traduzione guidata dalla sintassi La semantica in YACC Definizione di valori semantici Calcolo di attributi sintetizzati Sintesi di attributi in Lex Calcolo di attributi ereditati Trasformazione delle grammatiche Gestione degli errori semantici Abstract Syntax Tree Se una definizione guidata dalla sintassi usa solo attributi sintetizzati è detta definizione ad attributi S. È possibile calcolare i valori degli attributi di una definizione ad attributi S bottom-up, dalle foglie alla radice dell albero di derivazione. E E 1 + T E.value = E 1.value + T.value E T E.value = T.value T number T.value = number.value Versione Marco Torchiano 25

26 101 Attributi ereditati 103 La semantica in Yacc continua... Sono utili per esprimere la dipendenza di costrutti di un linguaggio dal contesto in cui si trovano. D L : T L.type = T.type L L 1, id L 1.type = L.type new_var(id.name,l.type) L id new_var(id.name,l.type) T integer T.type = type_int Accanto allo stack che contiene i simboli sintattici, c è un secondo stack che contiene i valori semantici ad essi associati. Ad ogni regola può essere associata un azione da eseguirsi ogni qualvolta la regola è applicata nel processo di analisi. Tale azione provvede ad aggiornare i valori semantici associati a ciascun simbolo. Un azione è composta da una o più istruzioni di codice C racchiuse tra i simboli { e, ed è posta (di norma) al termine della regola. 102 Attributi L 104 La semantica in Yacc...continua L ordine di valutazione degli attributi dipende dall ordine con cui vengono creati o visitati i nodi dell albero di derivazione. Comunemente i parser seguono l ordine di una visita in profondità dell albero. Una grammatica è detta ad attributi L se è possibile il calcolo dei valori degli attributi con una visita in profondità dell albero di derivazione. In tali grammatiche si ha una propagazione delle informazioni da sinistra a destra (dell albero di derivazione). All interno di ogni azione, si fa riferimento ai valori semantici associati ai successivi simboli del lato destro della regola mediante i nomi $1, $2, $3,... Il valore semantico associato al simbolo del lato sinistro della regola è indicato dal nome $$. Il traduttore generato da Yacc associa ad ogni regola che non contiene un azione esplicita la seguente azione di default: { $$ = $1 Versione Marco Torchiano 26

27 105 Esempio Data la grammatica delle espressioni algebriche, la regola seguente associa al simbolo E la somma o la sottrazione dei valori degli addendi/sottraendi: E : E + T { $$ = $1 + $3 E - T { $$ = $1 - $3 Un azione può contenere istruzioni qualsiasi, anche facenti riferimento a variabili globali: A : B C D { printf( %d\n,i) 107 Esempio Func ha due attributi: un intero ed un puntatore a carattere. I simboli E, T ed F hanno un solo attributo di tipo reale, Args un solo attributo di tipo intero. %{ typedef struct _function_desc { int arg_number char *name function_desc % %union { function_desc function float expression char * id int other %type <expression> E T F %type <function> Func %type <other> Args %% /*... rules here... */ 106 Tipi dei valori semantici 108 Calcolo di attributi sintetizzati Per default, ad ogni simbolo viene associato un solo attributo di tipo intero. Ciò può essere cambiato ridefinendo (mediante typedef) il simbolo YYSTYPE, oppure servendosi, nella sezione delle dichiarazioni, dei costrutti %union e %type. Nel primo caso, tutti i simboli sono legati ad un valore semantico il cui tipo è quello attribuito a YYSTYPE. In alternativa, %union consente di definire un insieme di interpretazioni alternative dei valori semantici contenuti nello stack. %type associa una data interpretazione ad uno o più simboli non terminali. Un attributo sintetizzato viene calcolato assegnando, nell azione associata ad una data regola, un valore alla pseudo-variabile $$. Tale valore è funzione, in genere, di uno o più degli attributi dei simboli del lato destro della regola stessa. Se ad un simbolo sono stati associati più attributi sotto forma di struct, è possibile far riferimento a ciascuno di essi con la sintassi $n.attr. Func: identifier ( Args ) { $$.name=$1 $$.arg_number=$3 Versione Marco Torchiano 27

28 109 Sintesi di attributi in Lex Se ad un simbolo terminale sono associati degli attributi, bisogna definirne il tipo nella sezione delle dichiarazioni con la sintassi seguente: %token <expression> number L analizzatore lessicale deve provvedere a depositare, all atto del riconoscimento del simbolo, il suo valore semantico nella variabile globale esterna yylval. Se si è usato il costrutto %union, nello scanner bisogna citare esplicitamente il campo della unione a cui ci si riferisce: [0-9]+. [0-9]* { yylval.field = atof(yytext) return(number) 111 Calcolo di attributi ereditati continua... In un riconoscitore bottom-up, non viene riservato spazio sullo stack semantico fino a che il corrispondente simbolo sintattico non è riconosciuto. Ciò rende problematica la gestione degli attributi ereditati. Se la grammatica è ad attributi L, e le regole semantiche per il calcolo degli attributi ereditati sono copy-rules è possibile aggirare l ostacolo in maniera semplice. Se le regole sono più complesse è possibile inserire dei marker, cioè dei non-terminali che si espandono in ε. 110 Esercizi Si scriva una grammatica per riconoscere delle espressioni regolari tipo Lex e costruire l albero di derivazione relativo all espressione riconosciuta. Si utilizzino le primitive: treenode* create_node(char* name) void add_son(treenode* father, treenode* son) Si scriva una grammatica che riconosca sequenze di espressioni matematiche separate dal simbolo = e che stampi, in conseguenza del riconoscimento di tale simbolo il valore dell espressione riconosciuta. 112 Calcolo di attributi ereditati continua... Una produzione che usa una copy-rule: (1) Decl T D1 D1.i = T.s (2) D1 id var(d1.i,id.n) Situazione dello stack prima di ridurre D1 id.n T.s... $1 contesto della regola (2) Versione Marco Torchiano 28

29 113 T type: type: int int Calcolo di attributi ereditati Decl Decl1 type: type: int int id name: name: jj...continua... Il simbolo Decl1 ha l attributo ereditato type. Il valore di tale attributo è presente sullo stack semantico (nella posizione associata a T ) prima che venga creato il simbolo Decl1. Tuttavia esso è al di fuori del contesto semantico della regola relativa a Decl Calcolo di attributi ereditati T type: type: int int id name: name: ii Decl, Decl1 type: type: int int Empty type: type: int int Decl1 type: type: int int id name: name: jj...continua... Aggiungendo la regola Decl1: id, Decl1 non è più vero che Decl1 è sempre preceduto da un identificatore di tipo. Si può aggiungere un nonterminale che porta questa informazione: Decl1: id, Empty Decl1 { $$.type= $0.type add_id($1.name, $$.type) Empty: {$$=$ Calcolo di attributi ereditati 116 Calcolo di attributi ereditati...continua......continua È possibile accedere ai valori semantici precedentemente memorizzati nello stack purché se ne conosca la posizione relativa alla regola corrente. la pseudo-variabile $0 indica il valore associato al simbolo che precede immediatamente (nel parsing left-to-right rightmost-derive) la regola, $-1 quello ancora precedente e così via. Assumendo che il simbolo Decl1 sia sempre preceduto da un identificatore di tipo: Decl1: id { $$.type = $0.type add_id($1.name, $$.type) Si può evitare di introdurre esplicitamente un non terminale riscritto come stringa nulla, utilizzando, nella parte destra delle regole, le azioni intermedie. Esse vengono automaticamente sostituite da YACC con un simbolo non terminale, a sua volta riscritto come ε. Nelle azioni intermedie, $$ indica il valore associato al non-terminale implicito. Per associare a tale valore un interpretazione tra quelle introdotte con il costrutto %union, si usa la sintassi $<union_field>$. Versione Marco Torchiano 29

30 117 Esempio %{ typedef struct { int type_name char* id_name YYSTYPE % %token integer char id %start Decls %% Decls : /* empty */ Decls Decl Decl : TypeName Decl1 TypeName : integer { $$.type_name=1 char { $$.type_name=2 Decl1 : id { $$.id_name = $1.id_name $$.type_name = $0.type_name id, {$$ = $0 Decl1 { $$.id_name = $1.id_name $$.type_name = $0.type_name %% 119 Aggiunta di marker L uso di marker, ovvero di simboli non terminali che si espandono in ε è molto utile in varie occasioni tuttavia può generare alcune complicazioni. La seguente trasformazioni genera una grammatica che non è LR(1): L L b a L M L b a M ε 118 Trasformazione della grammatica LL È possibile evitare l uso degli attributi ereditati trasformando la grammatica. D T L LL L : T integer real L, id id DD i, j : integer TT D L T DD LL id L, id L : T integer real LL i, j : integer TT 120 Gestione degli errori semantici All interno delle azioni possono essere eseguiti i vari controlli che verificano la correttezza semantica dei costrutti sintattici (ad esempio, verificano la giusta corrispondenza tra tipi di operandi). Si possono utilizzare le seguenti macro: YYABORT: termina l esecuzione del parser e restituisce 1 YYACCEPT: termina l esecuzione del parser e restituisce 0 YYERROR: genera un errore sintattico (non chiama yyerror). Alternativamente si può cercare di ricuperare almeno parzialmente l errore e proseguire nella analisi sintattica. Versione Marco Torchiano 30

31 121 Abstract Syntax Tree 123 Controllo dei tipi Gli AST sono una forma condensata degli alberi di derivazione. Gli operatori e le parole chiave non compaiono come foglie dell albero. Esse sono associate ai nodi intermedi che sarebbero stati i genitori delle foglie. S if B then S 1 else S 2 if-then-else Type expressions sistemi di tipi, espressioni di tipi, costruttori di tipo. Costruzione di type-expression Symbol tables Implementazione di un type-checker strutture dati grammatica semantica B S 1 S Esercizi 124 Sistemi di tipi Si modifichi la grammatica delle dichiarazioni C in modo che usi solo attributi ereditati. Si scriva una grammatica per riconoscere delle espressioni regolari tipo Lex e costruire l AST relativo all espressione riconosciuta. Si utilizzino le primitive: ast_node* create_leaf(char ch) ast_node* create_node(char optr, ast_node* opnd1, ast_node* opnd2) la seconda primitiva può accettare 1 o 2 operandi, ovvero il secondo operando può essere NULL gli operatori sono rappresentati dai caratteri + *? &, dove l ultimo rappresenta la concatenazione. Il controllo dei tipi è basato su: i costrutti sintattici del linguaggio, il concetto di tipo, le regole per assegnare i tipi ai costrutti. In generale, i tipi possono essere: primitivi (int, float, char) costruiti (struct, union) Ad ogni costrutto del linguaggio deve essere possibile associare un tipo, descritto per mezzo di una type-expression. Versione Marco Torchiano 31

32 125 Type-expressions 127 Costruttori di tipo Una type-expression è formata da un tipo primitivo, oppure è un costruttore di tipo applicato ad una typeexpression. I tipi primitivi sono tutti quelli necessari al linguaggio, più i due tipi speciali: void : denota l assenza di un tipo, type_error : indica un errore rilevato durante il controllo dei tipi. È possibile assegnare un nome ad un tipo o ad un suo campo. Un nome è una type-expression. Una funzione mappa un elemento del proprio dominio in un elemento del range. Funzioni: T 1 T 2 T 1 : tipo del dominio, T 2 : tipo del range. La funzione int* f(char a, char b) viene rappresentata dalla seguente type expression: (char x char) pointer(int) Teoricamente una funzione può avere come dominio e codominio tipi qualsiasi: ((int int) x (int int)) (int int) 126 Costruttori di tipo 128 Grafo dei tipi Array: array( I, T ) I : dimensione dell array T : type expression Puntatori: pointer( T ) Prodotto: T 1 X T 2 Strutture: struct( T ) Un modo efficace di rappresentare le type expression è l uso di grafi (alberi o DAG). (char x char) pointer(int) char v[10] array(10,char) struct { int i char s[5] struct((i x int )x( s x array(5,char))) X char pointer integer Versione Marco Torchiano 32

Esercitazioni di Linguaggi e Traduttori

Esercitazioni di Linguaggi e Traduttori 1 Linguaggi CF e Riconoscitori 2 Introduzione a Yacc Introduzione a YACC Definizione dei simboli Codifica della grammatica Formato del programma prodotto da YACC Ambiguità e conflitti Conflitti shift-reduce

Dettagli

Copyright. Esercitazioni di Linguaggi e Traduttori. Contenuti. Analisi lessicale. lex - un generatore di analizzatori lessicali

Copyright. Esercitazioni di Linguaggi e Traduttori. Contenuti. Analisi lessicale. lex - un generatore di analizzatori lessicali 1 2 Copyright Esercitazioni di Linguaggi e Traduttori a.a. 2003/2004 Lia Morra Dipartimento di Automatica ed Informatica Tel. (011 564) 7068 E-mail: lia.morra@polito.it Copyright (c) 2000, Marco Torchiano

Dettagli

LEX. Espressioni regolari in Lex

LEX. Espressioni regolari in Lex LEX Poiché la trasformazione di espressioni regolari in automi a stati finiti deterministici e la implementazione di questi ultimi sono processi meccanici (e noiosi), spesso si utilizza un generatore automatico

Dettagli

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

Riconoscitori e analizzatori sintattici. Scanning e parsing. Funzionamento di un parser: la tecnica Shift/Reduce. Esempio POLITECNICO I TORINO Laboratorio di Compilatori Corso di Linguaggi e Traduttori mail: stefano.scanzio@polito.it sito: Riconoscitori e analizzatori sintattici ata una grammatica non ambigua ed una sequenza

Dettagli

Yet Another Compiler-Compiler. Generazione automatica di analizzatori sintattici

Yet Another Compiler-Compiler. Generazione automatica di analizzatori sintattici Yet Another Compiler-Compiler Generazione automatica di analizzatori sintattici 2 YACC Yet Another Compiler-Compiler YACC (Bison) è un generatore di analizzatori sintattici a partire dalla descrizione

Dettagli

Definizioni syntax-directed

Definizioni syntax-directed Definizioni syntax-directed Esempio: Notazione infissa Notazione postfissa Produzioni E E 1 + T E E 1 T E T T 0 T 1 T 2... T 9 Regole semantiche E.t := E 1.t _T.t _ + E.t := E 1.t _T.t _ - E.t := T.t T.t

Dettagli

Linguaggi e Ambienti di Programmazione

Linguaggi e Ambienti di Programmazione Linguaggi e Ambienti di Programmazione Principi e tecniche diffuse che si incontrano spesso nelle applicazioni dell informatica. Compilatori Editor di struttura: riceve in input una sequenza di comandi

Dettagli

Dispensa 3. 1.1 YACC: generalità

Dispensa 3. 1.1 YACC: generalità Dispensa 3 1.1 YACC: generalità Il tool Yacc (acronimo per Yet Another Compiler Compiler) è uno strumento software che a partire da una specifica grammaticale context free di un linguaggio scritta in un

Dettagli

Analizzatori Lessicali con JLex. Giuseppe Morelli

Analizzatori Lessicali con JLex. Giuseppe Morelli Analizzatori Lessicali con JLex Giuseppe Morelli Terminologia Tre concetti sono necessari per comprendere la fase di analisi lessicale: TOKEN: rappresenta un oggetto in grado di rappresentare una specifica

Dettagli

Dispensa YACC. 1.1 YACC: generalità

Dispensa YACC. 1.1 YACC: generalità Dispensa YACC 1.1 YACC: generalità Il tool Yacc (acronimo per Yet Another Compiler Compiler) è uno strumento software che a partire da una specifica grammaticale context free di un linguaggio scritta in

Dettagli

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

Elementi lessicali. Lezione 4. La parole chiave. Elementi lessicali. Elementi lessicali e espressioni logiche. Linguaggi di Programmazione I Lezione 4 Elementi lessicali e espressioni logiche Matricole 2-3 Elementi lessicali il linguaggio C ha un suo vocabolario di base i cui elementi sono detti token esistono 6 tipi di token: parole chiave

Dettagli

Corso di Laurea Magistrale in Ingegneria Informatica A.A Linguaggi Formali e Compilatori LEX, FLEX, JLEX. Giacomo PISCITELLI

Corso di Laurea Magistrale in Ingegneria Informatica A.A Linguaggi Formali e Compilatori LEX, FLEX, JLEX. Giacomo PISCITELLI Corso di Laurea Magistrale in Ingegneria Informatica A.A. 2011-2012 Linguaggi Formali e Compilatori LEX, FLEX, JLEX Giacomo PISCITELLI LEX/FLEX/JLEX Poiché la trasformazione di espressioni regolari in

Dettagli

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

Analizzatore lessicale o scanner. Lo scanner rappresenta un'interfaccia fra il programma sorgente e l'analizzatore sintattico o parser. Analizzatore lessicale o scanner Dispensa del corso di Linguaggi e Traduttori A.A. 2005-2006 Lo scanner rappresenta un'interfaccia fra il programma sorgente e l'analizzatore sintattico o parser. Lo scanner,

Dettagli

Analizzatore Lessicale Parte I Scanner

Analizzatore Lessicale Parte I Scanner Analizzatore Lessicale Parte I Scanner Sommario Dispensa di Linguaggi di Programmazione Corrado Mencar, Pasquale Lops In questa dispensa si descrive un approccio alla costruzione di un analizzatore lessicale

Dettagli

1

1 POLITECNICO DI TORINO Laboratorio di Compilatori Corso di Linguaggi e Traduttori a.a 2010 / 2011 mail: stefano.scanzio@polito.it sito: Lessico () Linguaggi? Sapete qual è il colmo per un tennista? Ridere

Dettagli

Analisi lessicale. Scopi Tecniche Strumenti - Lex. Introduzione ai compilatori - UNINA 1

Analisi lessicale. Scopi Tecniche Strumenti - Lex. Introduzione ai compilatori - UNINA 1 Analisi lessicale Scopi Tecniche Strumenti - Lex Introduzione ai compilatori - UNINA 1 L analizzatore lessicale nel compilatore Linguaggio sorgente Analizzatore lessicale token Next token Analizzatore

Dettagli

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

POLITECNICO DI TORINO. Laboratorio di Compilatori Corso di Linguaggi e Traduttori. Esercitazione 1. a.a 2010 / Linguaggi? POLITECNICO DI TORINO Laboratorio di Compilatori Corso di Linguaggi e Traduttori mail: stefano.scanzio@polito.it sito: a.a 2010 / 2011 Linguaggi? Lessico () Sapete qual è il colmo per un tennista? Ridere

Dettagli

Fasi di un Compilatore

Fasi di un Compilatore Dipartimento di Matematica e Informatica Università di Camerino Un implementazione compilativa di un linguaggio di programmazione viene realizzata tramite un programma che prende il nome di compilatore

Dettagli

Corso di Fondamenti di Informatica Il sistema dei tipi in C++

Corso di Fondamenti di Informatica Il sistema dei tipi in C++ Corso di Fondamenti di Informatica Il sistema dei tipi in C++ Anno Accademico Francesco Tortorella Struttura di un programma C++ // Programma semplice in C++ #include int main() { cout

Dettagli

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

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 ANALISI SINTATTICA TIPO 1: Data un linguaggio scrivere una grammatica che lo generi TIPO 2: Verificare se una grammatica non contestuale è ambigua TiPO 3: Verificare se una grammatica e LL(1) e costruirne

Dettagli

Primi passi con JFlex

Primi passi con JFlex Primi passi con JFlex Luca Chiodini Abstract Ci proponiamo di muovere i primi passi nel mondo dell analisi lessicale e della produzione automatica di un analizzatore lessicale. Verrà mostrato l uso di

Dettagli

Lezione 6 Introduzione al C++ Mauro Piccolo

Lezione 6 Introduzione al C++ Mauro Piccolo Lezione 6 Introduzione al C++ Mauro Piccolo piccolo@di.unito.it Linguaggi di programmazione Un linguaggio formale disegnato per descrivere la computazione Linguaggi ad alto livello C, C++, Pascal, Java,

Dettagli

Fondamenti di Informatica 6. Algoritmi e pseudocodifica

Fondamenti di Informatica 6. Algoritmi e pseudocodifica Vettori e matrici #1 Fondamenti di Informatica 6. Algoritmi e pseudocodifica Corso di Laurea in Ingegneria Civile A.A. 2010-2011 1 Semestre Prof. Giovanni Pascoschi Le variabili definite come coppie

Dettagli

GESTIONE DEI FILE IN C. Docente: Giorgio Giacinto AA 2008/2009

GESTIONE DEI FILE IN C. Docente: Giorgio Giacinto AA 2008/2009 Università degli Studi di Cagliari Corso di Laurea Specialistica in Ingegneria per l Ambiente ed il Territorio Corso di Laurea Specialistica in Ingegneria Civile - Strutture FONDAMENTI DI INFORMATICA 2

Dettagli

Pumping lemma per i linguaggi Context-free

Pumping lemma per i linguaggi Context-free Pumping lemma per i linguaggi Context-free Sia L un linguaggio context-free. E possibile determinare una costante k, dipendente da L, tale che qualunque stringa z! L con z > k si può esprimere come z=

Dettagli

Costruzione dell insieme dei Follow

Costruzione dell insieme dei Follow Costruzione dell insieme dei Follow E! T E - T E E! + T E - T E " T! F T T! *F T " F! (E) i Per evitare che alcuni insiemi siano vuoti si aggiunge per default il simbolo speciale $ che demarca la fine

Dettagli

Algoritmi, Strutture Dati e Programmi. UD 2.b: Programmazione in Pascal

Algoritmi, Strutture Dati e Programmi. UD 2.b: Programmazione in Pascal Algoritmi, Strutture Dati e Programmi : Programmazione in Pascal Prof. Alberto Postiglione AA 2007-2008 Università degli Studi di Salerno Il Linguaggio di Programmazione Pascal Esistono molti linguaggi

Dettagli

Linguaggio C: introduzione

Linguaggio C: introduzione Dipartimento di Elettronica ed Informazione Politecnico di Milano Informatica e CAD (c.i.) - ICA Prof. Pierluigi Plebani A.A. 2008/2009 Linguaggio C: introduzione La presente dispensa e da utilizzarsi

Dettagli

I CARATTERI E LE STRINGHE

I CARATTERI E LE STRINGHE I CARATTERI E LE STRINGHE IL CODICE ASCII Per memorizzare i simboli grafici corrispondenti ai caratteri bisogna associare un numero intero a ciascuno di essi Il codice ASCII / æski/ (American Standard

Dettagli

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 - D. Talia - UNICAL 1. Fondamenti di Informatica Fondamenti di Informatica INTRODUZIONE ALLA PROGRAMMAZIONE AD ALTO LIVELLO IL LINGUAGGIO JAVA Fondamenti di Informatica - D. Talia - UNICAL 1 Fondamenti di Informatica - Programma Un programma è una formulazione

Dettagli

Riconoscitori e analizzatori sintattici

Riconoscitori e analizzatori sintattici POLITECNICO DI TORINO Laboratorio di Compilatori Corso di Linguaggi e Traduttori Esercitazione 2 Marco Torchiano mail: marco.torchiano@polito.it sito: http://www.skenz.it/traduttori a.a 2008 / 2009 1 Riconoscitori

Dettagli

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

Dispensa 2. Data una grammatica context free esistono tre metodi diversi per costruirne la parsing table per un parser LR: Dispensa 2 2.1 Costruzione Parsing Table LR: generalità Come tutti i parser tabellari predittivi, anche i parser LR possono essere applicati solo a parsing table senza conflitti (ossia entrate multiple)

Dettagli

Programma del corso. Elementi di Programmazione. Introduzione agli algoritmi. Rappresentazione delle Informazioni. Architettura del calcolatore

Programma del corso. Elementi di Programmazione. Introduzione agli algoritmi. Rappresentazione delle Informazioni. Architettura del calcolatore Programma del corso Introduzione agli algoritmi Rappresentazione delle Informazioni Architettura del calcolatore Reti di Calcolatori Elementi di Programmazione Algoritmi e programmi Algoritmo Sequenza

Dettagli

Funzioni, Stack e Visibilità delle Variabili in C

Funzioni, Stack e Visibilità delle Variabili in C Funzioni, Stack e Visibilità delle Variabili in C Programmazione I e Laboratorio Corso di Laurea in Informatica A.A. 2016/2017 Calendario delle lezioni Lez. 1 Lez. 2 Lez. 3 Lez. 4 Lez. 5 Lez. 6 Lez. 7

Dettagli

Le basi del linguaggio Java

Le basi del linguaggio Java Le basi del linguaggio Java Compilazione e interpretazione Quando si compila il codice sorgente scritto in Java, il compilatore genera il codice compilato, chiamato bytecode. È un codice generato per una

Dettagli

Esercitazione 11. Liste semplici

Esercitazione 11. Liste semplici Esercitazione 11 Liste semplici Liste semplici (o lineari) Una lista semplice (o lineare) è una successione di elementi omogenei che occupano in memoria una posizione qualsiasi. Ciascun elemento contiene

Dettagli

Costanti e Variabili

Costanti e Variabili Parte 3 Costanti e Variabili Identificatori Un identificatore è un nome che viene associato a diverse entità (costanti, tipi, variabili, funzioni, ecc.) e serve ad identificare la particolare entità Gli

Dettagli

Unità F1. Obiettivi. Il linguaggio C. Il linguaggio C++ Linguaggio C. Pseudolinguaggio. Primi programmi

Unità F1. Obiettivi. Il linguaggio C. Il linguaggio C++ Linguaggio C. Pseudolinguaggio. Primi programmi Obiettivi Unità F1 Primi programmi Conoscere il significato di dichiarazione e definizione di variabili Conoscere i tipi di dato numerici Essere in grado di realizzare semplici algoritmi in pseudolinguaggio

Dettagli

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

ESECUZIONE DI PROGRAMMI C SU MACCHINE REALI. Docente: Giorgio Giacinto AA 2008/2009. formalizzazione degli algoritmi in linguaggio C Università degli Studi di Cagliari Corso di Laurea Specialistica in Ingegneria per l Ambiente ed il Territorio Corso di Laurea Specialistica in Ingegneria Civile - Strutture FONDAMENTI DI INFORMATICA 2

Dettagli

L utility Unix awk [Aho-Weinberger-Kernighan]

L utility Unix awk [Aho-Weinberger-Kernighan] L utility Unix awk [Aho-Weinberger-Kernighan] L utility awk serve per processare file di testo secondo un programma specificato dall utente. L utility awk legge riga per riga i file ed esegue una o più

Dettagli

Linguaggio C - le strutture di controllo: sequenza, selezione, iterazione

Linguaggio C - le strutture di controllo: sequenza, selezione, iterazione Dipartimento di Elettronica ed Informazione Politecnico di Milano Informatica e CAD (c.i.) - ICA Prof. Pierluigi Plebani A.A. 2008/2009 Linguaggio C - le strutture di controllo: sequenza, selezione, iterazione

Dettagli

Le direttive del Preprocessore

Le direttive del Preprocessore Le direttive del Preprocessore Prof. Orazio Mirabella Direttive Un compilatore traduce le istruzioni di un programma sorgente in linguaggio macchina Talvolta è conveniente prendere coscienza dell esistenza

Dettagli

Argomenti Avanzati.! I puntatori! Stack! Visibilità delle Variabili

Argomenti Avanzati.! I puntatori! Stack! Visibilità delle Variabili Linguaggio C Argomenti Avanzati! I puntatori! Stack! Visibilità delle Variabili 2 ! Il C consente di associare ai tipi di dati nomi definiti dal programmatore, mediante la parola chiave typedef! Dal punto

Dettagli

Fondamenti d Informatica: linguaggi formali. Barbara Re, Phd

Fondamenti d Informatica: linguaggi formali. Barbara Re, Phd Fondamenti d Informatica: linguaggi formali Barbara Re, Phd Agenda } Introdurremo } La nozione di linguaggio } Strumenti per definire un linguaggio } Espressioni Regolari 2 Linguaggio } Da un punto di

Dettagli

Caratteristiche di un linguaggio ad alto livello

Caratteristiche di un linguaggio ad alto livello Caratteristiche di un linguaggio ad alto livello Un linguaggio ad alto livello deve offrire degli strumenti per: rappresentare le informazioni di interesse dell algoritmo definire le istruzioni che costituiscono

Dettagli

Generatori di analizzatori lessicali e sintattici

Generatori di analizzatori lessicali e sintattici Generatori di analizzatori lessicali e sintattici 1 Analizzatori lessicali Analisi lessicale: riconoscere nella stringa di ingresso gruppi di simboli che corrispondono a specifiche categorie sintattiche.

Dettagli

Espressione di chiamata di funzione

Espressione di chiamata di funzione Avvertenza Quanto segue NON è un libro, ma è una copia dei lucidi usati a lezione che NON sostituisce i libri di testo adottati e consigliati per l insegnamento di Informatica Generale. Questa copia è

Dettagli

Traduzione guidata dalla sintassi

Traduzione guidata dalla sintassi Traduzione guidata dalla sintassi Attributi e definizioni guidate dalla sintassi Dipartimento di Matematica e Informatica mariarita.diberardini@unicam.it Analisi Semantica Analisi sintattica - output:

Dettagli

File binari e file di testo

File binari e file di testo I file File binari e file di testo distinzione tra file binari file di testo si possono usare funzioni diverse per la gestione di tipi di file diversi Programmazione Gestione dei file 2 File binari e file

Dettagli

Caratteri e stringhe

Caratteri e stringhe Caratteri e stringhe Caratteri Dato che un computer può memorizzare esclusivamente sequenze di bit, per memorizzare un carattere (e quindi testi) è necessario stabilire una convenzione che associa a un

Dettagli

Unità Didattica 1 Linguaggio C. Fondamenti. Struttura di un programma.

Unità Didattica 1 Linguaggio C. Fondamenti. Struttura di un programma. Unità Didattica 1 Linguaggio C Fondamenti. Struttura di un programma. 1 La storia del Linguaggio C UNIX (1969) - DEC PDP-7 Assembly Language BCPL - un OS facilmente accessibile che fornisce potenti strumenti

Dettagli

Esercizi su strutture dati

Esercizi su strutture dati Esercizi su strutture dati Marco Alberti Programmazione e Laboratorio, A.A. 2016-2017 Dipartimento di Matematica e Informatica - Università di Ferrara Ultima modifica: 21 dicembre 2016 Liste collegate

Dettagli

Cognome e Nome : Corso e Anno di Immatricolazione: Modalità di Laboratorio (Progetto/Prova) :

Cognome e Nome : Corso e Anno di Immatricolazione: Modalità di Laboratorio (Progetto/Prova) : PROGRAMMAZIONE (Corsi B e C) Pre-appello di Gennaio 2004 (A.A. 2003/2004) PROGRAMMAZIONE (B e C) S. Straordinaria - Appello di Gennaio (A.A. 2002/2003) 22 Gennaio 2004 ore 11 Aula II di Facoltà (Durata:

Dettagli

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

L intero è o il valore zero o una stringa di cifre che inizia con una cifra diversa sa zero. ANALISI SINTATTICA Data un linguaggio scrivere una grammatica che lo generi ESERCIZIO 1 Definire una grammatica per il linguaggio L = {ww w appartiene a (a, b)*} ESERCIZIO 2 Dato l alfabeto T=[0,1,2,3,4,5,6,7,8,9,/}

Dettagli

Primi passi col linguaggio C

Primi passi col linguaggio C Andrea Marin Università Ca Foscari Venezia Laurea in Informatica Corso di Programmazione part-time a.a. 2011/2012 Come introdurre un linguaggio di programmazione? Obiettivi: Introduciamo una macchina astratta

Dettagli

Corso di Laboratorio di Sistemi Operativi

Corso di Laboratorio di Sistemi Operativi Corso di Laboratorio di Sistemi Operativi Lezione 4 Alessandro Dal Palù email: alessandro.dalpalu@unipr.it web: www.unipr.it/~dalpalu Approfondimento su make http://http://capone.mtsu.edu/csdept/facilitiesandresources/make.htm

Dettagli

Un esempio per iniziare. Il controllo del programma in C. Altri cenni su printf() Esercizi (printf) printf( 8!=%d, fatt);

Un esempio per iniziare. Il controllo del programma in C. Altri cenni su printf() Esercizi (printf) printf( 8!=%d, fatt); Un esempio per iniziare Il controllo del programma in C DD Cap.3 pp.91-130 /* calcolo di 8!*/ #include #define C 8 int main() int i=1; int fatt=1; while (i

Dettagli

Scope delle variabili e passaggio parametri. Danilo Ardagna Politecnico di Milano

Scope delle variabili e passaggio parametri. Danilo Ardagna Politecnico di Milano Scope delle variabili e passaggio parametri Danilo Ardagna Politecnico di Milano 1-4-2014 Introduzione! Con le funzioni è stato introdotto un meccanismo per definire dei piccoli programmi all interno di

Dettagli

Esercizio 2 (punti 7) Dato il seguente programma C: #include <stdio.h> int swap(int * nome, int length);

Esercizio 2 (punti 7) Dato il seguente programma C: #include <stdio.h> int swap(int * nome, int length); Fondamenti di Informatica L-A (A.A. 004/005) - Ingegneria Informatica Prof.ssa Mello & Prof. Bellavista I Prova Intermedia del 11/11/004 - durata h - COMPITO B Esercizio 1 (punti 1) Una associazione di

Dettagli

Verso i puntatori: Cosa è una variabile?

Verso i puntatori: Cosa è una variabile? Verso i puntatori: Cosa è una variabile? Quando si dichiara una variabile, ad es. int a; si rende noto il nome e il tipo della variabile. Il compilatore alloca l opportuno numero di byte di memoria per

Dettagli

Input/Output. Lettura e scrittura Caratteri e Stringhe: Terminale e file. Input/output. caratteri stringhe formattato ascii binari

Input/Output. Lettura e scrittura Caratteri e Stringhe: Terminale e file. Input/output. caratteri stringhe formattato ascii binari Input/Output Lettura e scrittura Caratteri e Stringhe: Terminale e file Input/output console file caratteri stringhe formattato ascii binari Linguaggio ANSI C Input/Output - 1 La libreria standard del

Dettagli

Intro. Traduzione guidata dalla sintassi. Attributi. Due notazioni a diversi livelli. Due notazioni a diversi livelli. Il flusso concettuale

Intro. Traduzione guidata dalla sintassi. Attributi. Due notazioni a diversi livelli. Due notazioni a diversi livelli. Il flusso concettuale Intro Traduzione guidata dalla sintassi Attributi e Definizioni guidate dalla sintassi In questa ultima parte del corso vediamo, in breve, una tecnica che permette di effettuare analisi semantiche e traduzione

Dettagli

Variabili. Unità 2. Domenico Daniele Bloisi. Corso di Fondamenti di Informatica Ingegneria delle Comunicazioni BCOR Ingegneria Elettronica BELR

Variabili. Unità 2. Domenico Daniele Bloisi. Corso di Fondamenti di Informatica Ingegneria delle Comunicazioni BCOR Ingegneria Elettronica BELR Corso di Fondamenti di Informatica Ingegneria delle Comunicazioni BCOR Ingegneria Elettronica BELR Domenico Daniele Bloisi Docenti Parte I prof. Silvio Salza salza@dis.uniroma1.it http://www.dis.uniroma1.it/~salza/fondamenti.htm

Dettagli

Introduzione alla programmazione

Introduzione alla programmazione Introduzione alla programmazione Risolvere un problema Per risolvere un problema si procede innanzitutto all individuazione Delle informazioni, dei dati noti Dei risultati desiderati Il secondo passo consiste

Dettagli

Input/Output di numeri

Input/Output di numeri Input/Output di numeri I/O di numeri Per utilizzare le funzioni di I/O occorre include il file di intestazione (o file header) stdio.h utilizzando all inizio del sorgente la direttiva #include

Dettagli

ADT LISTA: altre operazioni non primitive ADT LISTA COSTRUZIONE ADT LISTA COSTRUZIONE ADT LISTA (2)

ADT LISTA: altre operazioni non primitive ADT LISTA COSTRUZIONE ADT LISTA COSTRUZIONE ADT LISTA (2) ADT LISTA Pochi Linguaggi forniscono tipo lista fra predefiniti (LISP, Prolog); per gli altri, ADT lista si costruisce a partire da altre strutture dati (in C tipicamente vettori o puntatori) OPERAZIONI

Dettagli

Input/output da file I/O ANSI e I/O UNIX FLUSSI E FILE FLUSSI FLUSSI di TESTO FLUSSI BINARI FILE

Input/output da file I/O ANSI e I/O UNIX FLUSSI E FILE FLUSSI FLUSSI di TESTO FLUSSI BINARI FILE Input/output da file Il linguaggio C non contiene istruzioni di I/O, in quanto tali operazioni vengono eseguite tramite funzioni di libreria standard. Questo approccio rende estremamente flessibile e potente

Dettagli

Espressioni aritmetiche

Espressioni aritmetiche Espressioni aritmetiche Consideriamo espressioni costruite a partire da variabili e costanti intere mediante applicazione delle operazioni di somma, sottrazione, prodotto e divisione (intera). Ad esempio:

Dettagli

Funzioni in C. Funzioni. Strategie di programmazione. Funzioni in C. Come riusare il codice? (2/3) Come riusare il codice? (1/3)

Funzioni in C. Funzioni. Strategie di programmazione. Funzioni in C. Come riusare il codice? (2/3) Come riusare il codice? (1/3) Funzioni Il concetto di funzione Parametri formali e attuali Il valore di ritorno Definizione e chiamata di funzioni Passaggio dei parametri Corpo della funzione 2 Strategie di programmazione Riuso di

Dettagli

Array. Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 1. Dispensa 11. A. Miola Dicembre 2007

Array. Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 1. Dispensa 11. A. Miola Dicembre 2007 Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 1 Dispensa 11 Array A. Miola Dicembre 2007 http://www.dia.uniroma3.it/~java/fondinf1/ Array 1 Contenuti Il problema degli studenti da promuovere

Dettagli

Corso di Fondamenti di Informatica Linguaggi di Programmazione

Corso di Fondamenti di Informatica Linguaggi di Programmazione di Cassino e del Lazio Meridionale Corso di Informatica Linguaggi di Programmazione Anno Accademico 2014/2015 Francesco Tortorella Linguaggi di programmazione Un calcolatore basato sul modello di von Neumann

Dettagli

Lezione 8 Struct e qsort

Lezione 8 Struct e qsort Lezione 8 Struct e qsort Rossano Venturini rossano@di.unipi.it Pagina web del corso http://didawiki.cli.di.unipi.it/doku.php/informatica/all-b/start Esercizio 3 QuickSort strambo Modificare il Quicksort

Dettagli

Variabili. Unità 2. Domenico Daniele Bloisi. Corso di Programmazione e Metodi Numerici Ingegneria Aerospaziale BAER

Variabili. Unità 2. Domenico Daniele Bloisi. Corso di Programmazione e Metodi Numerici Ingegneria Aerospaziale BAER Corso di Programmazione e Metodi Numerici Ingegneria Aerospaziale BAER Domenico Daniele Bloisi Docenti Metodi Numerici prof. Vittoria Bruni vittoria.bruni@sbai.uniroma1.it Programmazione prof. Domenico

Dettagli

Perché il linguaggio C?

Perché il linguaggio C? Il linguaggio C 7 Perché il linguaggio C? Larga diffusione nel software applicativo Standard di fatto per lo sviluppo di software di sistema Visione a basso livello della memoria Capacità di manipolare

Dettagli

Informatica ALGORITMI E LINGUAGGI DI PROGRAMMAZIONE. Francesco Tura. F. Tura

Informatica ALGORITMI E LINGUAGGI DI PROGRAMMAZIONE. Francesco Tura. F. Tura Informatica ALGORITMI E LINGUAGGI DI PROGRAMMAZIONE Francesco Tura francesco.tura@unibo.it 1 Lo strumento dell informatico: ELABORATORE ELETTRONICO [= calcolatore = computer] Macchina multifunzionale Macchina

Dettagli

Linguaggio C Struttura dei programmi

Linguaggio C Struttura dei programmi FONDAMENTI DI INFORMATICA Prof. PIER LUCA MONTESSORO Ing. DAVIDE PIERATTONI Facoltà di Ingegneria Università degli Studi di Udine Linguaggio C Struttura dei programmi 2001 Pier Luca Montessoro - Davide

Dettagli

Foglio Elettronico Lezione 1

Foglio Elettronico Lezione 1 - Introduzione - Celle e riferimenti - Formule - Approfondimenti - Funzioni logiche Sommario Introduzione - Foglio elettronico o foglio di calcolo - Cos'è? Strumento per raccogliere dati organizzati in

Dettagli

Linguaggio C - sezione dichiarativa: costanti e variabili

Linguaggio C - sezione dichiarativa: costanti e variabili Dipartimento di Elettronica ed Informazione Politecnico di Milano Informatica e CAD (c.i.) - ICA Prof. Pierluigi Plebani A.A. 2008/2009 Linguaggio C - sezione dichiarativa: costanti e variabili La presente

Dettagli

Introduzione a Matlab

Introduzione a Matlab INFORMATICA B Ingegneria Elettrica Introduzione a Matlab Introduzione a Matlab Matlab (MATrix LABoratory) è uno strumento per il calcolo scientifico ed ingegneristico Matlab facilita lo sviluppo di programmi

Dettagli

Array in Fortran 90. Ing. Luca De Santis. Anno accademico 2006/2007. DIS - Dipartimento di informatica e sistemistica

Array in Fortran 90. Ing. Luca De Santis. Anno accademico 2006/2007. DIS - Dipartimento di informatica e sistemistica Array in Fortran 90 Ing. Luca De Santis DIS - Dipartimento di informatica e sistemistica Anno accademico 2006/2007 Fortran 90: array DIS - Dipartimento di informatica e sistemistica 1 / 25 Cosa vedremo

Dettagli

Funzioni e. Alessandra Giordani Mercoledì 16 maggio 2012

Funzioni e. Alessandra Giordani Mercoledì 16 maggio 2012 Funzioni e passaggio parametri Alessandra Giordani agiordani@disi.unitn.it Mercoledì 16 maggio 2012 http://disi.unitn.it/~agiordani/ Cosa vedremo oggi Le funzioni Il passaggio dei parametri Le dichiarazioni

Dettagli

Le strutture. Una struttura C è una collezione di variabili di uno o più tipi, raggruppate sotto un nome comune.

Le strutture. Una struttura C è una collezione di variabili di uno o più tipi, raggruppate sotto un nome comune. Le strutture Una struttura C è una collezione di variabili di uno o più tipi, raggruppate sotto un nome comune. Dichiarazione di una struttura: struct point { int x; int y; }; La dichiarazione di una struttura

Dettagli

Variabili e Istruzioni

Variabili e Istruzioni Exit Menù Variabili e Istruzioni 1 Le Variabili Una VARIABILE è un oggetto identificato da un NOME e da uno STATO, detto CONTENUTO o VALORE. Possiamo immaginarla come una scatola contenuto Pippo 11 nome

Dettagli

Gestione dei file. Stefano Ferrari. Università degli Studi di Milano Programmazione. anno accademico

Gestione dei file. Stefano Ferrari. Università degli Studi di Milano Programmazione. anno accademico Gestione dei file Stefano Ferrari Università degli Studi di Milano stefano.ferrari@unimi.it Programmazione anno accademico 2016 2017 Gli stream Si dice stream qualsiasi sorgente di dati in ingresso e qualsiasi

Dettagli

Descrizione delle operazioni di calcolo. Espressioni costanti semplici

Descrizione delle operazioni di calcolo. Espressioni costanti semplici Descrizione delle operazioni di calcolo Come abbiamo detto l interprete è in grado di generare nuovi valori a partire da valori precedentemente acquisiti o generati. Il linguaggio di programmazione permette

Dettagli

Analisi Lessicale. File

Analisi Lessicale. File Analisi Lessicale Corso di Linguaggi di Programmazione Stefano Ferilli ferilli@di.uniba.it Università degli Studi di Bari A.A. 2002/2003 File var nome: file of tipo; reset(nome) read(nome, arg,, arg) rewrite(nome)

Dettagli

Il preprocessore. Direttiva define Direttiva include Direttiva if

Il preprocessore. Direttiva define Direttiva include Direttiva if Il preprocessore Direttiva define Direttiva include Direttiva if Il preprocessore Il preprocessore è un processore di testi che elabora il contenuto di un file sorgente prima della compilazione vera e

Dettagli

Strategie di programmazione

Strategie di programmazione Funzioni Funzioni in C Il concetto di funzione Parametri formali e attuali Il valore di ritorno Definizione e chiamata di funzioni Passaggio dei parametri Corpo della funzione 2 Funzioni in C Strategie

Dettagli

La sintassi del C APPENDICE H

La sintassi del C APPENDICE H APPENDICE H La sintassi del C Nella notazione della sintassi utilizzata, le categorie sintattiche (non terminali) sono state indicate da uno stile tipografico in corsivo, mentre le parole letterali e i

Dettagli

Le basi del linguaggio Java

Le basi del linguaggio Java Corso di Laurea Ingegneria Civile Fondamenti di Informatica Dispensa 10 Le basi del linguaggio Java Aprile 2010 Le basi del linguaggio Java 1 Prerequisiti Nozioni generali sulla sintassi e semantica del

Dettagli

Linguaggio C: le funzioni. Visibilità variabili e passaggio parametri

Linguaggio C: le funzioni. Visibilità variabili e passaggio parametri Dipartimento di Elettronica ed Informazione Politecnico di Milano Informatica e CAD (c.i.) - ICA Prof. Pierluigi Plebani A.A. 2008/2009 Linguaggio C: le funzioni. Visibilità variabili e passaggio parametri

Dettagli

5. Quinta esercitazione autoguidata: liste semplici

5. Quinta esercitazione autoguidata: liste semplici 22 5. Quinta esercitazione autoguidata: liste semplici 5.1. Liste rappresentate mediante strutture e puntatori (LISTE1.C, LISTE2.C) Scrivere un programma che - costruisce una lista di k interi (con k letto

Dettagli

LINGUAGGI DI ALTO LIVELLO. Si basano su una macchina virtuale le cui mosse non sono quelle della macchina hardware

LINGUAGGI DI ALTO LIVELLO. Si basano su una macchina virtuale le cui mosse non sono quelle della macchina hardware LINGUAGGI DI ALTO LIVELLO Si basano su una macchina virtuale le cui mosse non sono quelle della macchina hardware 1 LINGUAGGI DI ALTO LIVELLO Barriera di astrazione Fortran Cobol Basic Pascal Python C

Dettagli

Linguaggi di Programmazione

Linguaggi di Programmazione Linguaggi di Programmazione 1 Linguaggio naturale e linguaggio macchina La comunicazione uomo-macchina avviene attraverso formalismi che assumono la forma di un linguaggio. Caratteristiche del Linguaggio

Dettagli

IL PRIMO PROGRAMMA IN C

IL PRIMO PROGRAMMA IN C IL PRIMO PROGRAMMA IN C LO SCOPO Si vuole scrivere un programma in linguaggio C che chieda all utente di introdurre da tastiera due numeri interi e visualizzi il valore della loro somma sul video SOLUZIONE

Dettagli

Grammatiche. Grammatiche libere da contesto Grammatiche regolari Potenza delle grammatiche libere e regolari Struttura di frase: Alberi di derivazione

Grammatiche. Grammatiche libere da contesto Grammatiche regolari Potenza delle grammatiche libere e regolari Struttura di frase: Alberi di derivazione Grammatiche Grammatiche libere da contesto Grammatiche regolari Potenza delle grammatiche libere e regolari Struttura di frase: Alberi di derivazione Esempio dei numeri interi Si consideri il linguaggio

Dettagli

6 - Blocchi e cicli. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo

6 - Blocchi e cicli. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo 6 - Blocchi e cicli Programmazione e analisi di dati Modulo A: Programmazione in Java Paolo Milazzo Dipartimento di Informatica, Università di Pisa http://pages.di.unipi.it/milazzo milazzo di.unipi.it

Dettagli

LINGUAGGI DI ALTO LIVELLO

LINGUAGGI DI ALTO LIVELLO LINGUAGGI DI ALTO LIVELLO Si basano su una macchina virtuale le cui mosse non sono quelle della macchina hardware 1 LINGUAGGI DI ALTO LIVELLO Barriera di astrazione C Fortran Modula-2 Cobol Algol Basic

Dettagli

Valutazione di espressioni

Valutazione di espressioni Valutazione di espressioni Stefano Ferrari Università degli Studi di Milano stefano.ferrari@unimi.it Programmazione anno accademico 2016 2017 Blocco Blocco è un insieme di istruzioni consecutive, con un

Dettagli

MATLAB I/O. Informatica B - A.A. 2012/2013 ACQUISIZIONE DI INPUT DA TASTIERA

MATLAB I/O. Informatica B - A.A. 2012/2013 ACQUISIZIONE DI INPUT DA TASTIERA MATLAB I/O Informatica B - A.A. 2012/2013 ACQUISIZIONE DI INPUT DA TASTIERA Funzione input valore = input( inserisci un valore ); Matlab stampa a video la stringa inserisci un valore ed aspetta di ricevere

Dettagli