options { STATIC=false; } PARSER_BEGIN(PL0Parser) package pl0front; import java.io.FileReader; import coins.HirRoot; import coins.IoRoot; import coins.SymRoot; import coins.ir.IrList; import coins.ir.hir.BlockStmt; import coins.ir.hir.Exp; import coins.ir.hir.HIR0; import coins.ir.hir.Program; import coins.ir.hir.Stmt; import coins.ir.hir.SubpDefinition; import coins.sym.Const; import coins.sym.IntConst; import coins.sym.NamedConst; import coins.sym.Subp; import coins.sym.SubpType; import coins.sym.Sym0; import coins.sym.SymTable; import coins.sym.Type; import coins.sym.Var; public class PL0Parser { private SymRoot symRoot; // シンボル情報のルート private Sym0 sym; // Sym0オブジェクト生成用のインスタンス private HirRoot hirRoot; // HIR情報のルート private HIR0 hir; // HIR0オブジェクト生成用のインスタンス private IoRoot ioRoot; // 入出力のルート private Subp printfSym = null; // ライブラリ関数printfのシンボル private Const dStringConst = null; // 文字列定数"%d " private Const nStringConst = null; // 文字列定数"\n" private Type typeInt; public PL0Parser(SymRoot sRoot, HirRoot hRoot, IoRoot iRoot, FileReader reader) { this(reader); 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); // プログラムのルートのノードとしてprogramノードを作る printfSym = sym.defineSubp("printf".intern(), typeInt); //int printf()のシンボル printfSym.addParamType(sym.pointerType(symRoot.typeChar)); printfSym.setOptionalParam(); printfSym.setVisibility(Sym0.SYM_EXTERN); printfSym.closeSubpPrototype(); dStringConst = sym.stringConst("%d".intern()); // 定数"%d" nStringConst = sym.stringConst("\n".intern()); // 定数"\n" } } PARSER_END(PL0Parser) SKIP : { } TOKEN : { | | | | | | | | | | | | } TOKEN : { ( | )*> | )+> | <#LETTER: ["a"-"z","A"-"Z"]> | <#DIGIT: ["0"-"9"]> } void program() : { Subp mainSubp; BlockStmt mainBlock; } { { mainSubp = sym.defineSubp("main".intern(), typeInt); mainSubp.setVisibility(Sym0.SYM_PUBLIC); SymTable lSymTable = symRoot.symTableCurrent.pushSymTable(mainSubp); mainSubp.closeSubpHeader(); } mainBlock = block(0) "." { SubpDefinition mainSubpDef = hir.subpDefinition(mainSubp, symRoot.symTableCurrent); mainSubpDef.setHirBody(mainBlock); ((Program)hirRoot.programRoot).addSubpDefinition(mainSubpDef); } } BlockStmt block(int level) : { BlockStmt blockStmt = hir.blockStmt(null); Stmt stmt; } { (decl(level))* stmt = statement() { blockStmt.addLastStmt(stmt); return blockStmt; } } void decl(int level) : { } { constDecl() { } | varDecl() { } | funcDecl(level) { } } void constDecl() : { } { constDef() ( "," constDef() )* ";" { } } void constDef() : { Token tId, tNum; } { tId = "=" tNum = { IntConst intConst = sym.intConst(Integer.parseInt(tNum.image), typeInt); NamedConst nc = sym.namedConst(tId.image.intern(), intConst); } } void varDecl() : { Token t; } { t = { sym.defineVar(t.image.intern(), typeInt); } ( "," t = { sym.defineVar(t.image.intern(), typeInt); } )* ";" { } } void funcDecl(int level) : { Token t; Subp funcSubp; BlockStmt funcBlock; } { t = { if (level >= 1) ioRoot.msgFatal.put("unimplemented nest of functions"); funcSubp = sym.defineSubp(t.image.intern(), typeInt); SymTable lSymTable = symRoot.symTableCurrent.pushSymTable(funcSubp); } "(" [ t = { funcSubp.addParam(sym.defineParam(t.image.intern(), typeInt)); } ( "," t = { funcSubp.addParam(sym.defineParam(t.image.intern(), typeInt)); } )* ] ")" { funcSubp.closeSubpHeader(); } funcBlock = block(level+1) ";" { SubpDefinition funcSubpDef = hir.subpDefinition(funcSubp, symRoot.symTableCurrent); funcSubpDef.setHirBody(funcBlock); ((Program)hirRoot.programRoot).addSubpDefinition(funcSubpDef); symRoot.symTableCurrent.popSymTable(); } } Stmt statement() : { Token t; Exp exp; BlockStmt innerBlock; Stmt stmt; IrList lParamList; Exp printfNode; } { [ t = ":=" exp = expression() { Sym0 lVar = symRoot.symTableCurrent.search(t.image.intern()); if ( !(lVar instanceof Var) ) { ioRoot.msgRecovered.put("undeclared " + t.image); // エラーメッセージを出し lVar = sym.defineVar(t.image.intern(), typeInt); //仮に登録する } stmt = hir.assignStmt( hir.varNode((Var)lVar), exp); stmt.setLineNumber(t.beginLine); return stmt; } | t = { innerBlock = hir.blockStmt(null); innerBlock.setLineNumber(t.beginLine);} stmt = statement() { innerBlock.addLastStmt(stmt); } (";" stmt = statement() { innerBlock.addLastStmt(stmt); } )* { return innerBlock; } | t = exp = condition() stmt = statement() { stmt = hir.ifStmt(exp, stmt, null); stmt.setLineNumber(t.beginLine); return stmt; } | t = exp = condition() stmt = statement() { stmt = hir.whileStmt(exp, stmt); stmt.setLineNumber(t.beginLine); return stmt; } | t = exp = expression() { stmt = hir.returnStmt(exp); stmt.setLineNumber(t.beginLine); return stmt; } | t = exp = expression() { lParamList = hir.irList(); lParamList.add(hir.decayExp(hir.constNode(dStringConst))); lParamList.add(exp); printfNode = hir.exp(HIR0.OP_ADDR, hir.subpNode(printfSym)); stmt = hir.callStmt(printfNode, lParamList); stmt.setLineNumber(t.beginLine); return stmt; } | t = { lParamList = hir.irList(); lParamList.add(hir.decayExp(hir.constNode(nStringConst))); printfNode = hir.exp(HIR0.OP_ADDR, hir.subpNode(printfSym)); stmt = hir.callStmt(printfNode, lParamList); stmt.setLineNumber(t.beginLine); return stmt; } ] { return null; } } Exp condition() : { Exp exp, exp1; int op; } { exp = expression() { exp1 = hir.exp(HIR0.OP_AND, exp, hir.constNode(symRoot.intConst1)); return hir.exp(HIR0.OP_CMP_EQ, exp1, hir.constNode(symRoot.intConst1)); } | exp = expression() ("=" { op = HIR0.OP_CMP_EQ; } | "<>" { op = HIR0.OP_CMP_NE; } | "<" { op = HIR0.OP_CMP_LT; } | "<=" { op = HIR0.OP_CMP_LE; } | ">" { op = HIR0.OP_CMP_GT; } | ">=" { op = HIR0.OP_CMP_GE; } ) exp1 = expression() { return hir.exp(op, exp, exp1); } } Exp expression() : { boolean prefixOp = false; int op; Exp exp, exp1; } { [("-" { prefixOp = true; } | "+")] exp = term() { if (prefixOp) exp = hir.exp(HIR0.OP_NEG, exp); } (("-" { op = HIR0.OP_SUB; } | "+" { op = HIR0.OP_ADD; } ) exp1 = term() { exp = hir.exp(op, exp, exp1); } )* { return exp; } } Exp term(): { Exp exp, exp1; int op; } { exp = factor() (("*" { op = HIR0.OP_MULT; } | "/" { op = HIR0.OP_DIV; } ) exp1 = factor() { exp = hir.exp(op, exp, exp1); } )* { return exp; } } Exp factor() : { Token t; Exp exp; IrList aParamList = hir.irList(); } { LOOKAHEAD(2) t = "(" [ exp = expression() { aParamList.add(exp); } ("," exp = expression() { aParamList.add(exp); } )*] ")" { Sym0 lSym = symRoot.symTableCurrent.search(t.image.intern(), Sym0.KIND_SUBP); if (lSym == null) { ioRoot.msgError.put("undefined function " + t.image); return hir.constNode(symRoot.intConst1); } else { Subp lSubp = (Subp)lSym; IrList fParamList = ((SubpType)lSubp.getSymType()).getParamTypeList(); if ( fParamList.size() != aParamList.size()) ioRoot.msgError.put("unmatched parameters of " + t.image); return hir.functionExp(hir.exp(HIR0.OP_ADDR, hir.subpNode(lSubp)), aParamList); } } | t = { IntConst intConst = sym.intConst(Integer.parseInt(t.image), typeInt); return hir.constNode(intConst); } | t = { Sym0 lVar = symRoot.symTableCurrent.search(t.image.intern()); if ( lVar instanceof Var ) { return hir.varNode((Var)lVar); } if (lVar == null ){ lVar = symRoot.symTableConst.searchLocal (t.image.intern(), Sym0.KIND_NAMED_CONST); if ( lVar != null ) return hir.constNode(((NamedConst)lVar).getConstValue()); } // else ioRoot.msgRecovered.put("undeclared " + t.image); lVar = sym.defineVar(t.image.intern(), typeInt); return hir.varNode((Var)lVar); } | "(" exp = expression() ")" { return exp; } }