diff options
author | Iru Cai <mytbk920423@gmail.com> | 2014-11-03 01:46:06 +0800 |
---|---|---|
committer | Iru Cai <mytbk920423@gmail.com> | 2014-11-03 01:46:06 +0800 |
commit | 5fa82beb2b420cc63111c186a670abcb674ba373 (patch) | |
tree | 7c16037088e74216ca0e146602b8653ab1cbf898 | |
parent | 400909d160c5a348f1f4015add94a69fa1855cfd (diff) | |
download | minijava-5fa82beb2b420cc63111c186a670abcb674ba373.tar.xz |
piglet to spiglet
-rw-r--r-- | src/piglet/piglet2spiglet/GenSpigletCtl.java | 25 | ||||
-rw-r--r-- | src/piglet/piglet2spiglet/Main.java | 11 | ||||
-rw-r--r-- | src/piglet/piglet2spiglet/PigletExpr.java | 19 | ||||
-rw-r--r-- | src/piglet/visitor/GenSpigletVisitor.java | 382 | ||||
-rw-r--r-- | src/piglet/visitor/ScanTempVisitor.java | 234 |
5 files changed, 667 insertions, 4 deletions
diff --git a/src/piglet/piglet2spiglet/GenSpigletCtl.java b/src/piglet/piglet2spiglet/GenSpigletCtl.java new file mode 100644 index 0000000..a95dcc4 --- /dev/null +++ b/src/piglet/piglet2spiglet/GenSpigletCtl.java @@ -0,0 +1,25 @@ +package piglet.piglet2spiglet; + +import java.util.Vector; + +public class GenSpigletCtl { + /* DEFAULT: return a PigletExpr + * PRINT: used with procedure, print the StmtExp + * LIST: used with call, add things to list, return null + */ + public enum Control { DEFAULT, PRINT, LIST }; + Control c; + public Vector<PigletExpr> call_list; + + public GenSpigletCtl(Control _c) { + c = _c; + call_list = new Vector<PigletExpr>(); + } + public boolean isPrint() { + return c==Control.PRINT; + } + + public boolean isList() { + return c==Control.LIST; + } +} diff --git a/src/piglet/piglet2spiglet/Main.java b/src/piglet/piglet2spiglet/Main.java index db68b6a..7c3d01b 100644 --- a/src/piglet/piglet2spiglet/Main.java +++ b/src/piglet/piglet2spiglet/Main.java @@ -6,6 +6,8 @@ import piglet.PigletParser; import piglet.TokenMgrError;
import piglet.syntaxtree.Node;
import piglet.visitor.GJDepthFirst;
+import piglet.visitor.GenSpigletVisitor;
+import piglet.visitor.ScanTempVisitor;
public class Main {
@@ -17,10 +19,11 @@ public class Main { * TODO: Implement your own Visitors and other classes.
*
*/
- GJDepthFirst v = new GJDepthFirst<Object,Object>() {
- };
- //Traverse the Abstract Grammar Tree
- root.accept(v,null);
+ ScanTempVisitor vt = new ScanTempVisitor();
+ root.accept(vt);
+ GenSpigletVisitor gen = new GenSpigletVisitor();
+ gen.nTemp = Math.max(vt.maxtmp, 20);
+ root.accept(gen, null);
}
catch(TokenMgrError e){
//Handle Lexical Errors
diff --git a/src/piglet/piglet2spiglet/PigletExpr.java b/src/piglet/piglet2spiglet/PigletExpr.java new file mode 100644 index 0000000..a8289e6 --- /dev/null +++ b/src/piglet/piglet2spiglet/PigletExpr.java @@ -0,0 +1,19 @@ +package piglet.piglet2spiglet; + +public class PigletExpr { + public enum Expr_t { Temp, Int, Label, Other }; + public Expr_t type; + public String s; + public PigletExpr(Expr_t t, String _s) { + type = t; + s = _s; + } + + public boolean isSimple() { + return type==Expr_t.Temp || type==Expr_t.Int || type==Expr_t.Label; + } + + public String toString() { + return s; + } +} diff --git a/src/piglet/visitor/GenSpigletVisitor.java b/src/piglet/visitor/GenSpigletVisitor.java new file mode 100644 index 0000000..779edf9 --- /dev/null +++ b/src/piglet/visitor/GenSpigletVisitor.java @@ -0,0 +1,382 @@ +package piglet.visitor;
+import java.util.Enumeration; +import java.util.Vector;
+
+import piglet.piglet2spiglet.GenSpigletCtl;
+import piglet.piglet2spiglet.PigletExpr;
+import piglet.syntaxtree.BinOp; +import piglet.syntaxtree.CJumpStmt; +import piglet.syntaxtree.Call; +import piglet.syntaxtree.ErrorStmt; +import piglet.syntaxtree.Exp; +import piglet.syntaxtree.Goal; +import piglet.syntaxtree.HAllocate; +import piglet.syntaxtree.HLoadStmt; +import piglet.syntaxtree.HStoreStmt; +import piglet.syntaxtree.IntegerLiteral; +import piglet.syntaxtree.JumpStmt; +import piglet.syntaxtree.Label; +import piglet.syntaxtree.MoveStmt; +import piglet.syntaxtree.NoOpStmt; +import piglet.syntaxtree.Node; +import piglet.syntaxtree.NodeList; +import piglet.syntaxtree.NodeListOptional; +import piglet.syntaxtree.NodeOptional; +import piglet.syntaxtree.NodeSequence; +import piglet.syntaxtree.NodeToken; +import piglet.syntaxtree.Operator; +import piglet.syntaxtree.PrintStmt; +import piglet.syntaxtree.Procedure; +import piglet.syntaxtree.Stmt; +import piglet.syntaxtree.StmtExp; +import piglet.syntaxtree.StmtList; +import piglet.syntaxtree.Temp; +
+/**
+ * Provides default methods which visit each node in the tree in depth-first
+ * order. Your visitors may extend this class.
+ */
+public class GenSpigletVisitor extends GJDepthFirst<PigletExpr, GenSpigletCtl> {
+
+ public int nTemp;
+ final GenSpigletCtl Default = new GenSpigletCtl(GenSpigletCtl.Control.DEFAULT);
+ final GenSpigletCtl Print = new GenSpigletCtl(GenSpigletCtl.Control.PRINT);
+ final String BinOPs[] = {"LT", "PLUS", "MINUS", "TIMES" };
+
+ String expr_to_tmp(PigletExpr e) {
+ if (e.type==PigletExpr.Expr_t.Temp) {
+ return e.toString();
+ } else {
+ nTemp++;
+ System.out.println("MOVE TEMP " + nTemp + " " + e.toString());
+ return "TEMP " + nTemp;
+ }
+ }
+
+ String expr_to_simple(PigletExpr e) {
+ if (e.isSimple()) {
+ return e.toString();
+ } else {
+ nTemp++;
+ System.out.println("MOVE TEMP " + nTemp + " " + e.toString());
+ return "TEMP " + nTemp;
+ }
+ }
+ //
+ // User-generated visitor methods below
+ //
+
+ /**
+ * f0 -> "MAIN"
+ * f1 -> StmtList()
+ * f2 -> "END"
+ * f3 -> ( Procedure() )*
+ * f4 -> <EOF>
+ */
+ public PigletExpr visit(Goal n, GenSpigletCtl argu) {
+ System.out.println("MAIN");
+ n.f1.accept(this, argu);
+ System.out.println("END");
+ n.f3.accept(this, argu);
+ return null;
+ } +
+ /**
+ * f0 -> ( ( Label() )? Stmt() )*
+ */
+ public PigletExpr visit(StmtList n, GenSpigletCtl argu) {
+ n.f0.accept(this, argu);
+ return null;
+ } +
+ /**
+ * f0 -> Label()
+ * f1 -> "["
+ * f2 -> IntegerLiteral()
+ * f3 -> "]"
+ * f4 -> StmtExp()
+ */
+ public PigletExpr visit(Procedure n, GenSpigletCtl argu) {
+ String lb = n.f0.f0.toString();
+ String numarg = n.f2.f0.toString();
+ System.out.println(lb + " [ " + numarg + " ]");
+ n.f4.accept(this, Print);
+ return null;
+ } +
+ /**
+ * f0 -> NoOpStmt()
+ * | ErrorStmt()
+ * | CJumpStmt()
+ * | JumpStmt()
+ * | HStoreStmt()
+ * | HLoadStmt()
+ * | MoveStmt()
+ * | PrintStmt()
+ */
+ public PigletExpr visit(Stmt n, GenSpigletCtl argu) {
+ n.f0.accept(this, argu);
+ return null;
+ } +
+ /**
+ * f0 -> "NOOP"
+ */
+ public PigletExpr visit(NoOpStmt n, GenSpigletCtl argu) {
+ System.out.println("NOOP");
+ return null;
+ } +
+ /**
+ * f0 -> "ERROR"
+ */
+ public PigletExpr visit(ErrorStmt n, GenSpigletCtl argu) {
+ System.out.println("ERROR");
+ return null;
+ } +
+ /**
+ * f0 -> "CJUMP"
+ * f1 -> Exp()
+ * f2 -> Label()
+ */
+ public PigletExpr visit(CJumpStmt n, GenSpigletCtl argu) {
+ PigletExpr e = n.f1.accept(this, Default);
+ String lb = n.f2.f0.toString();
+ String tmpstr;
+ if (e.type==PigletExpr.Expr_t.Temp) {
+ tmpstr = e.toString();
+ } else {
+ nTemp++;
+ System.out.println("MOVE TEMP " + nTemp + " " + e.toString());
+ tmpstr = "TEMP " + nTemp;
+ }
+ System.out.println("CJUMP " + tmpstr + " " + lb);
+ return null;
+ } +
+ /**
+ * f0 -> "JUMP"
+ * f1 -> Label()
+ */
+ public PigletExpr visit(JumpStmt n, GenSpigletCtl argu) {
+ String lb = n.f1.f0.toString();
+ System.out.println("JUMP " + lb);
+ return null;
+ } +
+ /**
+ * f0 -> "HSTORE"
+ * f1 -> Exp()
+ * f2 -> IntegerLiteral()
+ * f3 -> Exp()
+ */
+ public PigletExpr visit(HStoreStmt n, GenSpigletCtl argu) {
+ PigletExpr e1 = n.f1.accept(this, Default);
+ PigletExpr e2 = n.f3.accept(this, Default);
+ String t1, t2;
+ String offs = n.f2.f0.toString();
+ t1 = expr_to_tmp(e1);
+ t2 = expr_to_tmp(e2);
+ System.out.println("HSTORE " + t1 + " " + offs + " " + t2);
+ return null;
+ } +
+ /**
+ * f0 -> "HLOAD"
+ * f1 -> Temp()
+ * f2 -> Exp()
+ * f3 -> IntegerLiteral()
+ */
+ public PigletExpr visit(HLoadStmt n, GenSpigletCtl argu) {
+ PigletExpr e = n.f2.accept(this, Default);
+ String s;
+ String t = n.f1.accept(this, Default).toString();
+ String i = n.f3.f0.toString();
+ s = expr_to_tmp(e);
+ System.out.println("HLOAD " + t + " " + s + " " + i);
+ return null;
+ } +
+ /**
+ * f0 -> "MOVE"
+ * f1 -> Temp()
+ * f2 -> Exp()
+ */
+ public PigletExpr visit(MoveStmt n, GenSpigletCtl argu) {
+ PigletExpr t = n.f1.accept(this, Default);
+ PigletExpr e = n.f2.accept(this, Default);
+ System.out.println("MOVE " + t.toString() + " " + e.toString());
+ return null;
+ } +
+ /**
+ * f0 -> "PRINT"
+ * f1 -> Exp()
+ */
+ public PigletExpr visit(PrintStmt n, GenSpigletCtl argu) {
+ PigletExpr e = n.f1.accept(this, Default);
+ String s = expr_to_simple(e);
+ System.out.println("PRINT " + s);
+ return null;
+ } +
+ /**
+ * f0 -> StmtExp()
+ * | Call()
+ * | HAllocate()
+ * | BinOp()
+ * | Temp()
+ * | IntegerLiteral()
+ * | Label()
+ */
+ public PigletExpr visit(Exp n, GenSpigletCtl argu) {
+ PigletExpr e_result = n.f0.accept(this, argu);
+ if (argu.isList()) {
+ argu.call_list.add(e_result);
+ return null;
+ } else {
+ return e_result;
+ }
+ } +
+ /**
+ * f0 -> "BEGIN"
+ * f1 -> StmtList()
+ * f2 -> "RETURN"
+ * f3 -> Exp()
+ * f4 -> "END"
+ */
+ public PigletExpr visit(StmtExp n, GenSpigletCtl argu) {
+ /* a normal expression or a function body */
+ if (argu.isPrint()) {
+ // a function body
+ System.out.println("BEGIN");
+ /* statement list */
+ n.f1.accept(this, null);
+ /* return */
+ PigletExpr e = n.f3.accept(this, Default);
+ String ret = expr_to_simple(e);
+ System.out.println("RETURN " + ret);
+ System.out.println("END");
+ return null;
+ } else {
+ // a normal expression, going to turn to a simpler expression
+ n.f1.accept(this, null);
+ return n.f3.accept(this, Default);
+ }
+ } +
+ /**
+ * f0 -> "CALL"
+ * f1 -> Exp()
+ * f2 -> "("
+ * f3 -> ( Exp() )*
+ * f4 -> ")"
+ */
+ public PigletExpr visit(Call n, GenSpigletCtl argu) {
+ String result = "";
+ /* process the method */
+ PigletExpr m = n.f1.accept(this, Default);
+ String tm = expr_to_tmp(m);
+ /* process the arguments */
+ GenSpigletCtl ctl = new GenSpigletCtl(GenSpigletCtl.Control.LIST);
+ n.f3.accept(this, ctl);
+ Vector<String> args = new Vector<String>();
+ for (int i=0; i<ctl.call_list.size(); i++) {
+ String s = expr_to_tmp(ctl.call_list.elementAt(i));
+ args.add(s);
+ }
+ result += "CALL " + tm + "( ";
+ for (int i=0; i<args.size(); i++) {
+ result += args.elementAt(i) + " ";
+ }
+ result += ")";
+ return new PigletExpr(PigletExpr.Expr_t.Other, result);
+ } +
+ /**
+ * f0 -> "HALLOCATE"
+ * f1 -> Exp()
+ */
+ public PigletExpr visit(HAllocate n, GenSpigletCtl argu) {
+ PigletExpr e = n.f1.accept(this, Default);
+ String s;
+ if (!e.isSimple()) {
+ nTemp++;
+ System.out.println("MOVE TEMP " + nTemp + " " + e.toString());
+ s = "TEMP " + nTemp;
+ } else {
+ s = e.toString();
+ }
+ return new PigletExpr(PigletExpr.Expr_t.Other,
+ "HALLOCATE " + s);
+ } +
+ /**
+ * f0 -> Operator()
+ * f1 -> Exp()
+ * f2 -> Exp()
+ */
+ public PigletExpr visit(BinOp n, GenSpigletCtl argu) {
+ String op = BinOPs[n.f0.f0.which];
+ String s1, s2;
+ PigletExpr t1 = n.f1.accept(this, Default);
+ PigletExpr t2 = n.f2.accept(this, Default);
+ /* the first expr can only be temp */
+ if (!(t1.type==PigletExpr.Expr_t.Temp)) {
+ nTemp++;
+ System.out.println("MOVE TEMP " + nTemp + " " + t1.toString());
+ s1 = "TEMP " + nTemp;
+ } else {
+ s1 = t1.toString();
+ }
+ if (!t2.isSimple()) {
+ nTemp++;
+ System.out.println("MOVE TEMP " + nTemp + " " + t2.toString());
+ s2 = "TEMP " + nTemp;
+ } else {
+ s2 = t2.toString();
+ }
+ return new PigletExpr(PigletExpr.Expr_t.Other,
+ op + " " + s1 + " " + s2);
+ } +
+ /**
+ * f0 -> "LT"
+ * | "PLUS"
+ * | "MINUS"
+ * | "TIMES"
+ */
+ public PigletExpr visit(Operator n, GenSpigletCtl argu) {
+ return null;
+ } +
+ /* the following are simple expressions
+ * these visitors return the expression string
+ */
+
+ /**
+ * f0 -> "TEMP"
+ * f1 -> IntegerLiteral()
+ */
+ public PigletExpr visit(Temp n, GenSpigletCtl argu) {
+ return new PigletExpr(PigletExpr.Expr_t.Temp,
+ "TEMP " + n.f1.f0.toString());
+ } +
+ /**
+ * f0 -> <INTEGER_LITERAL>
+ */
+ public PigletExpr visit(IntegerLiteral n, GenSpigletCtl argu) {
+ return new PigletExpr(PigletExpr.Expr_t.Int, n.f0.toString());
+ } +
+ /**
+ * f0 -> <IDENTIFIER>
+ */
+ public PigletExpr visit(Label n, GenSpigletCtl argu) {
+ return new PigletExpr(PigletExpr.Expr_t.Label, n.f0.toString());
+ } +
+}
diff --git a/src/piglet/visitor/ScanTempVisitor.java b/src/piglet/visitor/ScanTempVisitor.java new file mode 100644 index 0000000..333c354 --- /dev/null +++ b/src/piglet/visitor/ScanTempVisitor.java @@ -0,0 +1,234 @@ +package piglet.visitor; + +import piglet.syntaxtree.BinOp; +import piglet.syntaxtree.CJumpStmt; +import piglet.syntaxtree.Call; +import piglet.syntaxtree.ErrorStmt; +import piglet.syntaxtree.Exp; +import piglet.syntaxtree.Goal; +import piglet.syntaxtree.HAllocate; +import piglet.syntaxtree.HLoadStmt; +import piglet.syntaxtree.HStoreStmt; +import piglet.syntaxtree.IntegerLiteral; +import piglet.syntaxtree.JumpStmt; +import piglet.syntaxtree.Label; +import piglet.syntaxtree.MoveStmt; +import piglet.syntaxtree.NoOpStmt; +import piglet.syntaxtree.Operator; +import piglet.syntaxtree.PrintStmt; +import piglet.syntaxtree.Procedure; +import piglet.syntaxtree.Stmt; +import piglet.syntaxtree.StmtExp; +import piglet.syntaxtree.StmtList; +import piglet.syntaxtree.Temp; + +public class ScanTempVisitor extends DepthFirstVisitor { + public int maxtmp = 0; + + /** + * f0 -> "MAIN" + * f1 -> StmtList() + * f2 -> "END" + * f3 -> ( Procedure() )* + * f4 -> <EOF> + */ + public void visit(Goal n) { + n.f1.accept(this); + n.f3.accept(this); + } + + /** + * f0 -> ( ( Label() )? Stmt() )* + */ + public void visit(StmtList n) { + n.f0.accept(this); + } + + /** + * f0 -> Label() + * f1 -> "[" + * f2 -> IntegerLiteral() + * f3 -> "]" + * f4 -> StmtExp() + */ + public void visit(Procedure n) { + n.f4.accept(this); + } + + /** + * f0 -> NoOpStmt() + * | ErrorStmt() + * | CJumpStmt() + * | JumpStmt() + * | HStoreStmt() + * | HLoadStmt() + * | MoveStmt() + * | PrintStmt() + */ + public void visit(Stmt n) { + n.f0.accept(this); + } + + /** + * f0 -> "NOOP" + */ + public void visit(NoOpStmt n) { + return; + } + + /** + * f0 -> "ERROR" + */ + public void visit(ErrorStmt n) { + return; + } + + /** + * f0 -> "CJUMP" + * f1 -> Exp() + * f2 -> Label() + */ + public void visit(CJumpStmt n) { + n.f1.accept(this); + } + + /** + * f0 -> "JUMP" + * f1 -> Label() + */ + public void visit(JumpStmt n) { + return; + } + + /** + * f0 -> "HSTORE" + * f1 -> Exp() + * f2 -> IntegerLiteral() + * f3 -> Exp() + */ + public void visit(HStoreStmt n) { + n.f1.accept(this); + n.f3.accept(this); + } + + /** + * f0 -> "HLOAD" + * f1 -> Temp() + * f2 -> Exp() + * f3 -> IntegerLiteral() + */ + public void visit(HLoadStmt n) { + n.f1.accept(this); + n.f2.accept(this); + } + + /** + * f0 -> "MOVE" + * f1 -> Temp() + * f2 -> Exp() + */ + public void visit(MoveStmt n) { + n.f1.accept(this); + n.f2.accept(this); + } + + /** + * f0 -> "PRINT" + * f1 -> Exp() + */ + public void visit(PrintStmt n) { + n.f1.accept(this); + } + + /** + * f0 -> StmtExp() + * | Call() + * | HAllocate() + * | BinOp() + * | Temp() + * | IntegerLiteral() + * | Label() + */ + public void visit(Exp n) { + n.f0.accept(this); + } + + /** + * f0 -> "BEGIN" + * f1 -> StmtList() + * f2 -> "RETURN" + * f3 -> Exp() + * f4 -> "END" + */ + public void visit(StmtExp n) { + n.f1.accept(this); + n.f3.accept(this); + } + + /** + * f0 -> "CALL" + * f1 -> Exp() + * f2 -> "(" + * f3 -> ( Exp() )* + * f4 -> ")" + */ + public void visit(Call n) { + n.f1.accept(this); + n.f3.accept(this); + } + + /** + * f0 -> "HALLOCATE" + * f1 -> Exp() + */ + public void visit(HAllocate n) { + n.f1.accept(this); + } + + /** + * f0 -> Operator() + * f1 -> Exp() + * f2 -> Exp() + */ + public void visit(BinOp n) { + n.f1.accept(this); + n.f2.accept(this); + } + + /** + * f0 -> "LT" + * | "PLUS" + * | "MINUS" + * | "TIMES" + */ + public void visit(Operator n) { + return; + } + + /** + * f0 -> "TEMP" + * f1 -> IntegerLiteral() + */ + public void visit(Temp n) { + int x = Integer.parseInt(n.f1.f0.tokenImage); + //System.out.println(x); + if (x>maxtmp) { + maxtmp = x; + } + } + + /** + * f0 -> <INTEGER_LITERAL> + */ + public void visit(IntegerLiteral n) { + return; + } + + /** + * f0 -> <IDENTIFIER> + */ + public void visit(Label n) { + return; + } + +} |