import java.io.*; // For FileInputStream and its exceptions. /* ========================================================================= */ class Token { public int type; public String spelling; public int first, last; public Token(int t, int f, int l) { type = t; first = f; last = l; } public Token(int t, int f, int l, String s) { type = t; first = f; last = l; spelling = s; } public static String spellingOf(int t) { // We use a function instead of an array spellingOf[] because // we don't have control over the order JavaCUP uses for these enums. switch (t) { case Sym.STATIC : return "static"; case Sym.EOF : return "end-of-file"; case Sym.INT : return "int"; case Sym.BOOLEAN : return "boolean"; case Sym.OR : return "||"; case Sym.ELSE : return "else"; case Sym.CLASS : return "class"; case Sym.error : return "*error*"; case Sym.MINUS : return "-"; case Sym.COMMA : return ","; case Sym.TIMES : return "*"; case Sym.LPAREN : return "("; case Sym.RPAREN : return ")"; case Sym.SEMICOLON: return ";"; case Sym.IF : return "if"; case Sym.ID : return "Id"; case Sym.GETS : return "="; case Sym.WHILE : return "while"; case Sym.MOD : return "%"; case Sym.DIV : return "/"; case Sym.UNINIT : return "*uninit*"; case Sym.AND : return "&&"; case Sym.LBRACE : return "{"; case Sym.PLUS : return "+"; case Sym.RBRACE : return "}"; case Sym.EQUALS : return "=="; case Sym.NUM : return "Num"; case Sym.BOOL : return "Bool"; case Sym.RETURN : return "return"; case Sym.NOTEQUAL : return "!="; default : return "*out of range*"; } } public String toString() { if (spelling != null) return "\"" + spelling + "\""; else return spelling; } } /* ========================================================================= */ %% /* JLex directives */ %class Lexer %function next %type Token %eofval{ return new Token(Sym.EOF, yychar, yychar); %eofval} %char ALPHA = [A-Za-z] DIGIT = [0-9] WORD = {ALPHA}({ALPHA}|{DIGIT}|_)* SPACE = [\ \t\b\r\n] COMMENT1 = [\/][\*]([^\*]|[\*][^\/])*[\*][\/] COMMENT2 = [\/][\/].* COMMENT = ({COMMENT1}|{COMMENT2}) %% {SPACE} { } {COMMENT} { } class { return new Token(Sym.CLASS, yychar, yychar+4); } else { return new Token(Sym.ELSE, yychar, yychar+3); } if { return new Token(Sym.IF, yychar, yychar+1); } int { return new Token(Sym.INT, yychar, yychar+2); } boolean { return new Token(Sym.BOOLEAN, yychar, yychar+6); } return { return new Token(Sym.RETURN, yychar, yychar+5); } static { return new Token(Sym.STATIC, yychar, yychar+5); } while { return new Token(Sym.WHILE, yychar, yychar+4); } true { return new Token(Sym.BOOL, yychar, yychar+3, yytext()); } false { return new Token(Sym.BOOL, yychar, yychar+4, yytext()); } {WORD} { return new Token(Sym.ID, yychar, yychar+yytext().length()-1, yytext()); } {DIGIT}+ { return new Token(Sym.NUM, yychar, yychar+yytext().length()-1, yytext()); } ";" { return new Token(Sym.SEMICOLON, yychar, yychar); } "," { return new Token(Sym.COMMA, yychar, yychar); } "(" { return new Token(Sym.LPAREN, yychar, yychar); } ")" { return new Token(Sym.RPAREN, yychar, yychar); } "{" { return new Token(Sym.LBRACE, yychar, yychar); } "}" { return new Token(Sym.RBRACE, yychar, yychar); } "=" { return new Token(Sym.GETS, yychar, yychar); } "+" { return new Token(Sym.PLUS, yychar, yychar); } "-" { return new Token(Sym.MINUS, yychar, yychar); } "*" { return new Token(Sym.TIMES, yychar, yychar); } "/" { return new Token(Sym.DIV, yychar, yychar); } "%" { return new Token(Sym.MOD, yychar, yychar); } "==" { return new Token(Sym.EQUALS, yychar, yychar+1); } "!=" { return new Token(Sym.NOTEQUAL, yychar, yychar+1); } "||" { return new Token(Sym.OR, yychar, yychar+1); } "&&" { return new Token(Sym.AND, yychar, yychar+1); } . { return new Token(Sym.error, yychar, yychar+yytext().length()-1, yytext()); }