// Yylex
//
// Copyright 2004, 2005 Christoph Csallner and Yannis Smaragdakis.
//
// 2005-06-14 Christoph Csallner
// Check how ESC creates identifiers:
//   escjava.translate.UniqName
//   escjava.translate.GC
//   escjava.translate.Translate
//   escjava.translate.TrAnExpr
//   escjava.backpred.Backpred
//   escjava.tc.Types
//   escjava.AnnotationHandler
// Add support for:
//   T_.TYPE, C_
// Switch to ESC 2.0a8 from 2.0a7:
//   _array, |equals##state#java.lang.Object|, |o:54.65.41%2|
// 2004-03-01 Christoph Csallner
// Started, this file is input for JLex:
//   http://www.cs.princeton.edu/~appel/modern/java/JLex/.

package edu.gatech.cc.cnc;

import java_cup.runtime.Symbol;

%%
%cup
%public

ALPHA		= [A-Za-z_$]
ALPHANUM	= [A-Za-z_$0-9]
IDENT	    = {ALPHA}{ALPHANUM}*

POSINT      = [0-9]+
POSTFIX     = #[a-z]|#{POSINT}|<{POSINT}>|%{POSINT}|@{POSINT}|-{POSINT}|"."{POSINT}|:{POSINT}|:unknown|".."|@pre|@loopold
TYPEID      = T_((".")?{IDENT})*("$"({POSINT}|{IDENT}))*


%init{
	/* Regular expressions in JLex should not contain any whitespace,
	 * as JLex interprets whitespace as end-of-regexp. */
%init}
%%
[ \t\r\n\f]+		{ /* skip each whitespace */ }

"("					{ return new Symbol(sym.LPAREN); }
")"					{ return new Symbol(sym.RPAREN); }

">="                { return new Symbol(sym.GEQ, String.valueOf(sym.GEQ)); }
">"	                { return new Symbol(sym.G,   String.valueOf(sym.G)); }
"<="				{ return new Symbol(sym.LEQ, String.valueOf(sym.LEQ)); }
"<"					{ return new Symbol(sym.L,   String.valueOf(sym.L)); }
"EQ"				{ return new Symbol(sym.EQ,  String.valueOf(sym.EQ)); }
"NEQ"				{ return new Symbol(sym.NEQ, String.valueOf(sym.NEQ)); }
"<:"                { /*Backpred.saySubType*/ return new Symbol(sym.LESSCOLON); }
"is"                { return new Symbol(sym.IS, yytext()); }
"-"					{ return new Symbol(sym.MINUS, String.valueOf(sym.MINUS)); }
"+"                 { return new Symbol(sym.PLUS,  String.valueOf(sym.PLUS)); }
"*"                 { return new Symbol(sym.STAR,  String.valueOf(sym.STAR)); }
"/"                 { return new Symbol(sym.SLASH, String.valueOf(sym.SLASH)); }

"TRUE"				{ return new Symbol(sym.TRUE, yytext()); }
"null"              { return new Symbol(sym.NULL); }
"this"              { /*GC.thisvar*/ return new Symbol(sym.THIS); }
"|@true|"           { return new Symbol(sym.ATTRUE); }
"|bool$false|"      { return new Symbol(sym.BOOLFALSE); }
"F_NaN"             { return new Symbol(sym.FLOATNAN, yytext()); }
"F_Infinity"        { return new Symbol(sym.FLOATINF, yytext()); }
"|F_-Infinity|"     { return new Symbol(sym.FLOATNEGINF, yytext()); }
"NOT"               { return new Symbol(sym.NOT); }
"BOOLNOT"           { return new Symbol(sym.BOOLNOT); }
"select"            { return new Symbol(sym.SELECT, yytext()); }
"_array"            { return new Symbol(sym.ARRAY, yytext()); }
"elemtype"          { return new Symbol(sym.ELEMTYPE, yytext()); }
"arrayLength"       { return new Symbol(sym.ARRAYLENGTH, yytext()); }
"typeof"            { return new Symbol(sym.TYPEOF, yytext()); }
"|getClass#|"       { return new Symbol(sym.TYPEOF, yytext()); }
"|java.lang.Class#_getClass|"   { return new Symbol(sym.TYPEOF, yytext()); }


{POSINT}   	        { return new Symbol(sym.POSINT, yytext()); }
-{POSINT}   	    { return new Symbol(sym.NEGINT, yytext()); }
("pos")({POSINT}) 	{ return new Symbol(sym.POSINT, yytext().substring(3, yytext().length())); }
("neg")({POSINT}) 	{ return new Symbol(sym.NEGINT, "-" +yytext().substring(3, yytext().length())); }

"|"F_{POSINT}"."{POSINT}(E{POSINT})?"|"     { return new Symbol(sym.POSFLOAT, yytext().substring(3, yytext().length()-1)); }
"|"S_{POSINT}"."{POSINT}("."{POSINT})?"|"   { return new Symbol(sym.STRINGLIT, yytext().substring(1, yytext().length()-1)); }
"|"L_{POSINT}"."{POSINT}("."{POSINT})?"|"   { /*GC.blockL*/ return new Symbol(sym.LABEL, yytext().substring(1, yytext().length()-1)); }
"|"C_{POSINT}"."{POSINT}("."{POSINT})?"|"   { /*Translate.continueLabel*/ return new Symbol(sym.LABEL, yytext().substring(1, yytext().length()-1)); }

{TYPEID}|"|"{TYPEID}"|"                     { /*UniqName.type*/ return new Symbol(sym.TYPEIDENT, ParseFct.stripBarFromType(yytext())); }
elems|"|"elems({POSTFIX})+"|"               { /*GC.elemsvar*/ 	return new Symbol(sym.ELEMS, yytext()); }
{IDENT}                                     { return new Symbol(sym.IDENT, yytext()); }

"|"{IDENT}({POSTFIX}|!|#|=|:|"[]"|"."|{IDENT})*"|"    { return new Symbol(sym.IDENTESC, yytext().substring(1, yytext().length()-1)); }
.                   { System.out.println("Unmatched input: " +yytext()); }