package lexical; /** * A lexical analyser. * * This Java code is automatically generated from the file * lexical/Lexer.lex through the JLex utility. * The following author hence is not completely responsible for its content * * @author Fausto Spoto */ import java.io.FileInputStream; import errorMsg.ErrorMsg; import syntactical.sym; import symbol.Symbol; public %% %function nextToken %type java_cup.runtime.Symbol %char %{ /** * * Records that a new line character has been found in the source file * */ private void newline() { errorMsg.newline(yychar); } /** * * Reports an error at a given position in the source file * * @param pos the position where the message must be reported, * from the beginning of the source file * @param msg the message to be reported * */ private void err(int pos, String msg) { errorMsg.error(pos,msg); } /** * * Reports an error at the current position in the source file * * @param msg the message to be reported * */ private void err(String msg) { err(yychar,msg); } /** * * Creates a token of a given kind and with a given lexical value * * @param kind the kind of token to be created, as enumerated in * syntactical/sym.java * @param value the lexical value associated with the token. * It may be null * */ private java_cup.runtime.Symbol tok(int kind, Object value) { return new java_cup.runtime.Symbol(kind, yychar, yychar+yylength(), value); } /** * * The error reporting utility used during the compilation * */ private ErrorMsg errorMsg; /** * Yields the error reporting utility used during the lexical analysis. * * @return the error reporting utility */ public ErrorMsg getErrorMsg() { return errorMsg; } /** * Creates a lexical analyser for a given class name. * * @param className the name of the class to be lexically analysed * (without the trailing .kit) * @throws java.io.FileNotFoundException if the source file cannot be found */ public Lexer(Symbol className) throws java.io.FileNotFoundException { this(); String fileName = className + ".kit"; errorMsg = new ErrorMsg(fileName); FileInputStream inp; try { inp = new FileInputStream(fileName); } catch (java.io.FileNotFoundException e) { errorMsg.error(-1,"Cannot find \"" + fileName + "\""); throw e; } yy_reader = new java.io.BufferedReader(new java.io.InputStreamReader(inp)); } /** * Creates a lexical analyser for a given source file. * * @param fileName the name of the file to be lexically analysed * (with the trailing .kit) * @throws java.io.FileNotFoundException if the source file cannot be found */ public Lexer(String fileName) throws java.io.FileNotFoundException { this(Symbol.mk(fileName.endsWith(".kit") ? fileName.substring(0,fileName.length() - 4) : fileName)); } // ritorna il simbolo della classe che si sta parsando public Symbol parsedClass() { return Symbol.mk (errorMsg.getFileName().substring(0,errorMsg.getFileName().length() - 4)); } int commentCount = 0; int myNum; String myString = ""; %} %eofval{ { if (commentCount != 0) err("Unclosed comment"); return tok(sym.EOF, null); } %eofval} %state STRING %state COMMENT %% "\"" {myString=""; yybegin(STRING);} [ \t\f] {} "/*" {commentCount++; yybegin(COMMENT);} \n {newline();} while {return tok(sym.WHILE, null);} for {return tok(sym.FOR, null);} method {return tok(sym.METHOD, null);} field {return tok(sym.FIELD, null);} constructor {return tok(sym.CONSTRUCTOR, null);} array {return tok(sym.ARRAY, null);} if {return tok(sym.IF, null);} then {return tok(sym.THEN, null);} else {return tok(sym.ELSE, null);} of {return tok(sym.OF, null);} as {return tok(sym.AS, null);} nil {return tok(sym.NIL, null);} class {return tok(sym.CLASS, null);} extends {return tok(sym.EXTENDS, null);} new {return tok(sym.NEW, null);} return {return tok(sym.RETURN, null);} boolean {return tok(sym.BOOLEAN, null);} int {return tok(sym.INT, null);} float {return tok(sym.FLOAT, null);} void {return tok(sym.VOID, null);} true {return tok(sym.TRUE, null);} false {return tok(sym.FALSE, null);} super {return tok(sym.SUPER, null);} same {return tok(sym.SAME, null);} "," {return tok(sym.COMMA, null);} ";" {return tok(sym.SEMICOLON, null);} "(" {return tok(sym.LPAREN, null);} ")" {return tok(sym.RPAREN, null);} "[" {return tok(sym.LBRACK, null);} "]" {return tok(sym.RBRACK, null);} "{" {return tok(sym.LBRACE, null);} "}" {return tok(sym.RBRACE, null);} "." {return tok(sym.DOT, null);} "+" {return tok(sym.PLUS, null);} "-" {return tok(sym.MINUS, null);} "*" {return tok(sym.TIMES, null);} "/" {return tok(sym.DIVIDE, null);} "=" {return tok(sym.EQ, null);} "!=" {return tok(sym.NEQ, null);} "<" {return tok(sym.LT, null);} "<=" {return tok(sym.LE, null);} ">=" {return tok(sym.GE, null);} ">" {return tok(sym.GT, null);} "&" {return tok(sym.AND, null);} "|" {return tok(sym.OR, null);} "!" {return tok(sym.NOT, null);} ":=" {return tok(sym.ASSIGN, null);} "*/" {err("Unopen comment");} [a-zA-Z][a-zA-Z0-9_]* {return tok(sym.ID, yytext());} [0-9]+ {return tok(sym.INTEGER, new Integer(yytext()));} [0-9]*"."[0-9]+ {return tok(sym.FLOATING, new Float(yytext()));} . {err("Unmatched input");} \\n {myString+="\n";} \\t {myString+="\t";} \\[0-9][0-9][0-9] {myNum=(yytext().charAt(1)-48)*100+ (yytext().charAt(2)-48)*10+ (yytext().charAt(3)-48); if (myNum>255) err("Overflow in ASCII Code"); else myString += (char)myNum;} \\\\ {myString += "\\";} \\[ \t\f\n]+\\ {} "\\"" {myString += "\"";} "\\'" {myString += "'";} "\"" {yybegin(YYINITIAL); return tok(sym.STRING, myString);} \n {newline(); myString += "\n";} . {myString += yytext();} "*/" {commentCount--; if (commentCount==0) yybegin(YYINITIAL);} "/*" {commentCount++;} \n {newline();} . {}