/* Esercitazione 2 - Esercizio 1 (Scanner) */ /* Inclusione della libreria di cup per l'integrazione con JFlex */ import java_cup.runtime.*; %% /* JFlex produrra' in uscita una classe dal nome Lexer.class */ %class Lexer /* Per la compatibilita'  con Cup */ %cup /* Viene settata la variabile yyline con il numero di linea attualente letta dallo scanner: tale variabile potra' essere passata allo scanner assieme ai Token riconosciuti */ %line /* Opzionale e abbastanza inutile in questo esercizio: serve per fare in modo che JFlex setti in yycolumn il numero di colonna dell'ultimo carattere riconosciuto dallo scanner */ %column /* Stato di tipo esclusivo comment */ %xstate comment /* Definizione delle costanti */ sign_modifier_token = signed|unsigned type_token = int|long|short|float|double|char leng_modifier_token = long|short storage_spec_token = extern|register|auto|static void_token = void ws = [ \t]+ const = ('+'|'-')?[0-9]+ floating = ('+'|'-')?(([0-9]+'.'[0-9]*)|([0-9]*'.'[0-9]+))(e|E('+'|'-')?[0-9]+)? direttiva = "#"(include|define).*\n stringa = \"([^\n\r\"]+|\\\")*\" identificatore = [A-Za-z_][A-Za-z0-9_]* relop = ("=="|">="|"<="|"<"|">"|"!=") logop = ("||"|"&&") assop = ("+="|"-=") %% {ws} {;} \n {;} /* Le direttive non sono state analizzate perche' in un compilatore esse vengono trattate da un modulo a parte che prende il nome di per-processor. Esso genera un codice intermedio che viene passato al vero e proprio compilatore */ {direttiva} {;} /* Commenti - posso eliminarli */ "/*" {yybegin(comment);} [^*]* {;} "*"+[^*/]* {;} "*"+"/" {yybegin(YYINITIAL);} if {return new Symbol(sym.IF); } else {return new Symbol(sym.ELSE); } while {return new Symbol(sym.WHILE); } switch {return new Symbol(sym.SWITCH); } case {return new Symbol(sym.CASE); } break {return new Symbol(sym.BREAK); } for {return new Symbol(sym.FOR); } return {return new Symbol(sym.RETURN); } default {return new Symbol(sym.DEFAULT); } "++" {return new Symbol(sym.INCR); } "--" {return new Symbol(sym.DECR); } {assop} {return new Symbol(sym.ASSOP); } {relop} {return new Symbol(sym.RELOP); } {logop} {return new Symbol(sym.LOGOP); } "+" {return new Symbol(sym.PLUS); } "-" {return new Symbol(sym.MINUS); } "*" {return new Symbol(sym.TIMES); } "/" {return new Symbol(sym.DIVIDE); } "%" {return new Symbol(sym.MOD); } "=" {return new Symbol(sym.UGUALE); } "(" {return new Symbol(sym.TONDAOPEN); } ")" {return new Symbol(sym.TONDACLOSED); } "[" {return new Symbol(sym.QUADRAOPEN); } "]" {return new Symbol(sym.QUADRACLOSED); } "{" {return new Symbol(sym.GRAFFAOPEN); } "}" {return new Symbol(sym.GRAFFACLOSED); } ";" {return new Symbol(sym.PUNTOEVIRGOLA); } "," {return new Symbol(sym.VIRGOLA); } ":" {return new Symbol(sym.DUEPUNTI); } {sign_modifier_token} {return new Symbol(sym.SIGN_MODIFIER); } {leng_modifier_token} {return new Symbol(sym.LENG_MODIFIER); } {storage_spec_token} {return new Symbol(sym.STORAGE_SPEC); } {type_token} {return new Symbol(sym.TYPE); } {void_token} {return new Symbol(sym.VOID); } {stringa} {return new Symbol(sym.STRINGCONST);} {const}|{floating} {return new Symbol(sym.CONST);} {identificatore} {return new Symbol(sym.ID); /* Si ricorda che questa regola deve comparire dopo le altre regole, in particolare quelle relative alle parole chiave, altrimenti a causa delle regole di risoluzione delle ambiguita' tutte le keyword verrebbero erroneamente riconosciute come identificatori */}