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();}
. {}