📄 parser.cup~3~
字号:
package parser;import java_cup.runtime.*;import java.util.*;import java.lang.String;import CatDecaf.SymTable.*;import CatDecaf.IR.*;import CatDecaf.Utilities.Debugger.*;//import SMA5503.IR.*;/* user code portion */parser code {:public static ClassProgram classProgram;public static int curType, curOffset;public static SymbolTable curST, curScopeST;public static MethodDescriptor curMD;public static String infile;public static boolean debug; // = Compiler.PARSER_DEBUG;public void startParse(String i) throws Exception{ parser.infile = i; this.parse(); } /** Report a non fatal error (or warning). This method takes a message * string and an additional object (to be used by specializations * implemented in subclasses). Here in the base class a very simple * implementation is provided which simply prints the message to * System.err. * * @param message an error message. * @param info an extra object reserved for use by specialized subclasses. */ public void report_error(String message, Object info) { ClassProgram.numOfError++; ClassProgram.semanticCheck=false; if (info instanceof Symbol) if (((Symbol)info).left != -1) System.out.println(parser.infile + ":"+ ((Symbol)info).left + ": Syntax error: '" + ((Symbol)info).value+"'"); //else System.err.println(""); //else System.err.println(""); } /** Overriding original error message to handle the errors just before EOF */ public void report_fatal_error( String message, Object info) throws java.lang.Exception { //ClassProgram.numOfError++; ClassProgram.semanticCheck=false; System.out.println(parser.infile + ":" + Scanner.lineno + ": Syntax error: missing '}'"); /* stop parsing */ done_parsing(); }:}action code {:/* This flag is used for printing DEBUG messages */public static boolean debug = parser.debug;public static Stmt stmtTemp = null;/* This function handles conversion of +ve integers and detection of over-sized +ve integers *//* This function handles conversion of -ve integers and detection of over-sized -ve integers */public static Exp convPos( Exp e, int lineNo ){ //if not a direct interger, not handling at all if (!(e instanceof LtrInt)) return e; LtrInt ltrInt = (LtrInt)e; //if already converted, not handling again, if (ltrInt.converted()) return e; int intNum; String intStr = ltrInt.getIntString(); try{ if (intStr.startsWith("0x")){ //always take as Uminus a Positive intNum = Integer.parseInt(intStr.substring(2), 16); //if (debug) System.out.println("Processed integer (+ve integer) at line (" + lineNo + "): " + intStr + "-> " + intNum); }else{ //decimal is always a negative number here intNum = Integer.parseInt(intStr); //if (debug) System.out.println("Processed integer (+ve integer) at line (" + lineNo + "): " + intStr); } ltrInt.convNum(intNum); return ltrInt; }catch(NumberFormatException err){ System.err.println(parser.infile + ": "+ lineNo +": Integer above upper bound: '"+intStr+"'"); ClassProgram.numOfError++; ltrInt.convNum(1); //default negative number return ltrInt; }}/* This function handles conversion of -ve integers and detection of over-sized -ve integers */public static Exp convNeg( Exp e, int lineNo ){ //if not a direct interger, not handling at all if (!(e instanceof LtrInt)) return new ExpUMinus((Exp)e); LtrInt ltrInt = (LtrInt)e; //if already converted, not handling again, if (ltrInt.converted()) return new ExpUMinus((Exp)e); int intNum; String intStr = ltrInt.getIntString(); try{ if (intStr.startsWith("0x")){ //always take as Uminus a Positive intNum = Integer.parseInt("-"+intStr.substring(2), 16); //if (debug) System.out.println("Processed integer (-ve integer) at line (" + lineNo + "): " + intStr + " -> " + intNum); }else{ //decimal is always a negative number here intNum = Integer.parseInt("-"+intStr); //if (debug) System.out.println("Processed integer (-ve integer) at line (" + lineNo + "): -" + intStr); } ltrInt.convNum(intNum); return ltrInt; }catch(NumberFormatException err){ System.err.println(parser.infile + ": "+ lineNo +": Integer below lower bound: '-"+intStr+"'"); ClassProgram.numOfError++; ltrInt.convNum(-1); //default negative number return ltrInt; }}:}/* Terminals (tokens returned by the scanner). */terminal ASSIGN,UMINUS;terminal COMMA,SEMI, LPAREN, RPAREN, LSQUARE, RSQUARE, LCURLY, RCURLY;terminal SHIFTLEFT, SHIFTRIGHT, PLUS, MINUS, MULT, DIVIDE, MOD;terminal LESSTHAN, GREATERTHAN,LTOE,GTOE,EQUAL,NOTEQUAL,AND,OR;terminal BOOLEAN, CALLOUT, CLASS, ELSE, EXTENDS, BOOLFALSE, FOR, IF, INT, NEW;terminal NULL, RETURN, THIS, BOOLTRUE, VOID, WHILE;terminal CHARLIT, ERROR_TYPE, NO_TYPE;terminal String ID, STRINGLIT, INTLIT;/* Non terminals */nonterminal program, field_decl_list, method_decl_list, field_decl, method_decl;nonterminal type;nonterminal global_var_list, local_var;nonterminal method_param_list, method_param;nonterminal block, var_decl_list, statement_list, var_decl, statement, local_var_list;nonterminal expr, location, method_call, literal, bool_literal;/*nonterminal bit_op, arith_op, rel_op, eq_op, bin_op, cond_op;*/nonterminal expr_list, callout_arg_list, callout_arg;nonterminal empty, prog_content, global_var, method_decl_content;nonterminal else_content, return_content, method_call_content, callout_content, expr_bin_op_expr;/* precedence */precedence left OR;precedence left AND;precedence left EQUAL, NOTEQUAL;precedence nonassoc LESSTHAN, GREATERTHAN,LTOE,GTOE;precedence left PLUS, MINUS;precedence left MULT, DIVIDE, MOD;precedence left UMINUS;precedence left SHIFTLEFT, SHIFTRIGHT;/* The grammar */program ::= CLASS ID:classname {:if(!classname.equals("Program")) { ClassProgram.numOfError++; ClassProgram.semanticCheck=false; System.out.println(parser.infile + ":"+ classnameleft +": Invalid class name '" + classname +"'"); } :} LCURLY:line {: if(debug) System.out.println("At Line ("+lineleft+"): program -> class Program { }"); parser.classProgram = new ClassProgram(); parser.classProgram.fieldVar.assertFieldST(); parser.curOffset = 0; :} prog_content:p RCURLY {: parser.classProgram.methods.checkIfMainExists(); RESULT = p; :} | error ;prog_content ::= field_decl_list:fdl {: RESULT = new IrProg(((FdDeclList)fdl).reverse(),null); :} | method_decl_list:mdl {: RESULT = new IrProg(null, ((MdDeclList)mdl).reverse()); :} | field_decl_list:fdl method_decl_list:mdl {: RESULT = new IrProg( ((FdDeclList)fdl).reverse(), ((MdDeclList)mdl).reverse()); :} | empty;field_decl_list ::= field_decl_list:fdl_lst field_decl:fdl {: parser.classProgram.fieldVar.setSymbolTableSize(parser.curOffset); RESULT = new FdDeclList((FdDecl)fdl,(FdDeclList)fdl_lst); :} | field_decl:fdl {: parser.classProgram.fieldVar.setSymbolTableSize(parser.curOffset); RESULT = new FdDeclList((FdDecl)fdl,null); :} ;field_decl ::= type:t global_var_list:gld_lst SEMI:line {: if(debug) System.out.println("At Line ("+lineleft+"): field_decl -> int/boolean/array "); RESULT = new FdDecl((Typ)t, ((GlbVarList)gld_lst).reverse()); :}| error;global_var_list ::= global_var_list:glb_lst COMMA global_var:glb_var {: RESULT = new GlbVarList((GlbVar)glb_var,(GlbVarList)glb_lst); :} | global_var:glb_var {: RESULT = new GlbVarList((GlbVar)glb_var,null); :} ;global_var ::= ID:id {: IDDescriptor idd = new IDDescriptor(id, parser.curType); idd.assertFieldDescriptor(); idd.setOffset(parser.curOffset); parser.curOffset += 4; // 32 bits for each field variable parser.classProgram.fieldVar.addDescriptor(idd); RESULT = new GlbVarId( new Identifier(id, sym.NO_TYPE) ); :} |ID:id LSQUARE INTLIT:s RSQUARE {: LtrInt sInt = (LtrInt)convPos(new LtrInt(s), sleft); int arraySize = sInt.ltrInt_; IDDescriptor idd = new IDDescriptor(id, parser.curType, arraySize); idd.assertFieldDescriptor(); idd.setOffset(parser.curOffset); parser.curOffset += 4 * arraySize + 4; //extra 4 bytes to store array size parser.classProgram.fieldVar.addDescriptor(idd); RESULT = new GlbVarArray(new Identifier(id, sym.NO_TYPE), sInt); //Array size error message reported in here :} |ID:id LSQUARE MINUS INTLIT:s RSQUARE //should be an error here {: LtrInt sInt = (LtrInt)convNeg(new LtrInt(s), sleft); int arraySize = sInt.ltrInt_; IDDescriptor idd = new IDDescriptor(id, parser.curType, arraySize); idd.assertFieldDescriptor(); idd.setOffset(parser.curOffset); parser.curOffset += 4 * arraySize + 4; parser.classProgram.fieldVar.addDescriptor(idd); RESULT = new GlbVarArray(new Identifier(id, sym.NO_TYPE), sInt); //Array size error message reported in here :};type ::= INT {: parser.curType = sym.INT; RESULT = new TypInt(); :} | BOOLEAN {: parser.curType = sym.BOOLEAN; RESULT = new TypBool(); :} ;method_decl_list ::= method_decl_list:mdl_lst method_decl:mdl {: RESULT = new MdDeclList((MdDecl)mdl,(MdDeclList)mdl_lst); :} | method_decl:mdl {: RESULT = new MdDeclList((MdDecl)mdl,null); :} ;method_decl ::= type:t ID:id {: parser.curMD = new MethodDescriptor(id, parser.curType); parser.curST = new SymbolTable(); parser.curOffset = 0;:} LPAREN:line {: if(debug) System.out.println("At Line ("+lineleft+"): method_decl -> int/boolean"); :} method_decl_content:md_par_lst RPAREN {: parser.curST.setParent(parser.classProgram.fieldVar); parser.curST.assertParamST(); parser.curMD.setParam(parser.curST); parser.curScopeST = parser.curST; parser.curMD.setParamSize(parser.curOffset); (parser.classProgram.methods).addDescriptor(parser.curMD); parser.curOffset = 0;:} block:blk {: parser.curMD.checkFoundReturnStatement(); parser.curMD.setLocalSize(parser.curOffset); RESULT = new MdDecl((Typ)t,new Identifier(id, sym.NO_TYPE),md_par_lst==null? null:((MdParaList)md_par_lst).reverse(),(Block)blk, parser.curMD.getLocalSize(), parser.curMD.getMaxCallInParamSize()); :} |VOID ID:id {: parser.curMD = new MethodDescriptor(id, sym.VOID); parser.curST = new SymbolTable(); parser.curOffset = 0;:} LPAREN:line {: if(debug) System.out.println("At Line ("+lineleft+"): method_decl -> void"); :} method_decl_content:md_par_lst RPAREN {: parser.curST.setParent(parser.classProgram.fieldVar); parser.curST.assertParamST(); parser.curMD.setParam(parser.curST); parser.curScopeST = parser.curST; parser.curMD.setParamSize(parser.curOffset); (parser.classProgram.methods).addDescriptor(parser.curMD); parser.curOffset = 0; :} block:blk {: parser.curMD.setLocalSize(parser.curOffset); RESULT = new MdDecl(new TypVoid(),new Identifier(id, sym.NO_TYPE),md_par_lst==null? null:((MdParaList)md_par_lst).reverse(),(Block)blk, parser.curMD.getLocalSize(), parser.curMD.getParamSize()); :};method_decl_content ::= method_param_list: md_para_lst {: RESULT = md_para_lst; :} | empty ;method_param_list
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -