Un esempio di compilatore realizzato con flex e bison

Похожие документы
Implementazione di un Compilatore e di una Macchina Virtuale per la Compilazione e l Esecuzione di un Linguaggio Simple

Esercitazioni di Informatica 3

Breve Manuale di Riferimento sulla Sintassi Linguaggi C++ e FORTRAN

Definizioni syntax-directed

Istruzioni di trasferimento dati

Yet Another Compiler-Compiler. Generazione automatica di analizzatori sintattici

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

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

Linguaggio C. Esercizio 1

Analizzatore Lessicale Parte I Scanner

Linguaggi e Ambienti di Programmazione

Esercitazione 12. Esercizi di Ricapitolazione

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

FONDAMENTI DI INFORMATICA

PILE E CODE. Pile (stack):

Linguaggio macchina e linguaggio assembly

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

Esercizi Strutture dati di tipo astratto

Esercizi. Assembly. Alessandro A. Nacci ACSO 2014/2014

Esercitazione: Implementazione in linguaggio C dell ADT. Stack con l utilizzo. di linked list

Sottoprogrammi in linguaggio assembly del Motorola 68000

I puntatori e l allocazione dinamica di memoria

Riassunto. Riassunto. Ciclo fetch&execute. Concetto di programma memorizzato. Istruzioni aritmetiche add, sub, mult, div

Lecture 2: Prime Istruzioni

Esercizio 1: funzione con valore di ritorno di tipo puntatore

Question 1: introduction to computer programming

ARM: stack e subroutine

La sintassi del C APPENDICE H

Il linguaggio assembly

Calcolatori Elettronici A a.a. 2008/2009

Esercizi. Stringhe. Stringhe Ricerca binaria

Grammatiche Parse trees Lezione del 17/10/2012

Strutture. Strutture e Unioni. Definizione di strutture (2) Definizione di strutture (1)

Esercitazioni di Linguaggi e Traduttori

PROGRAMMI LINGUAGGIO C

Fondamenti di Programmazione. Antonio Pescapè e Marcello Esposito Parte Quinta v1.0

Linguaggio macchina e linguaggio assembler

Esercitazione 11. Liste semplici

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

Programmazione I - Laboratorio

1 Esercizi con architettura a 1 bus

Esercizio 1 (15 punti)

Architettura degli Elaboratori

Introduzione alla programmazione strutturata

Le operazioni di allocazione e deallocazione sono a carico del sistema.

Lezione 20. Assembly MIPS: Il set istruzioni, strutture di controllo in Assembly

Perché il linguaggio C?

Istruzioni di modifica della sequenza di elaborazione

MIPS Instruction Set 2

Linguaggi di programmazione

LISTE, INSIEMI, ALBERI E RICORSIONE

File e puntatori a file

Analizzatore lessicale o scanner

Esercitazione n. 3. Dott. Salvatore Pontarelli

Il linguaggio C. Puntatori e dintorni

Sommario Introduzione al linguaggio Assembly. Calcolatori Elettronici Prof. Gian Luca Marcialis. Le operazioni fondamentali

Linguaggio C: puntatori

CREARE UNA LIBRERIA IN C

Strutture dati dinamiche in C (II)

Sommario. Introduzione... xv. Giorno 1 Elementi base del linguaggio C

Laboratorio di Programmazione

4 Le liste collegate 4.0. Le liste collegate. 4 Le liste collegate Rappresentazione di liste 4.1 Rappresentazione di liste

Linguaggi e Traduttori: Analisi lessicale

Esegue la sommatral'accumulatoreac e Se I=1, ilcontenutodellacelladi memoriailcui indirizzoè

LE STRUTTURE IN PROGRAMMAZIONE ASSEMBLER

Capitolo 5 - Funzioni

Uso avanzato dei puntatori Allocazione dinamica della memoria

Istruzioni macchina. Dove sono gli operandi? Ciclo della CPU. Elementi di un istruzione macchina. Rappresentazione delle istruzioni

5. Quinta esercitazione autoguidata: liste semplici

Транскрипт:

POLITECNICO DI MILANO Dipartimento di Elettronica e Informazione Corso di Linguaggi Formali e Compilatori - Esercitazioni Un esempio di compilatore realizzato con flex e bison Progetto di Vincenzo Martena Slide di Daniele Paolo Scarpazza Progetto 1

Tema Si costruisca, utilizzando bison e flex, un compilatore per il linguaggio di programmazione Simple. Il compilatore prenda in ingresso un file contenete un programma Simple e generi le corrispondenti istruzioni per la macchina virtuale SimpleVM. Progetto 2

Sintassi del linguaggio Simple program -> preamble body preamble -> DECLARATIONS declarations body -> BEGIN_PROGRAM cmd_seq END_PROGRAM declarations -> ε INTEGER id_seq IDENTIFIER. id_seq -> ε id_seq IDENTIFIER, cmd_seq -> ε cmd_seq command ; command -> ε SKIP READ IDENTIFIER WRITE exp IDENTIFIER := exp IF bool_exp THEN cmd_seq ELSE cmd_seq FI WHILE bool_exp DO cmd_seq OD exp -> exp + term exp - term term term factor primary bool_exp -> term * factor term / factor factor -> factor ^ primary primary -> NUMBER IDENT (exp) -> exp = exp exp < exp exp > exp Progetto 3

Token lessicali BEGIN_PROGRAM DECLARATIONS DO ELSE END_PROGRAM FI IDENTIFIER IF INTEGER NUMBER OD READ SKIP THEN WHILE WRITE begin declarations do else end fi [a - z][a - z0-9]+ if integer [0-9]+ od read skip then while write IDENTIFIER [a - z][a - z0-9]+ NUMBER [0-9]+ WRITE Progetto 4

La macchina virtuale SimpleVM Semplice macchina a stack: 2 aree di memoria: area C, per il codice area S, a pila, per i dati (variabili e risultati intermedi della computazione) 3 registri: stack pointer (SP): punta al top della pila; instruction register (IR): prossima istruzione; program counter (PC): indirizzo della prossima istruzione; Progetto 5

Istruzioni di SimpleVM HALT termina l'esecuzione IN_INT var legge un intero da tastiera e memorizza in var OUT_INT STORE var JMP_FALSE label GOTO label DATA spazio LD_INT intero LD_VAR var LT / EQ / GT scrive a video il top della pila ed esegue pop scrive in var il top della pila ed esegue pop se SP è falso, copia indirizzo di label in PC copia indirizzo di label in PC riserva spazio sullo stack esegue un push di intero sullo stack esegue un push di var sullo stack pop, pop, confronta i valori, push risultato ADD / SUB / MULT pop, pop, esegue l'operazione, push risultato / DIV / PWR (Per maggiori informazioni: fetch_execute_cycle(),, file SM.c) Progetto 6

Traduzione in assembly La traduzione segue lo schema riportato nella prossima slide; Nella traduzione finale, al nome simbolico delle etichette va sostituito il valore numerico corrispondente all'indirizzo nell'area del codice; Progetto 7

Schema di traduzione X := expr traduzione di expr STORE X if C then traduzione di C S1 JMP_FALSE L1 else traduzione di S1 S2 GOTO L2 fi L1: traduzione di S2 L2: read X IN_INT X write expr traduzione di expr OUT_INT Progetto 8

Esempi di traduzione declarations integer a,b,c. begin skip; end 0: data 2 1: halt 0 Progetto 9

Esempi di traduzione declarations integer a,b,c. begin a:=3; b:=4; read c; write a+b+c; end 0: data 2 1: ld_int 3 2: store 0 3: ld_int 4 4: store 1 5: in_int 2 6: ld_var 0 7: ld_var 1 8: add 0 9: ld_var 2 10: add 0 11: out_int 0 12: halt 0 Progetto 10

Esempi di traduzione declarations integer a,b,c. begin a:=3; b:=4; c:=a*b; while (c>0) do write c; c:=c-1; od end 0: data 2 1: ld_int 3 2: store 0 3: ld_int 4 4: store 1 5: ld_var 0 6: ld_var 1 7: mult 0 8: store 2 9: ld_var 2 10: ld_int 0 11: gt 0 12: jmp_false 20 13: ld_var 2 14: out_int 0 15: ld_var 2 16: ld_int 1 17: sub 0 18: store 2 19: goto 9 20: halt 0 Progetto 11

Esempi di traduzione declarations integer a,b,c. begin a:=3; b:=4; read c; if (c < 4) then write a; else write b; fi; end 0: data 2 1: ld_int 3 2: store 0 3: ld_int 4 4: store 1 5: in_int 2 6: ld_var 2 7: ld_int 4 8: lt 0 9: jmp_false 13 10: ld_var 0 11: out_int 0 12: goto 15 13: ld_var 1 14: out_int 0 15: halt 0 Progetto 12

Ingresso per flex DIGIT [0-9] ID [a-z][a-z0-9]* %% ":=" { return(assgnop); } {DIGIT}+ { yylval.intval = atoi( yytext ); return(number); } do { return(do); } od { return(od); } else { return(else); } end { return(end_program); } fi { return(fi); } if { return(if); } begin { return(begin_program); } integer { return(integer); } declarations { return(declarations); } read { return(read); } skip { return(skip); } then { return(then); } while { return(while); } write { return(write); } {ID} { yylval.id = (char *) strdup(yytext); return(identifier); } [ \t\n]+ /* consuma i separatori */. { return(yytext[0]); } Progetto 13

Ingresso per bison (token) %union semrec{ /* I record semantici */ int intval; /* Valori Interi */ char *id; /* Identificatori */ lbs *lbls; /* Per backpatching */ } %start program %token <intval> NUMBER /* Intero in Simple */ %token <id> IDENTIFIER /* Identificatore in Simple */ %token <lbls> IF WHILE /* For backpatching labels */ %token SKIP THEN ELSE FI DO OD END_PROGRAM %token INTEGER READ WRITE DECLARATIONS BEGIN_PROGRAM %token ASSGNOP %left '-' '+' %left '*' '/' %right '^' Progetto 14

Ingresso per bison (sintassi) program : DECLARATIONS declarations BEGIN_PROGRAM { gen_code( DATA, reserve_data_location()-1); } commands END_PROGRAM { gen_code(halt,0); YYACCEPT; } ; declarations : /* empty */ INTEGER id_seq IDENTIFIER '.' { insert( $3 ); } ; id_seq : /* empty */ id_seq IDENTIFIER ',' { insert( $2 ); } ; commands : /* empty */ commands command ';' ; Progetto 15

Ingresso per bison (sintassi) command : SKIP READ IDENTIFIER { context_check( READ_INT, $2 ); } WRITE exp { gen_code( WRITE_INT, 0 ); } IDENTIFIER ASSGNOP exp { context_check( STORE, $1 ); } IF exp { $1 = (lbs *) newlblrec(); $1->for_jmp_false=reserve_code_loc(); } THEN commands { $1->for_goto = reserve_code_loc(); } ELSE { gen_back_code( $1->for_jmp_false, JMP_FALSE, current_code_loc() ); } commands FI { gen_back_code( $1->for_goto, GOTO, current_code_loc() ); } WHILE { $1 = (lbs *) newlblrec(); $1->for_goto = current_code_loc(); } exp { $1->for_jmp_false=reserve_code_loc(); } DO commands OD { gen_code( GOTO, $1->for_goto ); gen_back_code( $1->for_jmp_false, JMP_FALSE, current_code_loc() ); } ; Progetto 16

Ingresso per bison (sintassi) command : SKIP READ IDENTIFIER { context_check( READ_INT, $2 ); } WRITE exp { gen_code( WRITE_INT, 0 ); } IDENTIFIER ASSGNOP exp { context_check( STORE, $1 ); } IF exp { $1 = (lbs *) newlblrec(); $1->for_jmp_false=reserve_code_loc(); } THEN commands { $1->for_goto = reserve_code_loc(); } ELSE { gen_back_code( $1->for_jmp_false, JMP_FALSE, current_code_loc() ); } commands FI { gen_back_code( $1->for_goto, GOTO, current_code_loc() ); } WHILE { $1 = (lbs *) newlblrec(); $1->for_goto = current_code_loc(); } exp { $1->for_jmp_false=reserve_code_loc(); } DO commands OD { gen_code( GOTO, $1->for_goto ); gen_back_code( $1->for_jmp_false, JMP_FALSE, current_code_loc() ); } ; Progetto 17

Backpatching typedef struct{ /* Etichette per i dati, if e while */ int for_goto; int for_jmp_false; } lbs; int current_code_loc(){ return code_offset; } int reserve_code_loc(){ return code_offset++; } Progetto 18

Symbol table symrec *identifier; /* Elemento della tabella dei simboli */ symrec *sym_table = NULL; /* puntatore a tabella dei simboli */ symrec * putsym (char *sym_name) { symrec *ptr; ptr = (symrec *) malloc (sizeof(symrec)); ptr->name = (char *) malloc (strlen(sym_name)+1); strcpy (ptr->name,sym_name); ptr->offset = reserve_data_location(); ptr->next = (symrec *)sym_table; sym_table = ptr; return ptr; } symrec * getsym (char *sym_name) { symrec *ptr; for (ptr=sym_table; ptr!=null; ptr=(symrec *)ptr->next ) if (strcmp (ptr->name,sym_name) == 0) return ptr; return NULL; } Progetto 19

Code generator char *op_name[17]={"halt", "store", "jmp_false", "goto", "data",...}; int data_offset = 0, code_offset = 0; int reserve_data_location() { return data_offset++; } int current_code_loc() { return code_offset; } int reserve_code_loc() { return code_offset++; } void gen_code( code_ops operation, int arg ){ setopinstruction(code_offset,operation); setarginstruction(code_offset++,arg); } void gen_back_code( int addr, code_ops operation, int arg ){ setopinstruction(addr,operation); setarginstruction(addr,arg); } void print_code(){ int i; for (i=0; i < code_offset; i++) printf("%3ld: %-10s%4ld\n", i, op_name[(int) getopinstruction(i)], getarginstruction(i)); } Progetto 20