options { STATIC = false; JAVA_UNICODE_ESCAPE = true; } PARSER_BEGIN(Parser) import java.io.*; import edu.neu.ccs.demeterf.*; import edu.neu.ccs.demeterf.util.Util; import edu.neu.ccs.demeterf.control.*; import edu.neu.ccs.demeter.*; public class Parser { // oit is uugly. Why isn't there a Character.valueOf(String)? static char unescapifyChar(String s) { char c = s.charAt(0); if (c == '\\') { switch (s.charAt(1)) { case 'n': c = '\n'; break; case 't': c = '\t'; break; case 'b': c = '\b'; break; case 'r': c = '\r'; break; case 'f': c = '\f'; break; case '\\': c = '\\'; break; case '\'': c = '\''; break; case '\"': c = '\"'; break; default: c = (char) Integer.parseInt(s.substring(1, s.length()), 8); break; } } return c; } // Even uglier... static String unescapify(String s) { char str[] = new char[s.length()]; int i = 0, o = 0; while (i < s.length()) { char c = s.charAt(i++); if (c == '\\') { int j = i + 1; while (j < s.length() && Character.digit(s.charAt(j), 8) != -1) { j++; } c = unescapifyChar(s.substring(i-1, j)); i = j; } str[o++] = c; } return String.valueOf(str, 0, o); } } PARSER_END(Parser) Main _Main() : { Main it = null; Exp _e; } { { it=new Main(); } _e=_Exp() { it.set_e(_e); } { return it; } } Exp _Exp() : { Exp it = null; } { ( it=_Var() | it=_Num() | it=_If() | it=_Lambda() | it=_Call() | it=_Op() | it=_Bool() | it=_LetRec() ) { return it; } } void common_Exp(Exp it) : { } { { } } LetRec _LetRec() : { LetRec it = null; Arg _bind; Exp _e; Exp _body; } { { it=new LetRec(); } "(letrec" "(" _bind=_Arg() { it.set_bind(_bind); } _e=_Exp() { it.set_e(_e); } ")" _body=_Exp() { it.set_body(_body); } ")" common_Exp(it) { return it; } } Lambda _Lambda() : { Lambda it = null; Arg _formal; Exp _body; } { { it=new Lambda(); } "(lambda" "(" _formal=_Arg() { it.set_formal(_formal); } ")" _body=_Exp() { it.set_body(_body); } ")" common_Exp(it) { return it; } } Var _Var() : { Var it = null; } { ( it=_Sym() | it=_Addr() ) { return it; } } void common_Var(Var it) : { } { common_Exp(it) { } } Sym _Sym() : { Sym it = null; Ident _name; } { { it=new Sym(); } _name=_Ident() { it.set_name(_name); } common_Var(it) { return it; } } Addr _Addr() : { Addr it = null; Integer _offset; } { { it=new Addr(); } "{" _offset=_Integer() { it.set_offset(_offset); } "}" common_Var(it) { return it; } } Arg _Arg() : { Arg it = null; Type _type; Sym _sym; } { { it=new Arg(); } _type=_Type() { it.set_type(_type); } _sym=_Sym() { it.set_sym(_sym); } { return it; } } Num _Num() : { Num it = null; Integer _value; } { { it=new Num(); } _value=_Integer() { it.set_value(_value); } common_Exp(it) { return it; } } Bool _Bool() : { Bool it = null; } { ( it=_True() | it=_False() ) { return it; } } void common_Bool(Bool it) : { } { common_Exp(it) { } } True _True() : { True it = null; } { { it=new True(); } "#t" common_Bool(it) { return it; } } False _False() : { False it = null; } { { it=new False(); } "#f" common_Bool(it) { return it; } } If _If() : { If it = null; Exp _cond; Exp _then; Exp _otherwise; } { { it=new If(); } "(if" _cond=_Exp() { it.set_cond(_cond); } _then=_Exp() { it.set_then(_then); } _otherwise=_Exp() { it.set_otherwise(_otherwise); } ")" common_Exp(it) { return it; } } Call _Call() : { Call it = null; Exp _proc; ExpList _args; } { { it=new Call(); } "(" _proc=_Exp() { it.set_proc(_proc); } _args=_ExpList() { it.set_args(_args); } ")" common_Exp(it) { return it; } } Op _Op() : { Op it = null; } { ( it=_Plus() | it=_Minus() | it=_Mult() | it=_Div() | it=_Less() | it=_Greater() | it=_Or() | it=_And() | it=_Eq() | it=_Print() ) { return it; } } void common_Op(Op it) : { } { common_Exp(it) { } } Plus _Plus() : { Plus it = null; } { { it=new Plus(); } "+" common_Op(it) { return it; } } Minus _Minus() : { Minus it = null; } { { it=new Minus(); } "-" common_Op(it) { return it; } } Div _Div() : { Div it = null; } { { it=new Div(); } "/" common_Op(it) { return it; } } Mult _Mult() : { Mult it = null; } { { it=new Mult(); } "*" common_Op(it) { return it; } } Less _Less() : { Less it = null; } { { it=new Less(); } "<" common_Op(it) { return it; } } Greater _Greater() : { Greater it = null; } { { it=new Greater(); } ">" common_Op(it) { return it; } } Or _Or() : { Or it = null; } { { it=new Or(); } "or" common_Op(it) { return it; } } And _And() : { And it = null; } { { it=new And(); } "and" common_Op(it) { return it; } } Eq _Eq() : { Eq it = null; } { { it=new Eq(); } "=" common_Op(it) { return it; } } Print _Print() : { Print it = null; Type _type; } { { it=new Print(); } "print<" _type=_Type() { it.set_type(_type); } ">" common_Op(it) { return it; } } Type _Type() : { Type it = null; } { ( it=_BoolT() | it=_NumT() | it=_FuncT() ) { return it; } } void common_Type(Type it) : { } { { } } BoolT _BoolT() : { BoolT it = null; } { { it=new BoolT(); } "bool" common_Type(it) { return it; } } NumT _NumT() : { NumT it = null; } { { it=new NumT(); } "int" common_Type(it) { return it; } } FuncT _FuncT() : { FuncT it = null; TypeList _args; Type _ret; } { { it=new FuncT(); } "(" _args=_TypeList() { it.set_args(_args); } "-> " _ret=_Type() { it.set_ret(_ret); } ")" common_Type(it) { return it; } } SymList _SymList() : { SymList it = null; } { ( it=_SymCons() | it=_SymEmpty() ) { return it; } } void common_SymList(SymList it) : { } { { } } SymCons _SymCons() : { SymCons it = null; Sym _first; SymList _rest; } { { it=new SymCons(); } _first=_Sym() { it.set_first(_first); } _rest=_SymList() { it.set_rest(_rest); } common_SymList(it) { return it; } } SymEmpty _SymEmpty() : { SymEmpty it = null; } { { it=new SymEmpty(); } common_SymList(it) { return it; } } ArgList _ArgList() : { ArgList it = null; } { ( it=_ArgCons() | it=_ArgEmpty() ) { return it; } } void common_ArgList(ArgList it) : { } { { } } ArgCons _ArgCons() : { ArgCons it = null; Arg _first; ArgList _rest; } { { it=new ArgCons(); } "(" _first=_Arg() { it.set_first(_first); } ")" _rest=_ArgList() { it.set_rest(_rest); } common_ArgList(it) { return it; } } ArgEmpty _ArgEmpty() : { ArgEmpty it = null; } { { it=new ArgEmpty(); } common_ArgList(it) { return it; } } ExpList _ExpList() : { ExpList it = null; } { ( it=_ExpCons() | it=_ExpEmpty() ) { return it; } } void common_ExpList(ExpList it) : { } { { } } ExpCons _ExpCons() : { ExpCons it = null; Exp _first; ExpList _rest; } { { it=new ExpCons(); } _first=_Exp() { it.set_first(_first); } _rest=_ExpList() { it.set_rest(_rest); } common_ExpList(it) { return it; } } ExpEmpty _ExpEmpty() : { ExpEmpty it = null; } { { it=new ExpEmpty(); } common_ExpList(it) { return it; } } TypeList _TypeList() : { TypeList it = null; } { ( it=_TypeCons() | it=_TypeEmpty() ) { return it; } } void common_TypeList(TypeList it) : { } { { } } TypeCons _TypeCons() : { TypeCons it = null; Type _first; TypeList _rest; } { { it=new TypeCons(); } _first=_Type() { it.set_first(_first); } _rest=_TypeList() { it.set_rest(_rest); } common_TypeList(it) { return it; } } TypeEmpty _TypeEmpty() : { TypeEmpty it = null; } { { it=new TypeEmpty(); } common_TypeList(it) { return it; } } boolean _boolean() : { Token t; }{ ( t= { return true; } | t= { return false; } ) } char _char() : { Token t; } { t= { String s = t.image; return unescapifyChar(s.substring(1, s.length()-1)); } } byte _byte() : { int i; } { i=_int() { return (byte) i; } } short _short() : { int i; } { i=_int() { return (short) i; } } int _int() : { Number num; } { num=_Number() { return num.intValue(); } } long _long() : { Number num; } { num=_Number() { return num.longValue(); } } float _float() : { Number num; } { num=_Number() { return num.floatValue(); } } double _double() : { Number num; } { num=_Number() { return num.doubleValue(); } } Boolean _Boolean() : { Token t; }{ ( t= { return Boolean.TRUE; } | t= { return Boolean.FALSE; } ) } Character _Character() : { char c; } { c=_char() { return new Character(c); } } Integer _Integer() : { int i; } { i = _int() { return new Integer(i); } } Long _Long() : { long l; } { l=_long() { return new Long(l); } } Float _Float() : { float f; } { f=_float() { return new Float(f); } } Double _Double() : { double d; } { d=_double() { return new Double(d); } } Number _Number() : { Token t; String s = null; int radix = 0; Number num = null; } { ( ( t= { s = t.image; radix = 10; } | t= { // Strip off the "0x". s = t.image.substring(2, t.image.length()); radix = 16; } | t= { s = t.image; radix = 8; } ) { switch (s.charAt(s.length()-1)) { case 'l': case 'L': s = s.substring(0, s.length()-1); num = new Long(new java.math.BigInteger(s, radix).longValue()); break; default: num = new Integer(new java.math.BigInteger(s, radix).intValue()); break; } } | t= { s = t.image; switch (s.charAt(s.length()-1)) { case 'd': case 'D': num = Double.valueOf(s.substring(0, s.length()-1)); break; case 'f': case 'F': num = Float.valueOf(s.substring(0, s.length()-1)); break; default: num = Float.valueOf(s); break; } } ) { return num; } } String _String() : { Token t; } { t= { String s = t.image; return unescapify(s.substring(1, s.length()-1)); } } StringBuffer _StringBuffer() : { String s; } { s=_String() { return new StringBuffer(s); } } Ident _Ident() : { Token t; } { t= { return new Ident(t.image); } } Text _Text() : { Token t; } { t= { String s = t.image; return new Text(s.substring(2, s.length()-2)); } } Line _Line() : { Token t; } { { token_source.SwitchTo(1); } t= { return new Line(t.image); } } Word _Word() : { Token t; } { { token_source.SwitchTo(2); } t= { return new Word(t.image); } } // Lexical specification (largely taken from Java.jack): SKIP : { " " | "\t" | "\n" | "\r" | <"//" (~["\n","\r"])* ("\n"|"\r\n")> | <"/*" (~["*"])* "*" (~["/"] (~["*"])* "*")* "/"> } TOKEN : { /* LITERALS */ < DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* (["l","L"])? > | < HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ (["l","L"])? > | < OCTAL_LITERAL: "0" (["0"-"7"])* (["l","L"])? > | < FLOATING_POINT_LITERAL: (["0"-"9"])+ "." (["0"-"9"])+ ()? (["f","F","d","D"])? | "." (["0"-"9"])+ ()? (["f","F","d","D"])? | (["0"-"9"])+ (["f","F","d","D"])? | (["0"-"9"])+ ()? ["f","F","d","D"] > | < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ > | < CHARACTER_LITERAL: "'" ( (~["\'","\\","\n","\r"]) | ("\\" ( ["n","t","b","r","f","\\","\'","\""] | ["0"-"7"] ( ["0"-"7"] )? | ["0"-"3"] ["0"-"7"] ["0"-"7"] ) ) ) "'" > | < STRING_LITERAL: "\"" ( (~["\"","\\","\n","\r"]) | ("\\" ( ["n","t","b","r","f","\\","\'","\""] | ["0"-"7"] ( ["0"-"7"] )? | ["0"-"3"] ["0"-"7"] ["0"-"7"] ) ) )* "\"" > | < TEXT_LITERAL: ( "(@" (~["@"])* ( "@" ~[")"] (~["@"])* )* "@)" ) | ( "{{" (~["}"])* ( "}" ~["}"] (~["}"])* )* "}}" ) > | < TRUE: "true" > | < FALSE: "false" > } TOKEN : { /* IDENTIFIERS */ < IDENTIFIER: (|)* > | < #LETTER: [ "\u0024", "\u0041"-"\u005a", "\u005f", "\u0061"-"\u007a", "\u00c0"-"\u00d6", "\u00d8"-"\u00f6", "\u00f8"-"\u00ff", "\u0100"-"\u1fff", "\u3040"-"\u318f", "\u3300"-"\u337f", "\u3400"-"\u3d2d", "\u4e00"-"\u9fff", "\uf900"-"\ufaff" ] > | < #DIGIT: [ "\u0030"-"\u0039", "\u0660"-"\u0669", "\u06f0"-"\u06f9", "\u0966"-"\u096f", "\u09e6"-"\u09ef", "\u0a66"-"\u0a6f", "\u0ae6"-"\u0aef", "\u0b66"-"\u0b6f", "\u0be7"-"\u0bef", "\u0c66"-"\u0c6f", "\u0ce6"-"\u0cef", "\u0d66"-"\u0d6f", "\u0e50"-"\u0e59", "\u0ed0"-"\u0ed9", "\u1040"-"\u1049" ] > } TOKEN : { < LINE: (~["\n","\r"])* > : DEFAULT } SKIP : { " " | "\t" | "\n" | "\r" } TOKEN : { < WORD: (~[" ","\t","\n","\r"])* > : DEFAULT }