options { UNICODE_INPUT=true; } PARSER_BEGIN(Compile) package pl0; import java.io.*; public class Compile { static boolean objCode; static CodeGen codeGen; static final int MINERROR = 3; static final int FIRSTADDR = 2; public Compile(CodeGen c, boolean o, FileReader reader){ this(reader); codeGen = c; objCode = o; } } PARSER_END(Compile) SKIP : { } TOKEN : { | | | | | | | | | | | | } TOKEN : { ( | )*> | )+> | <#LETTER: ["a"-"z","A"-"Z","\u3041"-"\u3093","\u4e00"-"\u9fa5"]> | <#DIGIT: ["0"-"9"]> } boolean program() : { } { { System.out.println("start compilation" ); Table.blockBegin(FIRSTADDR); } block(0) "." { if (objCode) codeGen.listCode(); System.out.println("end compilation" ); return GetSource.errorN() < MINERROR; } } void block(int pIndex) : { int backP; } { { backP = codeGen.genCodeV(CodeGen.jmp, 0); } ( decl() )* { codeGen.backPatch(backP); if(pIndex != 0) Table.changeV(pIndex, codeGen.nextCode()); codeGen.genCodeV(CodeGen.ict, Table.frameL()); } statement() { codeGen.genCodeR(); Table.blockEnd(); } } void decl() : { } { constDecl() | varDecl() | funcDecl() } void constDecl() : { } { constDef() ( "," constDef() )* ";" } void constDef() : { Token tId, tNum; } { tId = "=" tNum = { int num = Integer.parseInt(tNum.image); Table.enterTconst(tId.image.intern(), num); } } void varDecl() : { Token t; } { t = { Table.enterTvar(t.image.intern()); } ( "," t = { Table.enterTvar(t.image.intern()); } )* ";" } void funcDecl() : { Token t; int fIndex; } { t = { fIndex = Table.enterTfunc(t.image.intern(), codeGen.nextCode()); Table.blockBegin(FIRSTADDR); } "(" [ t = { Table.enterTpar(t.image.intern()); } ( "," t = { Table.enterTpar(t.image.intern()); } )* ] ")" { Table.endpar(); } block(fIndex) ";" } void statement() : { Token t; int backP, backP2; } { [ t = ":=" expression() { int tIndex = Table.searchT(t.image.intern(), GetSource.varId); int k = Table.kindT(tIndex); if (k != GetSource.varId && k != GetSource.parId) System.out.println("Lefthand "+t.image+" is not var or par"); codeGen.genCodeT(CodeGen.sto, tIndex); } | statement() (";" statement())* | condition() { backP = codeGen.genCodeV(CodeGen.jpc, 0); } statement() { codeGen.backPatch(backP); } | { backP2 = codeGen.nextCode(); } condition() { backP = codeGen.genCodeV(CodeGen.jpc, 0); } statement() { codeGen.genCodeV(CodeGen.jmp, backP2); codeGen.backPatch(backP); } | expression() { codeGen.genCodeR(); } | expression() { codeGen.genCodeO(CodeGen.wrt); } | { codeGen.genCodeO(CodeGen.wrl); } ] } void condition() : { int op; } { expression() { codeGen.genCodeO(CodeGen.odd); } | expression() ("=" { op = CodeGen.eq; } | "<>" { op = CodeGen.neq; } | "<" { op = CodeGen.ls; } | "<=" { op = CodeGen.lseq; } | ">" { op = CodeGen.gr; } | ">=" { op = CodeGen.greq; } ) expression() { codeGen.genCodeO(op); } } void expression() : { boolean prefixOp = false; int op; } { [("-" { prefixOp = true; } | "+")] term() { if (prefixOp) codeGen.genCodeO(CodeGen.neg); } (("-" { op = CodeGen.sub; } | "+" { op = CodeGen.add; } ) term() { codeGen.genCodeO(op); } )* } void term(): { int op; } { factor() (("*" { op = CodeGen.mul; } | "/" { op = CodeGen.div; } ) factor() { codeGen.genCodeO(op); } )* } void factor() : { Token t; int pCount = 0; } { LOOKAHEAD(2) t = "(" [ expression() { pCount++; } ("," expression() { pCount++; } )*] ")" { int tIndex = Table.searchT(t.image.intern(), GetSource.funcId); if (Table.pars(tIndex) != pCount) System.out.println("unmatched parameters of " + t.image); codeGen.genCodeT(CodeGen.cal, tIndex); } | t = { codeGen.genCodeV(CodeGen.lit, Integer.parseInt(t.image)); } | t = { int tIndex = Table.searchT(t.image.intern(), GetSource.varId); int k = Table.kindT(tIndex); switch (k) { case GetSource.varId: case GetSource.parId: codeGen.genCodeT(CodeGen.lod, tIndex); break; case GetSource.constId: codeGen.genCodeV(CodeGen.lit, Table.val(tIndex)); break; } } | "(" expression() ")" }