%{ package simple; import java.io.IOException; import java.util.Iterator; import java.util.ListIterator; import coins.HirRoot; import coins.IoRoot; import coins.SymRoot; import coins.ir.IrList; import coins.ir.hir.BlockStmt; import coins.ir.hir.ConstNode; import coins.ir.hir.Exp; import coins.ir.hir.HIR0; import coins.ir.hir.HirSeq; import coins.ir.hir.IfStmt; import coins.ir.hir.LoopStmt; import coins.ir.hir.Program; import coins.ir.hir.Stmt; import coins.ir.hir.SubpDefinition; import coins.ir.hir.VarNode; import coins.sym.CharConst; import coins.sym.Const; import coins.sym.FloatConst; import coins.sym.IntConst; import coins.sym.Label; import coins.sym.Param; import coins.sym.PointerType; import coins.sym.StringConst; import coins.sym.Subp; import coins.sym.SubpType; import coins.sym.Sym0; import coins.sym.SymTable; import coins.sym.Type; import coins.sym.Var; import coins.sym.VectorType; public class Parser { %} %token IF ELSE WHILE DO FOR RETURN ASSIGN STATIC %token SWITCH CASE DEFAULT BREAK CONTI READ WRITE %token RELOP ADDOP MULOP TYPE CNUM %token ID NUM RNUM SNUM %type type_spec decl %type declatr %type dim_list %type sub_list %type p_list %type p_decl %type f_head %type arg_list %type func_def %type program glbl_decl %type case_item default_item %type assign stmt opt_assign if_part %type s_list block %type expr tst_expr %left LOR %left LAND %left RELOP %left ADDOP %left MULOP %right '!' UM %% program : glbl_decl ; glbl_decl: { } | glbl_decl decl ';' { } | glbl_decl func_def { } | glbl_decl error ';' { yyErrorFlag = 0; } ; decl : type_spec declatr { $$ = $1; enterVar($1, $2); } | type_spec f_head { $$ = $1; makeFuncPrototype($1, $2); } | decl ',' declatr { $$ = $1; enterVar($1, $3); } | decl ',' f_head { $$ = $1; makeFuncPrototype($1, $3); } ; type_spec : TYPE { $$ = new TypeSpec($1.intValue(), false); } | STATIC TYPE { $$ = new TypeSpec($2.intValue(), true); } ; declatr : ID dim_list { $$ = new Declatr($1, $2); } ; dim_list : { $$ = new DimList(); } | '[' ']' dim_list { $$ = new DimList(0, $3); } | '[' NUM ']' dim_list { $$ = new DimList(Integer.parseInt($2), $4); } ; p_list : { $$ = hir.irList(); } | p_decl { $$ = hir.irList(); $$.add($1);} | p_list ',' p_decl { $$ = $1; $$.add($3); } ; p_decl : TYPE declatr { $$ = new PDecl($1, $2, false); } | TYPE '&' declatr { $$ = new PDecl($1, $3, true); } ; f_head : ID '(' p_list ')' { $$ = new FHead($1, $3); } ; func_def : type_spec f_head '{' { $$ = makeFuncDef($1, $2);} decl_list s_list '}' { setFuncBody($4, $6); popTable(); } ; block : '{' { openBlock(); } decl_list s_list '}' { $$ = $4; closeBlock(); } ; decl_list : | decl_list decl ';' ; s_list : stmt { $$ = makeBlockStmt($1); } | s_list stmt { $$ = addStmt($1, $2); } ; assign : ID ASSIGN expr { $$ = makeAssignStmtNode( $2.intValue(), searchAndMakeVarNode($1), $3); } | ID sub_list ASSIGN expr { $$ = makeAssignStmtNode( $3.intValue(), makeSubsNode($1, $2), $4); } opt_assign : { $$ = null; } | assign { $$ = $1; } ; stmt : block { $$ = $1; } | RETURN ';' { $$ = makeReturnStmt( $1.intValue(), null ); } | RETURN expr ';' { $$ = makeReturnStmt( $1.intValue(), $2 ); } | assign ';' { $$ = $1; } | ';' { $$ = null; } | READ ID ';' { $$ = makeReadStmtNode( $1.intValue(), searchAndMakeVarNode($2) ); } | WRITE expr ';' { $$ = makeWriteStmtNode( $1.intValue(), $2 ); } | if_part { $$ = $1; } | if_part ELSE stmt { $$ = replaceElsePart($1, $3); } | WHILE { nestIn(WHILE); } '(' expr ')' stmt { $$ = makeWhileStmt( $1.intValue(), $4, $6); } | DO { nestIn(DO); } stmt WHILE '(' expr ')' ';' { $$ = makeRepeatStmt( $1.intValue(), $3, $6); } | FOR '(' opt_assign ';' tst_expr ';' opt_assign ')' { nestIn(FOR, $3, $5, $7); } stmt { $$ = makeForStmt( $1.intValue(), $10); } | SWITCH '(' expr ')' { nestIn(SWITCH); } '{' case_list default_case '}' { $$ = makeSwitchStmt( $1.intValue(), $3); } | BREAK ';' { $$ = makeBreakStmt( $1.intValue() ); } | CONTI ';' { $$ = makeContiStmt( $1.intValue() ); } | error ';' { yyErrorFlag = 0; } ; case_list : case_item { } | case_list case_item { } ; case_item : CASE NUM ':' { $$ = addCase($2); } | case_item stmt { $$ = addCaseStmt($1, $2); } default_case : { } | default_item { } ; default_item : DEFAULT ':' { $$ = addDefault(); } | default_item stmt { $$ = addCaseStmt($1, $2); } ; if_part : IF '(' expr ')' stmt { $$ = makeIfPart( $1.intValue(), $3, $5); } ; tst_expr : { $$ = hir.trueNode(); } | expr { $$ = $1; } ; expr : expr LOR expr { $$ = makeLogicalBinaryExpNode(OR, $1, $3); } | expr LAND expr { $$ = makeLogicalBinaryExpNode(AND, $1, $3); } | expr RELOP expr { $$ = makeBinaryExpNode($2.intValue(), $1, $3); } | expr ADDOP expr { $$ = makeBinaryExpNode($2.intValue(), $1, $3); } | expr MULOP expr { $$ = makeBinaryExpNode($2.intValue(), $1, $3); } | '(' expr ')' { $$ = $2; } | ID '(' arg_list ')' { $$ = makeFunctionExp($1, $3); } | '!' expr { $$ = makeLogicalUnaryExpNode(NOT, $2); } | ADDOP expr %prec UM { if ($1.intValue() == SUB) $$ = makeUnaryExpNode(NEG, $2); else $$ = $2; } | ID sub_list { $$ = makeSubsNode($1, $2); } | ID { $$ = searchAndMakeVarNode($1); } | NUM { $$ = makeIntConstNode($1); } | SNUM { $$ = makeStringConstNode($1); } | CNUM { $$ = makeCharConstNode($1.intValue()); } | RNUM { $$ = makeFloatConstNode($1); } ; sub_list : '[' expr ']' { $$ = new SubList($2); } | '[' expr ']' sub_list { $$ = new SubList($2, $4); } arg_list : { $$ = hir.irList(); } | expr { $$ = makeAParamList($1); } | arg_list ',' expr { $$ = addAParam($1, $3); } ; %% static final int INT = Type.KIND_INT; static final int VOID = Type.KIND_VOID; static final int CHAR = Type.KIND_CHAR; static final int DOUBLE = Type.KIND_DOUBLE; static final int STRING = Type.KIND_STRING; static final int ADD = HIR0.OP_ADD; static final int SUB = HIR0.OP_SUB; static final int MUL = HIR0.OP_MULT; static final int DIV = HIR0.OP_DIV; static final int MOD = HIR0.OP_MOD; static final int NEG = HIR0.OP_NEG; static final int LT = HIR0.OP_CMP_LT; static final int LE = HIR0.OP_CMP_LE; static final int GT = HIR0.OP_CMP_GT; static final int GE = HIR0.OP_CMP_GE; static final int EQ = HIR0.OP_CMP_EQ; static final int NE = HIR0.OP_CMP_NE; static final int OR = HIR0.OP_OR; static final int AND = HIR0.OP_AND; static final int NOT = HIR0.OP_NOT; static final int ADDR = HIR0.OP_ADDR; static final int MAX_NEST = 20; private class TypeSpec { int type; boolean isStatic; TypeSpec(int t, boolean s) { type = t; isStatic = s; } } private class Declatr { String id; DimList dList; Declatr(String s, DimList d) { id = s; dList = d; } } private class DimList { int rank, dim; DimList dList; DimList() { rank = 0; dList = null; } DimList(int d, DimList list) { rank = list.rank + 1; dim = d; dList = list; } } private class SubList { Exp exp; SubList subList; SubList(Exp e) { subList = null; exp = e; } SubList(Exp e, SubList sList) { subList = sList; exp = e; } } private class FHead { String id; IrList pList; FHead(String name, IrList p) { id = name; pList = p; } } private class PDecl { Integer type; Declatr declatr; boolean isByRef; PDecl(Integer t, Declatr d, boolean b) { type = t; declatr = d; isByRef = b; } } private SymRoot symRoot; private Sym0 sym; private HirRoot hirRoot; private HIR0 hir; private IoRoot ioRoot; private Subp printfSym = null; private Subp scanfSym = null; private Const dStringConst = null; private Const dnStringConst = null; private Const fStringConst = null; private Const fnStringConst = null; private Type typeInt; private int labelCount = 1; private BseLabel[] bseLabelStack = new BseLabel[MAX_NEST]; private int stackTop = 0; private Type makeVType(DimList pDimList, Type elemType) { if (pDimList.rank == 0) return elemType; return sym.vectorType(makeVType(pDimList.dList, elemType), pDimList.dim); } private Type makeVPointerType(DimList pDimList, Type elemType) { Type lType = makeVType(pDimList, elemType); if (pDimList.rank == 0) return elemType; return sym.pointerType(lType); } private Type type(int t) { switch (t) { case INT: return symRoot.typeInt; case VOID: return symRoot.typeVoid; case CHAR: return symRoot.typeChar; case DOUBLE: return symRoot.typeDouble; default: ioRoot.msgError.put("unknown type"); return symRoot.typeVoid; } } private Type type(Integer t) { return type(t.intValue()); } private Type type(TypeSpec tSpec) { return type(tSpec.type); } private void makeFuncPrototype(TypeSpec tSpec, FHead fHead) { Subp lSubp = sym.defineSubp(fHead.id, type(tSpec)); ListIterator it = fHead.pList.iterator(); while ( it.hasNext() ) { PDecl pDecl = (PDecl)(it.next()); Type pType = makeVType(pDecl.declatr.dList, type(pDecl.type)); if (pDecl.isByRef) pType = sym.pointerType(pType); lSubp.addParamType(pType); } lSubp.closeSubpPrototype(); } private SubpDefinition makeFuncDef(TypeSpec tSpec, FHead fHead) { Subp lSubp; SymTable lSymTable; Type type = type(tSpec); SubpDefinition lSubpDef; IrList protoList = null; Sym0 proto = symRoot.symTableCurrent.search(fHead.id, Sym0.KIND_SUBP); if (proto == null) lSubp = sym.defineSubp(fHead.id, type); else { lSubp = (Subp)proto; protoList = ((SubpType)lSubp.getSymType()).getParamTypeList(); } lSymTable = symRoot.symTableCurrent.pushSymTable(lSubp); lSubpDef = hir.subpDefinition(lSubp, lSymTable); addParamDecl(lSubp, fHead.pList); lSubp.setVisibility(Sym0.SYM_PUBLIC); lSubp.closeSubpHeader(); if (protoList != null) { IrList defList = ((SubpType)lSubp.getSymType()).getParamTypeList(); if ( protoList.size() == defList.size() ) { Iterator protoIt = protoList.iterator(); Iterator defIt = defList.iterator(); while (protoIt.hasNext()){ Type pType = (Type)protoIt.next(); Type dType = (Type)defIt.next(); if ((pType != dType) && !(pType instanceof PointerType)){ ioRoot.msgError.put("unmatched parameters of " + fHead.id); break; } } } else ioRoot.msgError.put("unmatched parameters of " + fHead.id); } ((Program)hirRoot.programRoot).addSubpDefinition(lSubpDef); return lSubpDef; } private void addParamDecl(Subp subp, IrList fParams) { ListIterator it = fParams.iterator(); while ( it.hasNext() ) { PDecl pDecl = (PDecl)(it.next()); Type lType = makeVPointerType(pDecl.declatr.dList, type(pDecl.type)); Param lParam = sym.defineParam(pDecl.declatr.id, lType); if (pDecl.isByRef) { lType = sym.pointerType(lType); lParam.markAsCallByReference(); lParam.setSymType(lType); } subp.addParam(lParam); } } private void popTable() { symRoot.symTableCurrent.popSymTable(); } private void setFuncBody(SubpDefinition def, BlockStmt block) { def.setHirBody(block); } private void openBlock() { symRoot.symTableCurrent.pushSymTable(null); } private void closeBlock() { symRoot.symTableCurrent.popSymTable(); } private Exp makeFunctionExp(String id, IrList argList) { Sym0 lSym = symRoot.symTableCurrent.search(id, Sym0.KIND_SUBP); if (lSym == null) { ioRoot.msgError.put("undefined function " + id); return hir.constNode(symRoot.intConst1); } else { Subp lSubp = (Subp)lSym; IrList lParamList = ((SubpType)lSubp.getSymType()).getParamTypeList(); if (lParamList != null ) if ( lParamList.size() != argList.size()) ioRoot.msgError.put("unmatched parameters of " + id); ListIterator lIt = lParamList.iterator(); int aIndex = 0; while ( lIt.hasNext() ) { Type pType = (Type)lIt.next(); Exp arg = (Exp)argList.get(aIndex); Type aType = arg.getType(); if (pType instanceof PointerType && !(aType instanceof PointerType)) { argList.set(aIndex, makeUnaryExpNode(ADDR, arg)); pType = pType.getPointedType(); } if ((pType != aType) && !(pType instanceof PointerType)) ioRoot.msgError.put("unmatched parameter type of " + id ); aIndex++; } return hir.functionExp(hir.exp(HIR0.OP_ADDR, hir.subpNode(lSubp)), argList); } } private IrList makeAParamList(Exp exp) { IrList lParamList = hir.irList(); lParamList.add(exp); return lParamList; } private IrList addAParam(IrList list, Exp exp) { list.add(exp); return list; } class BseLabel { int stmtType; LoopStmt loopStmt; Label backLabel; Label stepLabel; Label endLabel; Label defaultLabel; BlockStmt sBlock; IrList jumpList; BseLabel(int stType){ stmtType = stType; switch (stType) { case WHILE: loopStmt = hir.whileStmt(null, null); setLabel(); break; case DO: loopStmt = hir.repeatStmt(null, null); setLabel(); break; case SWITCH: sBlock = hir.blockStmt(null); jumpList = hir.irList(); endLabel = newLabel(); defaultLabel = null; default: } } BseLabel(int t, Stmt st1, Exp exp, Stmt st2) { stmtType = t; loopStmt = hir.forStmt(st1, exp, null, st2); setLabel(); } void setLabel(){ backLabel = loopStmt.getLoopBackLabel(); stepLabel = loopStmt.getLoopStepLabel(); endLabel = loopStmt.getLoopEndLabel(); } } private void nestIn(int stType) { if (stackTop < MAX_NEST) { bseLabelStack[stackTop++] = new BseLabel(stType); } else { ioRoot.msgFatal.put("too deep nest"); System.exit(1); } } private void nestIn(int stType, Stmt st1, Exp exp, Stmt st2) { if (stackTop < MAX_NEST) { bseLabelStack[stackTop++] = new BseLabel(stType, st1, exp, st2); } else { ioRoot.msgFatal.put("too deep nest"); System.exit(1); } } private BseLabel nestOut() { BseLabel b = bseLabelStack[--stackTop]; bseLabelStack[stackTop] = null; return b; } private Label newLabel() { return sym.defineLabel(("L"+labelCount++).intern()); } private Stmt makeReturnStmt(int line, Exp exp){ Stmt rStmt = hir.returnStmt(exp); rStmt.setLineNumber(line); return rStmt; } private Stmt makeIfPart(int line, Exp exp, Stmt stmt) { Stmt ifPart = hir.ifStmt(exp, stmt, null);l ifPart.setLineNumber(line); return ifPart; } private Stmt replaceElsePart(Stmt ifPart, Stmt elsePart) { ((IfStmt)ifPart).replaceElsePart(elsePart.attachLabel(newLabel())); return ifPart; } private Stmt makeWhileStmt(int line, Exp exp, Stmt stmt) { BseLabel b = nestOut(); LoopStmt loopStmt = b.loopStmt; loopStmt.setLoopStartCondition(exp); Label bodyLabel = loopStmt.getLoopBodyLabel(); loopStmt.replaceBodyPart(hir.labeledStmt(bodyLabel, stmt)); loopStmt.setLineNumber(line); return loopStmt; } private Stmt makeRepeatStmt(int line, Stmt stmt, Exp exp) { BseLabel b = nestOut(); LoopStmt loopStmt = b.loopStmt; loopStmt.setLoopEndCondition(exp); Label bodyLabel = loopStmt.getLoopBodyLabel(); loopStmt.replaceBodyPart(hir.labeledStmt(bodyLabel, stmt)); loopStmt.setLineNumber(line); return loopStmt; } private Stmt makeForStmt(int line, Stmt stmt) { BseLabel b = nestOut(); LoopStmt loopStmt = b.loopStmt; loopStmt.addToLoopBodyPart(stmt); loopStmt.setLineNumber(line); return loopStmt; } private Stmt makeSwitchStmt(int line, Exp exp) { BseLabel b = nestOut(); Stmt sStmt = hir.switchStmt(exp, b.jumpList, b.defaultLabel, b.sBlock, b.endLabel); sStmt.setLineNumber(line); return sStmt; } private BseLabel addCase(String num) { Label lLabel = newLabel(); HirSeq lSeq = hir.hirSeq(makeIntConstNode(num), hir.labelNode(lLabel)); BseLabel b = bseLabelStack[stackTop-1]; b.jumpList.add(lSeq); b.sBlock.addLastStmt(hir.labeledStmt(lLabel, null)); return b; } private BseLabel addCaseStmt(BseLabel b, Stmt stmt) { b.sBlock.addLastStmt(stmt); return b; } private BseLabel addDefault() { Label lLabel = newLabel(); BseLabel b = bseLabelStack[stackTop-1]; b.sBlock.addLastStmt(hir.labeledStmt(lLabel, null)); b.defaultLabel = lLabel; return b; } private Stmt makeBreakStmt(int line) { if (stackTop > 0) { BseLabel b = bseLabelStack[stackTop-1]; Stmt stmt = hir.jumpStmt(b.endLabel); stmt.setLineNumber(line); return stmt; } else { ioRoot.msgError.put("Illegal use of break statement"); return null; } } private Stmt makeContiStmt(int line) { for (int i = stackTop-1; i >= 0; i--) { BseLabel b = bseLabelStack[i]; if (b.stmtType != SWITCH) { Stmt stmt = hir.jumpStmt(b.stepLabel); stmt.setLineNumber(line); return stmt; } } ioRoot.msgError.put("Illegal use of continue statement"); return null; } private Var enterVar(TypeSpec tSpec, Declatr declatr) { Type lType = type(tSpec); Sym0 lSym = sym.defineVar(declatr.id, lType); if (lSym == null) { ioRoot.msgError.put(declatr.id + " declared twice"); return null; } Var lVar = (Var)lSym; lVar.setSymType(makeVType(declatr.dList, lType)); if (tSpec.isStatic || symRoot.symTableCurrent == symRoot.symTableRoot) lVar.setStorageClass(Var.VAR_STATIC); return lVar; } private Var enterSimpleVar(int t, String id) { Var lVar = sym.defineVar(id, type(t)); if (symRoot.symTableCurrent == symRoot.symTableRoot) lVar.setStorageClass(Var.VAR_STATIC); lVar.setSymType(type(t)); return lVar; } private Exp searchAndMakeVarNode(String id) { Sym0 lVar = symRoot.symTableCurrent.search(id); if ( lVar instanceof Param ) { Param lParam = (Param)lVar; if (lParam.isCallByReference()) return hir.contentsExp(hir.varNode(lParam)); } if ( lVar instanceof Var ) { Var aVar = (Var)lVar; Type aType = aVar.getSymType(); if (aType instanceof VectorType) return hir.decayExp(hir.varNode(aVar)); return hir.varNode(aVar); } else { ioRoot.msgRecovered.put("undeclared " + id); lVar = enterSimpleVar(INT, id); return hir.varNode((Var)lVar); } } private Exp makeSubsNode(String id, SubList sList) { Sym0 lVar = symRoot.symTableCurrent.search(id); Type lType = lVar.getSymType(); Exp vNode; if (lVar instanceof Param ) { if (lType instanceof PointerType) { vNode = hir.undecayExp(hir.varNode((Param)lVar), 1, 0); lType = ((PointerType)lType).getPointedType(); vNode.setType(lType); } else vNode = hir.varNode((Var)lVar); } else if (lVar instanceof Var) vNode = hir.varNode((Var)lVar); else { ioRoot.msgError.put("undeclared array " + id); return null; } SubList lList = sList; Exp sExp = vNode; do { if ( ! (lType instanceof VectorType) ) { ioRoot.msgError.put("unmatched subscript " + id); return sExp; } // lType = ((VectorType)lType).getElemType(); // sExp = hir.subscriptedExp(sExp, lList.exp, lType.getSizeExp()); sExp = hir.subscriptedExp(sExp, lList.exp); lList = lList.subList; } while (lList != null); return sExp; } private Exp makeStringConstNode(String s) { StringConst sConst = sym.stringConst(s); return hir.decayExp(hir.constNode(sConst)); } private ConstNode makeCharConstNode(int c) { CharConst cConst = sym.charConst((char)c, symRoot.typeChar); return hir.constNode(cConst); } private ConstNode makeFloatConstNode(String rnum) { FloatConst dConst = sym.floatConst(Double.parseDouble(rnum), symRoot.typeDouble); return hir.constNode(dConst); } private ConstNode makeIntConstNode(String num) { IntConst intConst = sym.intConst(Integer.parseInt(num), symRoot.typeInt); return hir.constNode(intConst); } private Exp makeLogicalBinaryExpNode(int op, Exp exp1, Exp exp2) { if (exp1.getType() != symRoot.typeBool || exp2.getType() != symRoot.typeBool ) { ioRoot.msgError.put("illegal logical expression "); return hir.constNode(symRoot.boolConstFalse); } return hir.exp(op, exp1, exp2); } private Exp makeBinaryExpNode(int op, Exp exp1, Exp exp2) { Type exp1Type = exp1.getType(); Type exp2Type = exp2.getType(); int rank1 = exp1Type.getTypeRank(); int rank2 = exp2Type.getTypeRank(); if ( rank1 > rank2 ) exp2 = hir.convExp(exp1Type, exp2); else if ( rank1 < rank2 ) exp1 = hir.convExp(exp2Type, exp1); return hir.exp(op, exp1, exp2); } private Exp makeLogicalUnaryExpNode(int op, Exp exp) { if (exp.getType() != symRoot.typeBool ) { ioRoot.msgError.put("illegal logical expression "); return hir.constNode(symRoot.boolConstFalse); } return hir.exp(op, exp); } private Exp makeUnaryExpNode(int op, Exp exp1) { return hir.exp(op, exp1); } private Stmt makeAssignStmtNode(int line, Exp exp1, Exp exp2) { Type exp1Type = exp1.getType(); Type exp2Type = exp2.getType(); int rank1 = exp1Type.getTypeRank(); int rank2 = exp2Type.getTypeRank(); if (rank1 < rank2) { ioRoot.msgError.put("illegal assignment"); return null; } if ( rank1 > rank2 ) exp2 = hir.convExp(exp1Type, exp2); Stmt stmt = hir.assignStmt(exp1, exp2); stmt.setLineNumber(line); return stmt; } private Stmt makeWriteStmtNode(int line, Exp exp) { IrList paramList = hir.irList(); Type eType = exp.getType(); if ( eType == symRoot.typeInt ) paramList.add(hir.decayExp(hir.constNode(dnStringConst))); // "%d\n" else if ( eType == symRoot.typeDouble ) paramList.add(hir.decayExp(hir.constNode(fnStringConst))); // "%f\n" paramList.add(exp); Exp printfNode = hir.exp(ADDR, hir.subpNode(printfSym)); Stmt stmt = hir.callStmt(printfNode, paramList); stmt.setLineNumber(line); return stmt; } private Stmt makeReadStmtNode(int line, Exp var) { IrList paramList = hir.irList(); Type eType = var.getType(); if ( eType == symRoot.typeInt ) paramList.add(hir.decayExp(hir.constNode(dStringConst))); // "%d" else if ( eType == symRoot.typeDouble ) paramList.add(hir.decayExp(hir.constNode(fStringConst))); // "%f" paramList.add(makeUnaryExpNode(ADDR, var)); Exp scanfNode = hir.exp(ADDR, hir.subpNode(scanfSym)); Stmt stmt = hir.callStmt(scanfNode, paramList); stmt.setLineNumber(line); return stmt; } private BlockStmt makeBlockStmt(Stmt stmt) { return hir.blockStmt(stmt); } private BlockStmt addStmt(BlockStmt st_list, Stmt stmt) { st_list.addLastStmt(stmt); return st_list; } public Parser(SymRoot sRoot, HirRoot hRoot, IoRoot iRoot) { symRoot = sRoot; sym = (Sym0)symRoot.sym; hirRoot = hRoot; hir = (HIR0)hirRoot.hir; ioRoot = iRoot; typeInt = symRoot.typeInt; hirRoot.programRoot = hir.program(null, symRoot.symTableRoot, null, null); printfSym = sym.defineSubp("printf".intern(), typeInt); printfSym.addParamType(sym.pointerType(symRoot.typeChar)); printfSym.setOptionalParam(); printfSym.setVisibility(Sym0.SYM_EXTERN); printfSym.closeSubpPrototype(); scanfSym = sym.defineSubp("scanf".intern(), typeInt); scanfSym.addParamType(sym.pointerType(symRoot.typeChar)); scanfSym.setOptionalParam(); scanfSym.setVisibility(Sym0.SYM_EXTERN); scanfSym.closeSubpPrototype(); dStringConst = sym.stringConst("%d".intern()); dnStringConst = sym.stringConst("%d\n".intern()); fStringConst = sym.stringConst("%f".intern()); fnStringConst = sym.stringConst("%f\n".intern()); } }