import java.io.*; import java.util.*; // ********************************************************************** // The ASTnode class defines the nodes of the abstract-syntax tree that // represents a C-- program. // // Internal nodes of the tree contain pointers to children, organized // either in a sequence (for nodes that may have a variable number of children) // or as a fixed set of fields. // // The nodes for literals and ids contain line and character number // information; for string literals and identifiers, they also contain a // string; for integer literals, they also contain an integer value. // // Here are all the different kinds of AST nodes and what kinds of children // they have. All of these kinds of AST nodes are subclasses of "ASTnode". // Indentation indicates further subclassing: // // Subclass Kids // -------- ---- // ProgramNode DeclListNode // DeclListNode linked list of DeclNode // DeclNode: // VarDeclNode TypeNode, IdNode, int // FnDeclNode TypeNode, IdNode, FormalsListNode, FnBodyNode // FormalDeclNode TypeNode, IdNode // // FormalsListNode linked list of FormalDeclNode // FnBodyNode DeclListNode, StmtListNode // StmtListNode linked list of StmtNode // ExpListNode linked list of ExpNode // // TypeNode: // IntNode -- none -- // BoolNode -- none -- // VoidNode -- none -- // // StmtNode: // ReadStmtNode ExpNode // WriteStmtNode ExpNode // AssignStmtNode ExpNode, ExpNode // IfStmtNode ExpNode, DeclListNode, StmtListNode // IfElseStmtNode ExpNode, DeclListNode, StmtListNode, // DeclListNode, StmtListNode // WhileStmtNode ExpNode, DeclListNode, StmtListNode // CallStmtNode CallExpNode // ReturnStmtNode ExpNode // // ExpNode: // IntLitNode -- none -- // StringLitNode -- none -- // TrueNode -- none -- // FalseNode -- none -- // IdNode -- none -- // ArrayExpNode IdNode, ExpNode // CallExpNode IdNode, ExpListNode // UnaryExpNode ExpNode // UnaryMinusNode // NotNode // BinaryExpNode ExpNode ExpNode // PlusNode // MinusNode // TimesNode // DivideNode // AndNode // OrNode // EqualsNode // NotEqualsNode // LessNode // GreaterNode // LessEqNode // GreaterEqNode // // Here are the different kinds of AST nodes again, organized according to // whether they are leaves, internal nodes with sequences of kids, or internal // nodes with a fixed number of kids: // // (1) Leaf nodes: // IntNode, BoolNode, VoidNode, IntLitNode, StringLitNode, // TrueNode, FalseNode, IdNode // // (2) Internal nodes with (possibly empty) linked lists of children: // DeclListNode, FormalsListNode, StmtListNode, ExpListNode // // (3) Internal nodes with fixed numbers of kids: // ProgramNode, VarDeclNode, FnDeclNode, FormalDeclNode, // FnBodyNode, TypeNode, ReadStmtNode, WriteStmtNode // AssignStmtNode, IfStmtNode, IfElseStmtNode, WhileStmtNode, // CallStmtNode, ReturnStmtNode, ArrayExpNode, CallExpNode, // UnaryExpNode, BinaryExpNode, UnaryMinusNode, NotNode, // PlusNode, MinusNode, TimesNode, DivideNode, // AndNode, OrNode, EqualsNode, NotEqualsNode, // LessNode, GreaterNode, LessEqNode, GreaterEqNode, // // ********************************************************************** // ********************************************************************** // ASTnode class (base class for all other kinds of nodes) // ********************************************************************** abstract class ASTnode { // every subclass must provide an unparse operation abstract public void unparse(PrintWriter p, int indent); // this method can be used by the unparse methods to do indenting protected void doIndent(PrintWriter p, int indent) { for (int k=0; k> "); myExp.unparse(p,0); p.println(";"); } // 1 kid (actually can only be an IdNode or an ArrayExpNode) private ExpNode myExp; } class WriteStmtNode extends StmtNode { public WriteStmtNode(ExpNode exp) { myExp = exp; } // ** unparse ** public void unparse(PrintWriter p, int indent) { p.print("cout << "); myExp.unparse(p,0); p.println(";"); } // 1 kid private ExpNode myExp; } class AssignStmtNode extends StmtNode { public AssignStmtNode(ExpNode lhs, ExpNode exp) { myLhs = lhs; myExp = exp; } // ** unparse ** public void unparse(PrintWriter p, int indent) { myLhs.unparse(p, 0); p.print(" = "); myExp.unparse(p,0); p.println(";"); } // 2 kids private ExpNode myLhs; private ExpNode myExp; } class IfStmtNode extends StmtNode { public IfStmtNode(ExpNode exp, DeclListNode dlist, StmtListNode slist) { myDeclList = dlist; myExp = exp; myStmtList = slist; } // ** unparse ** public void unparse(PrintWriter p, int indent) { p.print("if ("); myExp.unparse(p,0); p.println(") {"); if (myDeclList != null) myDeclList.unparse(p,indent+2); if (myStmtList != null) myStmtList.unparse(p,indent+2); doIndent(p, indent); p.println("}"); } // 3 kids private ExpNode myExp; private DeclListNode myDeclList; private StmtListNode myStmtList; } class IfElseStmtNode extends StmtNode { public IfElseStmtNode(ExpNode exp, DeclListNode dlist1, StmtListNode slist1, DeclListNode dlist2, StmtListNode slist2) { myExp = exp; myThenDeclList = dlist1; myThenStmtList = slist1; myElseDeclList = dlist2; myElseStmtList = slist2; } // ** unparse ** public void unparse(PrintWriter p, int indent) { p.print("if ("); myExp.unparse(p,0); p.println(") {"); if (myThenDeclList != null) myThenDeclList.unparse(p,indent+2); if (myThenStmtList != null) myThenStmtList.unparse(p,indent+2); doIndent(p, indent); p.println("}"); doIndent(p, indent); p.println("else {"); if (myElseDeclList != null) myElseDeclList.unparse(p,indent+2); if (myElseStmtList != null) myElseStmtList.unparse(p,indent+2); doIndent(p, indent); p.println("}"); } // 5 kids private ExpNode myExp; private DeclListNode myThenDeclList; private StmtListNode myThenStmtList; private StmtListNode myElseStmtList; private DeclListNode myElseDeclList; } class WhileStmtNode extends StmtNode { public WhileStmtNode(ExpNode exp, DeclListNode dlist, StmtListNode slist) { myExp = exp; myDeclList = dlist; myStmtList = slist; } // ** unparse ** public void unparse(PrintWriter p, int indent) { p.print("while ("); myExp.unparse(p,0); p.println(") {"); if (myDeclList != null) myDeclList.unparse(p,indent+2); if (myStmtList != null) myStmtList.unparse(p,indent+2); doIndent(p, indent); p.println("}"); } // 3 kids private ExpNode myExp; private DeclListNode myDeclList; private StmtListNode myStmtList; } class CallStmtNode extends StmtNode { public CallStmtNode(CallExpNode call) { myCall = call; } // ** unparse ** public void unparse(PrintWriter p, int indent) { myCall.unparse(p,indent); p.println(";"); } // 1 kid private CallExpNode myCall; } class ReturnStmtNode extends StmtNode { public ReturnStmtNode(ExpNode exp) { myExp = exp; } // ** unparse ** public void unparse(PrintWriter p, int indent) { p.print("return"); if (myExp != null) { p.print(" "); myExp.unparse(p,0); } p.println(";"); } // 1 kid private ExpNode myExp; } // ********************************************************************** // ExpNode and its subclasses // ********************************************************************** abstract class ExpNode extends ASTnode { } class IntLitNode extends ExpNode { public IntLitNode(int lineNum, int charNum, int intVal) { myLineNum = lineNum; myCharNum = charNum; myIntVal = intVal; } // ** unparse ** public void unparse(PrintWriter p, int indent) { p.print(myIntVal); } private int myLineNum; private int myCharNum; private int myIntVal; } class StringLitNode extends ExpNode { public StringLitNode(int lineNum, int charNum, String strVal) { myLineNum = lineNum; myCharNum = charNum; myStrVal = strVal; } // ** unparse ** public void unparse(PrintWriter p, int indent) { p.print(myStrVal); } private int myLineNum; private int myCharNum; private String myStrVal; } class TrueNode extends ExpNode { public TrueNode(int lineNum, int charNum) { myLineNum = lineNum; myCharNum = charNum; } // ** unparse ** public void unparse(PrintWriter p, int indent) { p.print("true"); } private int myLineNum; private int myCharNum; } class FalseNode extends ExpNode { public FalseNode(int lineNum, int charNum) { myLineNum = lineNum; myCharNum = charNum; } // ** unparse ** public void unparse(PrintWriter p, int indent) { p.print("false"); } // 2 fields private int myLineNum; private int myCharNum; } class IdNode extends ExpNode { public IdNode(int lineNum, int charNum, String strVal) { myLineNum = lineNum; myCharNum = charNum; myStrVal = strVal; } // ** unparse ** public void unparse(PrintWriter p, int indent) { p.print(myStrVal); } // fields private int myLineNum; private int myCharNum; private String myStrVal; } class ArrayExpNode extends ExpNode { public ArrayExpNode(IdNode id, ExpNode exp) { myId = id; myExp = exp; } // ** unparse ** public void unparse(PrintWriter p, int indent) { myId.unparse(p, 0); if (myExp != null) { p.print("["); myExp.unparse(p,0); p.print("]"); } } // 2 kids private IdNode myId; private ExpNode myExp; } class CallExpNode extends ExpNode { public CallExpNode(IdNode name, ExpListNode elist) { myId = name; myExpList = elist; } public CallExpNode(IdNode name) { myId = name; myExpList = new ExpListNode(new LinkedList()); } // ** unparse ** public void unparse(PrintWriter p, int indent) { myId.unparse(p,0); p.print("("); if (myExpList != null) myExpList.unparse(p,0); p.print(")"); } // 2 kids private IdNode myId; private ExpListNode myExpList; } abstract class UnaryExpNode extends ExpNode { public UnaryExpNode(ExpNode exp) { myExp = exp; } // one kid protected ExpNode myExp; } abstract class BinaryExpNode extends ExpNode { public BinaryExpNode(ExpNode exp1, ExpNode exp2) { myExp1 = exp1; myExp2 = exp2; } // two kids protected ExpNode myExp1; protected ExpNode myExp2; } // ********************************************************************** // Subclasses of UnaryExpNode // ********************************************************************** class UnaryMinusNode extends UnaryExpNode { public UnaryMinusNode(ExpNode exp) { super(exp); } // ** unparse ** public void unparse(PrintWriter p, int indent) { p.print("(-"); myExp.unparse(p, 0); p.print(")"); } } class NotNode extends UnaryExpNode { public NotNode(ExpNode exp) { super(exp); } // ** unparse ** public void unparse(PrintWriter p, int indent) { p.print("(!"); myExp.unparse(p, 0); p.print(")"); } } // ********************************************************************** // Subclasses of BinaryExpNode // ********************************************************************** class PlusNode extends BinaryExpNode { public PlusNode(ExpNode exp1, ExpNode exp2) { super(exp1, exp2); } // ** unparse ** public void unparse(PrintWriter p, int indent) { p.print("("); myExp1.unparse(p, 0); p.print("+"); myExp2.unparse(p, 0); p.print(")"); } } class MinusNode extends BinaryExpNode { public MinusNode(ExpNode exp1, ExpNode exp2) { super(exp1, exp2); } // ** unparse ** public void unparse(PrintWriter p, int indent) { p.print("("); myExp1.unparse(p, 0); p.print("-"); myExp2.unparse(p, 0); p.print(")"); } } class TimesNode extends BinaryExpNode { public TimesNode(ExpNode exp1, ExpNode exp2) { super(exp1, exp2); } // ** unparse ** public void unparse(PrintWriter p, int indent) { p.print("("); myExp1.unparse(p, 0); p.print("*"); myExp2.unparse(p, 0); p.print(")"); } } class DivideNode extends BinaryExpNode { public DivideNode(ExpNode exp1, ExpNode exp2) { super(exp1, exp2); } // ** unparse ** public void unparse(PrintWriter p, int indent) { p.print("("); myExp1.unparse(p, 0); p.print("/"); myExp2.unparse(p, 0); p.print(")"); } } class AndNode extends BinaryExpNode { public AndNode(ExpNode exp1, ExpNode exp2) { super(exp1, exp2); } // ** unparse ** public void unparse(PrintWriter p, int indent) { p.print("("); myExp1.unparse(p, 0); p.print("&&"); myExp2.unparse(p, 0); p.print(")"); } } class OrNode extends BinaryExpNode { public OrNode(ExpNode exp1, ExpNode exp2) { super(exp1, exp2); } // ** unparse ** public void unparse(PrintWriter p, int indent) { p.print("("); myExp1.unparse(p, 0); p.print("||"); myExp2.unparse(p, 0); p.print(")"); } } class EqualsNode extends BinaryExpNode { public EqualsNode(ExpNode exp1, ExpNode exp2) { super(exp1, exp2); } // ** unparse ** public void unparse(PrintWriter p, int indent) { p.print("("); myExp1.unparse(p, 0); p.print("=="); myExp2.unparse(p, 0); p.print(")"); } } class NotEqualsNode extends BinaryExpNode { public NotEqualsNode(ExpNode exp1, ExpNode exp2) { super(exp1, exp2); } // ** unparse ** public void unparse(PrintWriter p, int indent) { p.print("("); myExp1.unparse(p, 0); p.print("!="); myExp2.unparse(p, 0); p.print(")"); } } class LessNode extends BinaryExpNode { public LessNode(ExpNode exp1, ExpNode exp2) { super(exp1, exp2); } // ** unparse ** public void unparse(PrintWriter p, int indent) { p.print("("); myExp1.unparse(p, 0); p.print("<"); myExp2.unparse(p, 0); p.print(")"); } } class GreaterNode extends BinaryExpNode { public GreaterNode(ExpNode exp1, ExpNode exp2) { super(exp1, exp2); } // ** unparse ** public void unparse(PrintWriter p, int indent) { p.print("("); myExp1.unparse(p, 0); p.print(">"); myExp2.unparse(p, 0); p.print(")"); } } class LessEqNode extends BinaryExpNode { public LessEqNode(ExpNode exp1, ExpNode exp2) { super(exp1, exp2); } // ** unparse ** public void unparse(PrintWriter p, int indent) { p.print("("); myExp1.unparse(p, 0); p.print("<="); myExp2.unparse(p, 0); p.print(")"); } } class GreaterEqNode extends BinaryExpNode { public GreaterEqNode(ExpNode exp1, ExpNode exp2) { super(exp1, exp2); } // ** unparse ** public void unparse(PrintWriter p, int indent) { p.print("("); myExp1.unparse(p, 0); p.print(">="); myExp2.unparse(p, 0); p.print(")"); } }