1
Fork 0

AST Generation

Construct an AST.
master
Joshua Potter 2014-02-21 22:34:37 -05:00
parent 983f4cd852
commit 46a6e73f5d
60 changed files with 1985 additions and 172 deletions

BIN
docs/PA2.pdf Normal file

Binary file not shown.

View File

@ -0,0 +1,27 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public abstract class AST {
public AST (SourcePosition posn) {
this.posn = posn;
}
public String toString() {
String fullClassName = this.getClass().getName();
String cn = fullClassName.substring(1 + fullClassName.lastIndexOf('.'));
if (ASTDisplay.showPosition)
cn = cn + " " + posn.toString();
return cn;
}
public abstract <A,R> R visit(Visitor<A,R> v, A o);
public SourcePosition posn;
}

View File

@ -0,0 +1,353 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
/*
* Display AST in text form
* In-order traversal of AST, visiting each node with a method of the form
*
* public Object visitXXX( XXX astnode, String arg)
*
* where arg is a prefix string (indentation) to precede display of ast node
* and a null Object is returned as the result.
*
* implements Visitor<argtype,resulttype>
*/
public class ASTDisplay implements Visitor<String,Object> {
public static boolean showPosition = false;
/**
* print text representation of AST to stdout
* @param ast root node of AST
*/
public void showTree(AST ast){
System.out.println("======= AST Display =========================");
ast.visit(this, "");
System.out.println("=============================================");
}
// methods to format output
/**
* display arbitrary text for a node
* @param prefix spacing to indicate depth in AST
* @param text preformatted node display
*/
private void show(String prefix, String text) {
System.out.println(prefix + text);
}
/**
* display AST node by name
* @param prefix spacing to indicate depth in AST
* @param node AST node, will be shown by name
*/
private void show(String prefix, AST node) {
System.out.println(prefix + node.toString());
}
/**
* quote a string
* @param text string to quote
*/
private String quote(String text) {
return ("\"" + text + "\"");
}
/**
* increase depth in AST
* @param prefix current spacing to indicate depth in AST
* @return new spacing
*/
private String indent(String prefix) {
return prefix + " ";
}
///////////////////////////////////////////////////////////////////////////////
//
// PACKAGE
//
///////////////////////////////////////////////////////////////////////////////
public Object visitPackage(Package prog, String arg){
show(arg, prog);
ClassDeclList cl = prog.classDeclList;
show(arg," ClassDeclList [" + cl.size() + "]");
String pfx = arg + " . ";
for (ClassDecl c: prog.classDeclList){
c.visit(this, pfx);
}
return null;
}
///////////////////////////////////////////////////////////////////////////////
//
// DECLARATIONS
//
///////////////////////////////////////////////////////////////////////////////
public Object visitClassDecl(ClassDecl clas, String arg){
show(arg, clas);
show(indent(arg), quote(clas.name) + " classname");
show(arg," FieldDeclList [" + clas.fieldDeclList.size() + "]");
String pfx = arg + " . ";
for (FieldDecl f: clas.fieldDeclList)
f.visit(this, pfx);
show(arg," MethodDeclList [" + clas.methodDeclList.size() + "]");
for (MethodDecl m: clas.methodDeclList)
m.visit(this, pfx);
return null;
}
public Object visitFieldDecl(FieldDecl f, String arg){
show(arg, "(" + (f.isPrivate ? "private": "public")
+ (f.isStatic ? " static) " :") ") + f.toString());
f.type.visit(this, indent(arg));
show(indent(arg), quote(f.name) + " fieldname");
return null;
}
public Object visitMethodDecl(MethodDecl m, String arg){
show(arg, "(" + (m.isPrivate ? "private": "public")
+ (m.isStatic ? " static) " :") ") + m.toString());
m.type.visit(this, indent(arg));
show(indent(arg), quote(m.name) + " methodname");
ParameterDeclList pdl = m.parameterDeclList;
show(arg, " ParameterDeclList [" + pdl.size() + "]");
String pfx = ((String) arg) + " . ";
for (ParameterDecl pd: pdl) {
pd.visit(this, pfx);
}
StatementList sl = m.statementList;
show(arg, " StmtList [" + sl.size() + "]");
for (Statement s: sl) {
s.visit(this, pfx);
}
if (m.returnExp != null) {
m.returnExp.visit(this, indent(arg));
}
return null;
}
public Object visitParameterDecl(ParameterDecl pd, String arg){
show(arg, pd);
pd.type.visit(this, indent(arg));
show(indent(arg), quote(pd.name) + "parametername ");
return null;
}
public Object visitVarDecl(VarDecl vd, String arg){
show(arg, vd);
vd.type.visit(this, indent(arg));
show(indent(arg), quote(vd.name) + " varname");
return null;
}
///////////////////////////////////////////////////////////////////////////////
//
// TYPES
//
///////////////////////////////////////////////////////////////////////////////
public Object visitBaseType(BaseType type, String arg){
show(arg, type.typeKind + " " + type.toString());
return null;
}
public Object visitClassType(ClassType type, String arg){
show(arg, type);
show(indent(arg), quote(type.className.spelling) + " classname");
return null;
}
public Object visitArrayType(ArrayType type, String arg){
show(arg, type);
type.eltType.visit(this, indent(arg));
return null;
}
///////////////////////////////////////////////////////////////////////////////
//
// STATEMENTS
//
///////////////////////////////////////////////////////////////////////////////
public Object visitBlockStmt(BlockStmt stmt, String arg){
show(arg, stmt);
StatementList sl = stmt.sl;
show(arg," StatementList [" + sl.size() + "]");
String pfx = arg + " . ";
for (Statement s: sl) {
s.visit(this, pfx);
}
return null;
}
public Object visitVardeclStmt(VarDeclStmt stmt, String arg){
show(arg, stmt);
stmt.varDecl.visit(this, indent(arg));
stmt.initExp.visit(this, indent(arg));
return null;
}
public Object visitAssignStmt(AssignStmt stmt, String arg){
show(arg,stmt);
stmt.ref.visit(this, indent(arg));
stmt.val.visit(this, indent(arg));
return null;
}
public Object visitCallStmt(CallStmt stmt, String arg){
show(arg,stmt);
stmt.methodRef.visit(this, indent(arg));
ExprList al = stmt.argList;
show(arg," ExprList [" + al.size() + "]");
String pfx = arg + " . ";
for (Expression e: al) {
e.visit(this, pfx);
}
return null;
}
public Object visitIfStmt(IfStmt stmt, String arg){
show(arg,stmt);
stmt.cond.visit(this, indent(arg));
stmt.thenStmt.visit(this, indent(arg));
if (stmt.elseStmt != null)
stmt.elseStmt.visit(this, indent(arg));
return null;
}
public Object visitWhileStmt(WhileStmt stmt, String arg){
show(arg, stmt);
stmt.cond.visit(this, indent(arg));
stmt.body.visit(this, indent(arg));
return null;
}
///////////////////////////////////////////////////////////////////////////////
//
// EXPRESSIONS
//
///////////////////////////////////////////////////////////////////////////////
public Object visitUnaryExpr(UnaryExpr expr, String arg){
show(arg, expr);
expr.operator.visit(this, indent(arg));
expr.expr.visit(this, indent(indent(arg)));
return null;
}
public Object visitBinaryExpr(BinaryExpr expr, String arg){
show(arg, expr);
expr.operator.visit(this, indent(arg));
expr.left.visit(this, indent(indent(arg)));
expr.right.visit(this, indent(indent(arg)));
return null;
}
public Object visitRefExpr(RefExpr expr, String arg){
show(arg, expr);
expr.ref.visit(this, indent(arg));
return null;
}
public Object visitCallExpr(CallExpr expr, String arg){
show(arg, expr);
expr.functionRef.visit(this, indent(arg));
ExprList al = expr.argList;
show(arg," ExprList + [" + al.size() + "]");
String pfx = arg + " . ";
for (Expression e: al) {
e.visit(this, pfx);
}
return null;
}
public Object visitLiteralExpr(LiteralExpr expr, String arg){
show(arg, expr);
expr.literal.visit(this, indent(arg));
return null;
}
public Object visitNewArrayExpr(NewArrayExpr expr, String arg){
show(arg, expr);
expr.eltType.visit(this, indent(arg));
expr.sizeExpr.visit(this, indent(arg));
return null;
}
public Object visitNewObjectExpr(NewObjectExpr expr, String arg){
show(arg, expr);
expr.classtype.visit(this, indent(arg));
return null;
}
///////////////////////////////////////////////////////////////////////////////
//
// REFERENCES
//
///////////////////////////////////////////////////////////////////////////////
public Object visitQualifiedRef(QualifiedRef qr, String arg) {
show(arg, qr);
qr.id.visit(this, indent(arg));
qr.ref.visit(this, indent(arg));
return null;
}
public Object visitIndexedRef(IndexedRef ir, String arg) {
show(arg, ir);
ir.indexExpr.visit(this, indent(arg));
ir.ref.visit(this, indent(arg));
return null;
}
public Object visitIdRef(IdRef ref, String arg) {
show(arg,ref);
ref.id.visit(this, indent(arg));
return null;
}
public Object visitThisRef(ThisRef ref, String arg) {
show(arg,ref);
return null;
}
///////////////////////////////////////////////////////////////////////////////
//
// TERMINALS
//
///////////////////////////////////////////////////////////////////////////////
public Object visitIdentifier(Identifier id, String arg){
show(arg, quote(id.spelling) + " " + id.toString());
return null;
}
public Object visitOperator(Operator op, String arg){
show(arg, quote(op.spelling) + " " + op.toString());
return null;
}
public Object visitIntLiteral(IntLiteral num, String arg){
show(arg, quote(num.spelling) + " " + num.toString());
return null;
}
public Object visitBooleanLiteral(BooleanLiteral bool, String arg){
show(arg, quote(bool.spelling) + " " + bool.toString());
return null;
}
}

View File

@ -0,0 +1,24 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class ArrayType extends Type {
public ArrayType(Type eltType, SourcePosition posn){
super(TypeKind.ARRAY, posn);
this.eltType = eltType;
}
public <A,R> R visit(Visitor<A,R> v, A o) {
return v.visitArrayType(this, o);
}
public Type eltType;
}

View File

@ -0,0 +1,24 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class AssignStmt extends Statement
{
public AssignStmt(Reference r, Expression e, SourcePosition posn){
super(posn);
ref = r;
val = e;
}
public <A,R> R visit(Visitor<A,R> v, A o) {
return v.visitAssignStmt(this, o);
}
public Reference ref;
public Expression val;
}

View File

@ -0,0 +1,19 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class BaseType extends Type
{
public BaseType(TypeKind t, SourcePosition posn){
super(t, posn);
}
public <A,R> R visit(Visitor<A,R> v, A o) {
return v.visitBaseType(this, o);
}
}

View File

@ -0,0 +1,26 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class BinaryExpr extends Expression
{
public BinaryExpr(Operator o, Expression e1, Expression e2, SourcePosition posn){
super(posn);
operator = o;
left = e1;
right = e2;
}
public <A,R> R visit(Visitor<A,R> v, A o) {
return v.visitBinaryExpr(this, o);
}
public Operator operator;
public Expression left;
public Expression right;
}

View File

@ -0,0 +1,22 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class BlockStmt extends Statement
{
public BlockStmt(StatementList sl, SourcePosition posn){
super(posn);
this.sl = sl;
}
public <A,R> R visit(Visitor<A,R> v, A o) {
return v.visitBlockStmt(this, o);
}
public StatementList sl;
}

View File

@ -0,0 +1,19 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class BooleanLiteral extends Literal {
public BooleanLiteral(String spelling, SourcePosition posn) {
super (spelling,posn);
}
public <A,R> R visit(Visitor<A,R> v, A o) {
return v.visitBooleanLiteral(this, o);
}
}

View File

@ -0,0 +1,24 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class CallExpr extends Expression
{
public CallExpr(Reference f, ExprList el, SourcePosition posn){
super(posn);
functionRef = f;
argList = el;
}
public <A,R> R visit(Visitor<A,R> v, A o) {
return v.visitCallExpr(this, o);
}
public Reference functionRef;
public ExprList argList;
}

View File

@ -0,0 +1,24 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class CallStmt extends Statement
{
public CallStmt(Reference m, ExprList el, SourcePosition posn){
super(posn);
methodRef = m;
argList = el;
}
public <A,R> R visit(Visitor<A,R> v, A o) {
return v.visitCallStmt(this, o);
}
public Reference methodRef;
public ExprList argList;
}

View File

@ -0,0 +1,24 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class ClassDecl extends Declaration {
public ClassDecl(String cn, FieldDeclList fdl, MethodDeclList mdl, SourcePosition posn) {
super(cn, null, posn);
fieldDeclList = fdl;
methodDeclList = mdl;
}
public <A,R> R visit(Visitor<A, R> v, A o) {
return v.visitClassDecl(this, o);
}
public FieldDeclList fieldDeclList;
public MethodDeclList methodDeclList;
}

View File

@ -0,0 +1,34 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import java.util.*;
public class ClassDeclList implements Iterable<ClassDecl>
{
public ClassDeclList() {
classDeclList = new ArrayList<ClassDecl>();
}
public void add(ClassDecl cd){
classDeclList.add(cd);
}
public ClassDecl get(int i){
return classDeclList.get(i);
}
public int size() {
return classDeclList.size();
}
public Iterator<ClassDecl> iterator() {
return classDeclList.iterator();
}
private List<ClassDecl> classDeclList;
}

View File

@ -0,0 +1,22 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class ClassType extends Type
{
public ClassType(Identifier cn, SourcePosition posn){
super(TypeKind.CLASS, posn);
className = cn;
}
public <A,R> R visit(Visitor<A,R> v, A o) {
return v.visitClassType(this, o);
}
public Identifier className;
}

View File

@ -0,0 +1,20 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public abstract class Declaration extends AST {
public Declaration(String name, Type type, SourcePosition posn) {
super(posn);
this.name = name;
this.type = type;
}
public String name;
public Type type;
}

View File

@ -0,0 +1,14 @@
package miniJava.AbstractSyntaxTrees;
public class Declarators {
public Declarators(boolean isPrivate, boolean isStatic, Type mt) {
this.isPrivate = isPrivate;
this.isStatic = isStatic;
this.mt = mt;
}
public boolean isPrivate;
public boolean isStatic;
public Type mt;
}

View File

@ -0,0 +1,33 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import java.util.*;
public class ExprList implements Iterable<Expression>
{
public ExprList() {
elist = new ArrayList<Expression>();
}
public void add(Expression e){
elist.add(e);
}
public Expression get(int i){
return elist.get(i);
}
public int size() {
return elist.size();
}
public Iterator<Expression> iterator() {
return elist.iterator();
}
private List<Expression> elist;
}

View File

@ -0,0 +1,16 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public abstract class Expression extends AST {
public Expression(SourcePosition posn) {
super (posn);
}
}

View File

@ -0,0 +1,24 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class FieldDecl extends MemberDecl {
public FieldDecl(boolean isPrivate, boolean isStatic, Type t, String name, SourcePosition posn){
super(isPrivate, isStatic, t, name, posn);
}
public FieldDecl(MemberDecl md, SourcePosition posn) {
super(md,posn);
}
public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitFieldDecl(this, o);
}
}

View File

@ -0,0 +1,34 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import java.util.*;
public class FieldDeclList implements Iterable<FieldDecl>
{
public FieldDeclList() {
fieldDeclList = new ArrayList<FieldDecl>();
}
public void add(FieldDecl cd){
fieldDeclList.add(cd);
}
public FieldDecl get(int i){
return fieldDeclList.get(i);
}
public int size() {
return fieldDeclList.size();
}
public Iterator<FieldDecl> iterator() {
return fieldDeclList.iterator();
}
private List<FieldDecl> fieldDeclList;
}

View File

@ -0,0 +1,22 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class IdRef extends Reference {
public IdRef(Identifier id, SourcePosition posn){
super(posn);
this.id = id;
}
public <A,R> R visit(Visitor<A,R> v, A o) {
return v.visitIdRef(this, o);
}
public Identifier id;
}

View File

@ -0,0 +1,20 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class Identifier extends Terminal {
public Identifier (String s, SourcePosition posn) {
super (s,posn);
}
public <A,R> R visit(Visitor<A,R> v, A o) {
return v.visitIdentifier(this, o);
}
}

View File

@ -0,0 +1,33 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class IfStmt extends Statement
{
public IfStmt(Expression b, Statement t, Statement e, SourcePosition posn){
super(posn);
cond = b;
thenStmt = t;
elseStmt = e;
}
public IfStmt(Expression b, Statement t, SourcePosition posn){
super(posn);
cond = b;
thenStmt = t;
elseStmt = null;
}
public <A,R> R visit(Visitor<A,R> v, A o) {
return v.visitIfStmt(this, o);
}
public Expression cond;
public Statement thenStmt;
public Statement elseStmt;
}

View File

@ -0,0 +1,24 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class IndexedRef extends Reference {
public IndexedRef(Reference ref, Expression expr, SourcePosition posn){
super(posn);
this.ref = ref;
this.indexExpr = expr;
}
public <A,R> R visit(Visitor<A,R> v, A o){
return v.visitIndexedRef(this, o);
}
public Reference ref;
public Expression indexExpr;
}

View File

@ -0,0 +1,19 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class IntLiteral extends Literal {
public IntLiteral(String s, SourcePosition posn) {
super(s, posn);
}
public <A,R> R visit(Visitor<A,R> v, A o) {
return v.visitIntLiteral(this, o);
}
}

View File

@ -0,0 +1,15 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public abstract class Literal extends Terminal {
public Literal(String spelling, SourcePosition posn) {
super(spelling, posn);
}
}

View File

@ -0,0 +1,22 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class LiteralExpr extends Expression
{
public LiteralExpr(Literal c, SourcePosition posn){
super(posn);
literal = c;
}
public <A,R> R visit(Visitor<A,R> v, A o){
return v.visitLiteralExpr(this, o);
}
public Literal literal;
}

View File

@ -0,0 +1,16 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public abstract class LocalDecl extends Declaration {
public LocalDecl(String name, Type t, SourcePosition posn){
super(name,t,posn);
}
}

View File

@ -0,0 +1,26 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
abstract public class MemberDecl extends Declaration {
public MemberDecl(boolean isPrivate, boolean isStatic, Type mt, String name, SourcePosition posn) {
super(name, mt, posn);
this.isPrivate = isPrivate;
this.isStatic = isStatic;
}
public MemberDecl(MemberDecl md, SourcePosition posn){
super(md.name, md.type, posn);
this.isPrivate = md.isPrivate;
this.isStatic = md.isStatic;
}
public boolean isPrivate;
public boolean isStatic;
}

View File

@ -0,0 +1,26 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class MethodDecl extends MemberDecl {
public MethodDecl(MemberDecl md, ParameterDeclList pl, StatementList sl, Expression e, SourcePosition posn){
super(md,posn);
parameterDeclList = pl;
statementList = sl;
returnExp = e;
}
public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitMethodDecl(this, o);
}
public ParameterDeclList parameterDeclList;
public StatementList statementList;
public Expression returnExp;
}

View File

@ -0,0 +1,34 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import java.util.*;
public class MethodDeclList implements Iterable<MethodDecl>
{
public MethodDeclList() {
methodDeclList = new ArrayList<MethodDecl>();
}
public void add(MethodDecl cd){
methodDeclList.add(cd);
}
public MethodDecl get(int i){
return methodDeclList.get(i);
}
public int size() {
return methodDeclList.size();
}
public Iterator<MethodDecl> iterator() {
return methodDeclList.iterator();
}
private List<MethodDecl> methodDeclList;
}

View File

@ -0,0 +1,24 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class NewArrayExpr extends NewExpr
{
public NewArrayExpr(Type et, Expression e, SourcePosition posn){
super(posn);
eltType = et;
sizeExpr = e;
}
public <A,R> R visit(Visitor<A,R> v, A o) {
return v.visitNewArrayExpr(this, o);
}
public Type eltType;
public Expression sizeExpr;
}

View File

@ -0,0 +1,15 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public abstract class NewExpr extends Expression {
public NewExpr(SourcePosition posn) {
super (posn);
}
}

View File

@ -0,0 +1,22 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class NewObjectExpr extends NewExpr
{
public NewObjectExpr(ClassType ct, SourcePosition posn){
super(posn);
classtype = ct;
}
public <A,R> R visit(Visitor<A,R> v, A o) {
return v.visitNewObjectExpr(this, o);
}
public ClassType classtype;
}

View File

@ -0,0 +1,22 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
import miniJava.SyntacticAnalyzer.Token;
public class Operator extends Terminal {
public Operator (Token t, SourcePosition posn) {
super (t.spelling, posn);
}
public <A,R> R visit(Visitor<A,R> v, A o) {
return v.visitOperator(this, o);
}
public Token token;
}

View File

@ -0,0 +1,22 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class Package extends AST {
public Package(ClassDeclList cdl, SourcePosition posn) {
super(posn);
classDeclList = cdl;
}
public <A,R> R visit(Visitor<A,R> v, A o) {
return v.visitPackage(this, o);
}
public ClassDeclList classDeclList;
}

View File

@ -0,0 +1,20 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class ParameterDecl extends LocalDecl {
public ParameterDecl(Type t, String name, SourcePosition posn){
super(name, t, posn);
}
public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitParameterDecl(this, o);
}
}

View File

@ -0,0 +1,33 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import java.util.*;
public class ParameterDeclList implements Iterable<ParameterDecl>
{
public ParameterDeclList() {
parameterDeclList = new ArrayList<ParameterDecl>();
}
public void add(ParameterDecl s){
parameterDeclList.add(s);
}
public ParameterDecl get(int i){
return parameterDeclList.get(i);
}
public int size() {
return parameterDeclList.size();
}
public Iterator<ParameterDecl> iterator() {
return parameterDeclList.iterator();
}
private List<ParameterDecl> parameterDeclList;
}

View File

@ -0,0 +1,25 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class QualifiedRef extends Reference {
public QualifiedRef(Reference ref, Identifier id, SourcePosition posn){
super(posn);
this.ref = ref;
this.id = id;
}
@Override
public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitQualifiedRef(this, o);
}
public Reference ref;
public Identifier id;
}

View File

@ -0,0 +1,22 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class RefExpr extends Expression
{
public RefExpr(Reference r, SourcePosition posn){
super(posn);
ref = r;
}
public <A,R> R visit(Visitor<A,R> v, A o) {
return v.visitRefExpr(this, o);
}
public Reference ref;
}

View File

@ -0,0 +1,16 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public abstract class Reference extends AST
{
public Reference(SourcePosition posn){
super(posn);
}
}

View File

@ -0,0 +1,16 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public abstract class Statement extends AST {
public Statement(SourcePosition posn) {
super (posn);
}
}

View File

@ -0,0 +1,33 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import java.util.*;
public class StatementList implements Iterable<Statement>
{
public StatementList() {
slist = new ArrayList<Statement>();
}
public void add(Statement s){
slist.add(s);
}
public Statement get(int i){
return slist.get(i);
}
public int size() {
return slist.size();
}
public Iterator<Statement> iterator() {
return slist.iterator();
}
private List<Statement> slist;
}

View File

@ -0,0 +1,18 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
abstract public class Terminal extends AST {
public Terminal (String s, SourcePosition posn) {
super(posn);
spelling = s;
}
public String spelling;
}

View File

@ -0,0 +1,21 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class ThisRef extends Reference {
public ThisRef(SourcePosition posn) {
super(posn);
}
@Override
public <A, R> R visit(Visitor<A, R> v, A o) {
return v.visitThisRef(this, o);
}
}

View File

@ -0,0 +1,21 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
abstract public class Type extends AST {
public Type(TypeKind typ, SourcePosition posn){
super(posn);
typeKind = typ;
}
public TypeKind typeKind;
}

View File

@ -0,0 +1,16 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
public enum TypeKind {
VOID,
INT,
BOOLEAN,
CLASS,
ARRAY,
UNSUPPORTED,
ERROR;
}

View File

@ -0,0 +1,24 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class UnaryExpr extends Expression
{
public UnaryExpr(Operator o, Expression e, SourcePosition posn){
super(posn);
operator = o;
expr = e;
}
public <A,R> R visit(Visitor<A,R> v, A o) {
return v.visitUnaryExpr(this, o);
}
public Operator operator;
public Expression expr;
}

View File

@ -0,0 +1,19 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class VarDecl extends LocalDecl {
public VarDecl(Type t, String name, SourcePosition posn) {
super(name, t, posn);
}
public <A,R> R visit(Visitor<A,R> v, A o) {
return v.visitVarDecl(this, o);
}
}

View File

@ -0,0 +1,24 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class VarDeclStmt extends Statement
{
public VarDeclStmt(VarDecl vd, Expression e, SourcePosition posn){
super(posn);
varDecl = vd;
initExp = e;
}
public <A,R> R visit(Visitor<A,R> v, A o) {
return v.visitVardeclStmt(this, o);
}
public VarDecl varDecl;
public Expression initExp;
}

View File

@ -0,0 +1,57 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
/**
* An implementation of the Visitor interface provides a method visitX
* for each non-abstract AST class X.
*/
public interface Visitor<ArgType,ResultType> {
// Package
public ResultType visitPackage(Package prog, ArgType arg);
// Declarations
public ResultType visitClassDecl(ClassDecl cd, ArgType arg);
public ResultType visitFieldDecl(FieldDecl fd, ArgType arg);
public ResultType visitMethodDecl(MethodDecl md, ArgType arg);
public ResultType visitParameterDecl(ParameterDecl pd, ArgType arg);
public ResultType visitVarDecl(VarDecl decl, ArgType arg);
// Types
public ResultType visitBaseType(BaseType type, ArgType arg);
public ResultType visitClassType(ClassType type, ArgType arg);
public ResultType visitArrayType(ArrayType type, ArgType arg);
// Statements
public ResultType visitBlockStmt(BlockStmt stmt, ArgType arg);
public ResultType visitVardeclStmt(VarDeclStmt stmt, ArgType arg);
public ResultType visitAssignStmt(AssignStmt stmt, ArgType arg);
public ResultType visitCallStmt(CallStmt stmt, ArgType arg);
public ResultType visitIfStmt(IfStmt stmt, ArgType arg);
public ResultType visitWhileStmt(WhileStmt stmt, ArgType arg);
// Expressions
public ResultType visitUnaryExpr(UnaryExpr expr, ArgType arg);
public ResultType visitBinaryExpr(BinaryExpr expr, ArgType arg);
public ResultType visitRefExpr(RefExpr expr, ArgType arg);
public ResultType visitCallExpr(CallExpr expr, ArgType arg);
public ResultType visitLiteralExpr(LiteralExpr expr, ArgType arg);
public ResultType visitNewObjectExpr(NewObjectExpr expr, ArgType arg);
public ResultType visitNewArrayExpr(NewArrayExpr expr, ArgType arg);
// References
public ResultType visitQualifiedRef(QualifiedRef ref, ArgType arg);
public ResultType visitIndexedRef(IndexedRef ref, ArgType arg);
public ResultType visitIdRef(IdRef ref, ArgType arg);
public ResultType visitThisRef(ThisRef ref, ArgType arg);
// Terminals
public ResultType visitIdentifier(Identifier id, ArgType arg);
public ResultType visitOperator(Operator op, ArgType arg);
public ResultType visitIntLiteral(IntLiteral num, ArgType arg);
public ResultType visitBooleanLiteral(BooleanLiteral bool, ArgType arg);
}

View File

@ -0,0 +1,24 @@
/**
* miniJava Abstract Syntax Tree classes
* @author prins
* @version COMP 520 (v2.2)
*/
package miniJava.AbstractSyntaxTrees;
import miniJava.SyntacticAnalyzer.SourcePosition;
public class WhileStmt extends Statement
{
public WhileStmt(Expression b, Statement s, SourcePosition posn){
super(posn);
cond = b;
body = s;
}
public <A,R> R visit(Visitor<A,R> v, A o) {
return v.visitWhileStmt(this, o);
}
public Expression cond;
public Statement body;
}

View File

@ -1,7 +1,10 @@
package miniJava; package miniJava;
import java.io.*; import java.io.*;
import miniJava.SyntacticAnalyzer.*; import miniJava.SyntacticAnalyzer.*;
import miniJava.AbstractSyntaxTrees.*;
import miniJava.AbstractSyntaxTrees.Package;
public class Compiler { public class Compiler {
@ -16,18 +19,19 @@ public class Compiler {
try(FileReader input = new FileReader(args[0])) { try(FileReader input = new FileReader(args[0])) {
// Setup
Scanner scanner = new Scanner(new BufferedReader(input)); Scanner scanner = new Scanner(new BufferedReader(input));
Parser parser = new Parser(scanner); Parser parser = new Parser(scanner);
parser.parse(); Package p = parser.parse();
System.out.println("Works"); // Display
ASTDisplay display = new ASTDisplay();
display.showTree(p);
System.exit(0); System.exit(0);
} catch(FileNotFoundException e) { } catch(FileNotFoundException e) {
System.out.println("Not Found");
System.exit(rc); System.exit(rc);
} catch(IOException e) { } catch(IOException e) {
System.out.println("Not Works");
System.exit(rc); System.exit(rc);
} }
} }

View File

@ -2,6 +2,8 @@ package miniJava.SyntacticAnalyzer;
import java.io.*; import java.io.*;
import java.util.LinkedList; import java.util.LinkedList;
import miniJava.AbstractSyntaxTrees.*;
import miniJava.AbstractSyntaxTrees.Package;
public class Parser { public class Parser {
@ -13,191 +15,271 @@ public class Parser {
this.stream = new LinkedList<Token>(); this.stream = new LinkedList<Token>();
} }
/** /**
* Program ::= (ClassDeclaration)* eot * Program ::= (ClassDeclaration)* eot
* @return
* @throws IOException * @throws IOException
*/ */
public void parse() throws IOException { public Package parse() throws IOException {
while(peek(1).type == Token.TYPE.CLASS) parseClassDeclaration(); ClassDeclList decls = new ClassDeclList();
while(peek(1).type == Token.TYPE.CLASS) {
decls.add(parseClassDeclaration());
}
accept(Token.TYPE.EOT); accept(Token.TYPE.EOT);
return new Package(decls, null);
} }
/** /**
* ClassDeclaration ::= * ClassDeclaration ::=
* class id { * class id {
* (Declarators id (; | MethodDeclaration))* * (Declarators id (; | MethodDeclaration))*
* } * }
* @return
* @throws IOException * @throws IOException
*/ */
private void parseClassDeclaration() throws IOException { private ClassDecl parseClassDeclaration() throws IOException {
// Class Header // Class Header
accept(Token.TYPE.CLASS); accept(Token.TYPE.CLASS);
accept(Token.TYPE.ID); String cn = accept(Token.TYPE.ID).spelling;
accept(Token.TYPE.LBRACKET); accept(Token.TYPE.LBRACKET);
// Setup
FieldDeclList fdl = new FieldDeclList();
MethodDeclList mdl = new MethodDeclList();
// Class Body // Class Body
while(peek(1).type != Token.TYPE.RBRACKET) { while(peek(1).type != Token.TYPE.RBRACKET) {
parseDeclarators(); Declarators d = parseDeclarators();
accept(Token.TYPE.ID); String name = accept(Token.TYPE.ID).spelling;
if(peek(1).type == Token.TYPE.SEMICOLON) accept(Token.TYPE.SEMICOLON); FieldDecl f = new FieldDecl(d.isPrivate, d.isStatic, d.mt, name, null);
else parseMethodDeclaration();
// Field Declarations
if(peek(1).type == Token.TYPE.SEMICOLON) {
accept(Token.TYPE.SEMICOLON);
fdl.add(f);
}
// Method Declarations
else mdl.add(parseMethodDeclaration(f));
} }
accept(Token.TYPE.RBRACKET); accept(Token.TYPE.RBRACKET);
return new ClassDecl(cn, fdl, mdl, null);
} }
/**
* Declarators ::= (public | private)? static? Type
* @return
* @throws IOException
*/
private Declarators parseDeclarators() throws IOException {
// Visibility
boolean isPrivate = false;
if(peek(1).type == Token.TYPE.PUBLIC) {
accept(Token.TYPE.PUBLIC);
} else if(peek(1).type == Token.TYPE.PRIVATE) {
isPrivate = true;
accept(Token.TYPE.PRIVATE);
}
// Class Methods
boolean isStatic = false;
if(peek(1).type == Token.TYPE.STATIC) {
isStatic = true;
accept(Token.TYPE.STATIC);
}
Type t = parseType();
return new Declarators(isPrivate, isStatic, t);
}
/** /**
* MethodDeclaration ::= * * MethodDeclaration ::=
* (ParameterList?) { * (ParameterList?) {
* Statement* (return Expression ;)? * Statement* (return Expression ;)?
* } * }
* @param f describes the declaratory aspect of the method
* @return
* @throws IOException * @throws IOException
*/ */
private void parseMethodDeclaration() throws IOException { private MethodDecl parseMethodDeclaration(FieldDecl f) throws IOException {
// Method Header // Method Header
accept(Token.TYPE.LPAREN); accept(Token.TYPE.LPAREN);
if(peek(1).type != Token.TYPE.RPAREN) parseParameterList();
// Parameter List
ParameterDeclList pdl = new ParameterDeclList();
if(peek(1).type != Token.TYPE.RPAREN) pdl = parseParameterList();
accept(Token.TYPE.RPAREN); accept(Token.TYPE.RPAREN);
accept(Token.TYPE.LBRACKET); accept(Token.TYPE.LBRACKET);
// Method Body // Method Body
Expression re = null;
StatementList stl = new StatementList();
while(peek(1).type != Token.TYPE.RBRACKET) { while(peek(1).type != Token.TYPE.RBRACKET) {
if(peek(1).type == Token.TYPE.RETURN) { if(peek(1).type == Token.TYPE.RETURN) {
accept(Token.TYPE.RETURN); accept(Token.TYPE.RETURN);
parseExpression(); re = parseExpression();
accept(Token.TYPE.SEMICOLON); accept(Token.TYPE.SEMICOLON);
break; break;
} }
parseStatement(); stl.add(parseStatement());
} }
accept(Token.TYPE.RBRACKET); accept(Token.TYPE.RBRACKET);
return new MethodDecl(f, pdl, stl, re, null);
} }
/**
* Declarators ::= (public | private)? static? Type
* @throws IOException
*/
private void parseDeclarators() throws IOException {
if(peek(1).type == Token.TYPE.PUBLIC) accept(Token.TYPE.PUBLIC);
else if(peek(1).type == Token.TYPE.PRIVATE) accept(Token.TYPE.PRIVATE);
if(peek(1).type == Token.TYPE.STATIC) accept(Token.TYPE.STATIC);
parseType();
}
/** /**
* Type ::= boolean | void | int ([])? | id ([])? * Type ::= boolean | void | int ([])? | id ([])?
* @return
* @throws IOException * @throws IOException
*/ */
private void parseType() throws IOException { private Type parseType() throws IOException {
Token.TYPE type = peek(1).type; switch(peek(1).type) {
switch(type) {
case BOOLEAN: case BOOLEAN:
case VOID: accept(Token.TYPE.BOOLEAN);
accept(type); return new BaseType(TypeKind.BOOLEAN, null);
break;
case VOID:
accept(Token.TYPE.VOID);
return new BaseType(TypeKind.VOID, null);
case INT: {
accept(Token.TYPE.INT);
BaseType b = new BaseType(TypeKind.INT, null);
case INT:
case ID:
accept(type);
if(peek(1).type == Token.TYPE.LSQUARE) { if(peek(1).type == Token.TYPE.LSQUARE) {
accept(Token.TYPE.LSQUARE); accept(Token.TYPE.LSQUARE);
accept(Token.TYPE.RSQUARE); accept(Token.TYPE.RSQUARE);
return new ArrayType(b, null);
} }
break;
return b;
}
case ID: {
String cn = accept(peek(1).type).spelling;
Identifier i = new Identifier(cn, null);
ClassType c = new ClassType(i, null);
if(peek(1).type == Token.TYPE.LSQUARE) {
accept(Token.TYPE.LSQUARE);
accept(Token.TYPE.RSQUARE);
return new ArrayType(c, null);
}
return c;
}
default: default:
throw new IOException(); throw new IOException();
} }
} }
/** /**
* ParameterList ::= Type id (, Type id)* * ParameterList ::= Type id (, Type id)*
* @return
* @throws IOException * @throws IOException
*/ */
private void parseParameterList() throws IOException { private ParameterDeclList parseParameterList() throws IOException {
parseType();
accept(Token.TYPE.ID); ParameterDeclList decls = new ParameterDeclList();
// First Parameter
Type t = parseType();
String name = accept(Token.TYPE.ID).spelling;
decls.add(new ParameterDecl(t, name, null));
// Remainder of List
while(peek(1).type == Token.TYPE.COMMA) { while(peek(1).type == Token.TYPE.COMMA) {
accept(Token.TYPE.COMMA); accept(Token.TYPE.COMMA);
parseType(); t = parseType();
accept(Token.TYPE.ID); name = accept(Token.TYPE.ID).spelling;
decls.add(new ParameterDecl(t, name, null));
} }
return decls;
} }
/** /**
* ArgumentList ::= Expression (, Expression)* * ArgumentList ::= Expression (, Expression)*
* @return
* @throws IOException * @throws IOException
*/ */
private void parseArgumentList() throws IOException { private ExprList parseArgumentList() throws IOException {
parseExpression(); ExprList e = new ExprList();
e.add(parseExpression());
while(peek(1).type == Token.TYPE.COMMA) { while(peek(1).type == Token.TYPE.COMMA) {
accept(Token.TYPE.COMMA); accept(Token.TYPE.COMMA);
parseExpression(); e.add(parseExpression());
} }
return e;
} }
/** /**
* Reference ::= BaseRef (. BaseRef)* * Reference ::= BaseRef (. BaseRef)*
* @return
* @throws IOException * @throws IOException
*/ */
private void parseReference() throws IOException { private Reference parseReference() throws IOException {
parseBaseRef(); Reference r = parseBaseRef();
while(peek(1).type == Token.TYPE.PERIOD) { while(peek(1).type == Token.TYPE.PERIOD) {
accept(Token.TYPE.PERIOD); accept(Token.TYPE.PERIOD);
accept(Token.TYPE.ID); String name = accept(Token.TYPE.ID).spelling;
Identifier id = new Identifier(name, null);
r = new QualifiedRef(r, id, null);
if(peek(1).type == Token.TYPE.LSQUARE) { if(peek(1).type == Token.TYPE.LSQUARE) {
accept(Token.TYPE.LSQUARE); accept(Token.TYPE.LSQUARE);
parseExpression(); Expression e = parseExpression();
accept(Token.TYPE.RSQUARE); accept(Token.TYPE.RSQUARE);
r = new IndexedRef(r, e, null);
}
}
return r;
}
/**
* BaseRef ::= this | id ([ Expression])?
* @return
* @throws IOException
*/
private Reference parseBaseRef() throws IOException {
switch(peek(1).type) {
case THIS:
accept(Token.TYPE.THIS);
return new ThisRef(null);
// id ([ Expression])?
default: {
String id = accept(Token.TYPE.ID).spelling;
Identifier i = new Identifier(id, null);
IdRef r = new IdRef(i, null);
if(peek(1).type == Token.TYPE.LSQUARE) {
accept(Token.TYPE.LSQUARE);
Expression e = parseExpression();
accept(Token.TYPE.RSQUARE);
return new IndexedRef(r, e, null);
}
return r;
} }
} }
} }
/**
* BaseRef ::= this | id ([ Expression])?
* @throws IOException
*/
private void parseBaseRef() throws IOException {
switch(peek(1).type) {
// this
case THIS:
accept(Token.TYPE.THIS);
break;
// id ([ Expression])?
default:
accept(Token.TYPE.ID);
if(peek(1).type == Token.TYPE.LSQUARE) {
accept(Token.TYPE.LSQUARE);
parseExpression();
accept(Token.TYPE.RSQUARE);
}
break;
}
}
/** /**
* Statement ::= * Statement ::=
* {Statement*} * {Statement*}
@ -206,82 +288,100 @@ public class Parser {
* | Reference ( ArgumentList? ); * | Reference ( ArgumentList? );
* | if (Expression) Statement (else Statement)? * | if (Expression) Statement (else Statement)?
* | while (Expression) Statement * | while (Expression) Statement
* @return
* @throws IOException * @throws IOException
*/ */
private void parseStatement() throws IOException { private Statement parseStatement() throws IOException {
switch(peek(1).type) { switch(peek(1).type) {
// { Statement* } // { Statement* }
case LBRACKET: case LBRACKET: {
accept(Token.TYPE.LBRACKET); accept(Token.TYPE.LBRACKET);
StatementList stl = new StatementList();
while(peek(1).type != Token.TYPE.RBRACKET) { while(peek(1).type != Token.TYPE.RBRACKET) {
parseStatement(); stl.add(parseStatement());
} }
accept(Token.TYPE.RBRACKET); accept(Token.TYPE.RBRACKET);
break;
return new BlockStmt(stl, null);
}
// if (Expression) Statement (else Statement)? // if (Expression) Statement (else Statement)?
case IF: case IF: {
accept(Token.TYPE.IF); accept(Token.TYPE.IF);
accept(Token.TYPE.LPAREN); accept(Token.TYPE.LPAREN);
parseExpression(); Expression e = parseExpression();
accept(Token.TYPE.RPAREN); accept(Token.TYPE.RPAREN);
parseStatement(); Statement s1 = parseStatement();
if(peek(1).type == Token.TYPE.ELSE) { if(peek(1).type == Token.TYPE.ELSE) {
accept(Token.TYPE.ELSE); accept(Token.TYPE.ELSE);
parseStatement(); Statement s2 = parseStatement();
return new IfStmt(e, s1, s2, null);
} }
break;
return new IfStmt(e, s1, null);
}
// while (Expression) Statement // while (Expression) Statement
case WHILE: case WHILE: {
accept(Token.TYPE.WHILE); accept(Token.TYPE.WHILE);
accept(Token.TYPE.LPAREN); accept(Token.TYPE.LPAREN);
parseExpression(); Expression e = parseExpression();
accept(Token.TYPE.RPAREN); accept(Token.TYPE.RPAREN);
parseStatement(); Statement s = parseStatement();
break;
return new WhileStmt(e, s, null);
}
// Type id = Expression ; // Type id = Expression ;
case BOOLEAN: case BOOLEAN: case VOID: case INT: case ID: {
case VOID:
case INT:
case ID:
// Must be a type though there is a possibility of a reference // Must be a type though there is a possibility of a reference
if(peek(1).type != Token.TYPE.ID if(peek(1).type != Token.TYPE.ID || peek(2).type == Token.TYPE.ID
|| peek(2).type == Token.TYPE.ID
||(peek(2).type == Token.TYPE.LSQUARE && peek(3).type == Token.TYPE.RSQUARE)) { ||(peek(2).type == Token.TYPE.LSQUARE && peek(3).type == Token.TYPE.RSQUARE)) {
parseType(); Type t = parseType();
accept(Token.TYPE.ID); String name = accept(Token.TYPE.ID).spelling;
VarDecl v = new VarDecl(t, name, null);
accept(Token.TYPE.EQUALS); accept(Token.TYPE.EQUALS);
parseExpression(); Expression e = parseExpression();
accept(Token.TYPE.SEMICOLON); accept(Token.TYPE.SEMICOLON);
break;
return new VarDeclStmt(v, e, null);
} }
/* Fall Through */ /* Fall Through */
}
default: {
Statement s = null;
Reference r = parseReference();
// Reference = Expression ; | Reference ( ArgumentList? ) ; // Reference ( ArgumentList? ) ;
default:
parseReference();
if(peek(1).type == Token.TYPE.LPAREN) { if(peek(1).type == Token.TYPE.LPAREN) {
ExprList e = new ExprList();
accept(Token.TYPE.LPAREN); accept(Token.TYPE.LPAREN);
if(peek(1).type != Token.TYPE.RPAREN) parseArgumentList(); if(peek(1).type != Token.TYPE.RPAREN) {
e = parseArgumentList();
}
accept(Token.TYPE.RPAREN); accept(Token.TYPE.RPAREN);
} else { s = new CallStmt(r, e, null);
}
// Reference = Expression ;
else {
accept(Token.TYPE.EQUALS); accept(Token.TYPE.EQUALS);
parseExpression(); Expression e = parseExpression();
s = new AssignStmt(r, e, null);
} }
accept(Token.TYPE.SEMICOLON); accept(Token.TYPE.SEMICOLON);
break; return s;
} }
}
} }
/** /**
* Expression ::= * Expression ::=
* Reference * Reference
@ -291,92 +391,198 @@ public class Parser {
* | ( Expression ) * | ( Expression )
* | num | true | false * | num | true | false
* | new (id() | int [ Expression ] | id [ Expression ] ) * | new (id() | int [ Expression ] | id [ Expression ] )
* @return
* @throws IOException * @throws IOException
*/ */
private void parseExpression() throws IOException { private Expression parseExpression() throws IOException {
Expression e = null;
switch(peek(1).type) { switch(peek(1).type) {
// num | true | false // num
case NUM: case NUM: {
case TRUE: String number = accept(Token.TYPE.NUM).spelling;
case FALSE: IntLiteral i = new IntLiteral(number, null);
accept(peek(1).type); e = new LiteralExpr(i, null);
break; break;
}
// true | false
case TRUE:
case FALSE: {
String bool = accept(peek(1).type).spelling;
BooleanLiteral b = new BooleanLiteral(bool, null);
e = new LiteralExpr(b, null);
break;
}
// ( Expression ) // ( Expression )
case LPAREN: case LPAREN: {
accept(Token.TYPE.LPAREN); accept(Token.TYPE.LPAREN);
parseExpression(); e = parseExpression();
accept(Token.TYPE.RPAREN); accept(Token.TYPE.RPAREN);
break; break;
}
// unop Expression // unop Expression
case UNOP: case UNOP:
accept(Token.TYPE.UNOP); case BINOP: {
parseExpression(); if(peek(1).spelling.equals("!") || peek(1).spelling.equals("-")) {
break; Operator o = new Operator(accept(peek(1).type), null);
e = new UnaryExpr(o, parseExpression(), null);
// Must be a minus sign }
case BINOP:
if(peek(1).attr.equals("-")) {
accept(Token.TYPE.BINOP);
parseExpression();
}
else throw new IOException(); else throw new IOException();
break; break;
}
// new ( int [ Expression ] | id ( ) | id [ Expression ] ) // new ( int [ Expression ] | id ( ) | id [ Expression ] )
case NEW: case NEW: {
accept(Token.TYPE.NEW); accept(Token.TYPE.NEW);
if(peek(1).type == Token.TYPE.INT) { if(peek(1).type == Token.TYPE.INT) {
accept(Token.TYPE.INT); accept(Token.TYPE.INT);
accept(Token.TYPE.LSQUARE); accept(Token.TYPE.LSQUARE);
parseExpression(); Expression e2 = parseExpression();
accept(Token.TYPE.RSQUARE); accept(Token.TYPE.RSQUARE);
BaseType b = new BaseType(TypeKind.INT, null);
e = new NewArrayExpr(b, e2, null);
} }
else { else {
accept(Token.TYPE.ID); String cn = accept(Token.TYPE.ID).spelling;
Identifier i = new Identifier(cn, null);
ClassType c = new ClassType(i, null);
if(peek(1).type == Token.TYPE.LPAREN){ if(peek(1).type == Token.TYPE.LPAREN){
accept(Token.TYPE.LPAREN); accept(Token.TYPE.LPAREN);
accept(Token.TYPE.RPAREN); accept(Token.TYPE.RPAREN);
} e = new NewObjectExpr(c, null);
} else {
else {
accept(Token.TYPE.LSQUARE); accept(Token.TYPE.LSQUARE);
parseExpression(); Expression e2 = parseExpression();
accept(Token.TYPE.RSQUARE); accept(Token.TYPE.RSQUARE);
e = new NewArrayExpr(c, e2, null);
} }
} }
break; break;
}
// Reference | Reference (ArgumentList?) // Reference ((ArgumentList?))?
case THIS: case THIS: case ID: {
case ID: Reference r = parseReference();
parseReference();
if(peek(1).type == Token.TYPE.LPAREN) { if(peek(1).type == Token.TYPE.LPAREN) {
accept(Token.TYPE.LPAREN); accept(Token.TYPE.LPAREN);
if(peek(1).type != Token.TYPE.RPAREN) parseArgumentList(); ExprList el = new ExprList();
if(peek(1).type != Token.TYPE.RPAREN) {
el = parseArgumentList();
}
accept(Token.TYPE.RPAREN); accept(Token.TYPE.RPAREN);
e = new CallExpr(r, el, null);
} else {
e = new RefExpr(r, null);
} }
break;
// Expression binop Expression
default:
accept(Token.TYPE.BINOP);
parseExpression();
break; break;
}
default:
throw new IOException();
} }
// Expression binop Expression // Expression binop Expression
if(peek(1).type == Token.TYPE.BINOP) { if(peek(1).type == Token.TYPE.BINOP) {
accept(Token.TYPE.BINOP); Operator o = new Operator(accept(Token.TYPE.BINOP), null);
parseExpression(); e = new BinaryExpr(o, e, parseDExpression(), null);
} }
return e;
}
/**
* Disjunction
* @throws IOException
*/
private Expression parseDExpression() throws IOException {
Expression e = parseCExpression();
while(peek(1).spelling.equals("||")) {
Operator o = new Operator(accept(Token.TYPE.BINOP), null);
e = new BinaryExpr(o, e, parseCExpression(), null);
}
return e;
}
/**
* Conjunction
* @throws IOException
*/
private Expression parseCExpression() throws IOException {
Expression e = parseEExpression();
while(peek(1).spelling.equals("&&")) {
Operator o = new Operator(accept(Token.TYPE.BINOP), null);
e = new BinaryExpr(o, e, parseEExpression(), null);
}
return e;
}
/**
* Equality
* @throws IOException
*/
private Expression parseEExpression() throws IOException {
Expression e = parseRExpression();
while(peek(1).spelling.equals("==") || peek(1).spelling.equals("!=")) {
Operator o = new Operator(accept(Token.TYPE.BINOP), null);
e = new BinaryExpr(o, e, parseRExpression(), null);
}
return e;
}
/**
* Relational
* @throws IOException
*/
private Expression parseRExpression() throws IOException {
Expression e = parseAExpression();
while(peek(1).spelling.equals("<=") || peek(1).spelling.equals(">=")
|| peek(1).spelling.equals("<") || peek(1).spelling.equals(">")) {
Operator o = new Operator(accept(Token.TYPE.BINOP), null);
e = new BinaryExpr(o, e, parseAExpression(), null);
}
return e;
}
/**
* Additive
* @throws IOException
*/
private Expression parseAExpression() throws IOException {
Expression e = parseMExpression();
while(peek(1).spelling.equals("+") || peek(1).spelling.equals("-")) {
Operator o = new Operator(accept(Token.TYPE.BINOP), null);
e = new BinaryExpr(o, e, parseMExpression(), null);
}
return e;
}
/**
* Multiplicative
* @throws IOException
*/
private Expression parseMExpression() throws IOException {
Expression e = parseExpression();
while(peek(1).spelling.equals("*") || peek(1).spelling.equals("/")) {
Operator o = new Operator(accept(Token.TYPE.BINOP), null);
e = new BinaryExpr(o, e, parseExpression(), null);
}
return e;
} }
@ -401,9 +607,11 @@ public class Parser {
* Consumes token or throws exception. * Consumes token or throws exception.
* @throws IOException * @throws IOException
*/ */
private void accept(Token.TYPE type) throws IOException { private Token accept(Token.TYPE type) throws IOException {
Token next = peek(1); Token next = peek(1);
if(next.type == type) stream.poll(); if(next.type == type) stream.poll();
else throw new IOException(); else throw new IOException();
return next;
} }
} }

View File

@ -153,7 +153,7 @@ public class Scanner {
break; break;
} }
} }
System.out.println(token.type);
return token; return token;
} }

View File

@ -0,0 +1,12 @@
package miniJava.SyntacticAnalyzer;
public class SourcePosition {
public final int col;
public final int line;
public SourcePosition(int line, int col) {
this.col = col;
this.line = line;
}
}

View File

@ -69,10 +69,10 @@ public class Token {
} }
public final TYPE type; public final TYPE type;
public final String attr; public final String spelling;
public Token(String attr, TYPE type) { public Token(String spelling, TYPE type) {
this.type = type; this.type = type;
this.attr = attr; this.spelling = spelling;
} }
} }

View File

@ -31,10 +31,10 @@ Statement ::=
| while (Expression) Statement | while (Expression) Statement
Expression ::= Expression ::=
Reference Reference ((ArgumentList?))?
| Reference ( ArgumentList? )
| unop Expression | unop Expression
| Expression binop Expression | Expression binop Expression
| ( Expression ) | ( Expression )
| num | true | false | num | true | false
| new (id() | int [ Expression ] | id [ Expression ] ) | new (id() | int [ Expression ] | id [ Expression ] )

View File

@ -0,0 +1,50 @@
Program ::= (ClassDeclaration)* eot
ClassDeclaration ::=
class id {
(Declarators id (; | MethodDeclaration))*
}
MethodDeclaration ::=
(ParameterList?) {
Statement* (return Expression ;)?
}
Declarators ::= (public | private)? static? Type
Type ::= boolean | void | int ([])? | id ([])?
ParameterList ::= Type id (, Type id)*
ArgumentList ::= Expression (, Expression)*
Reference ::= BaseRef (. id ([ Expression])?)*
BaseRef ::= this | id ([ Expression])?
Statement ::=
{Statement*}
| Type id = Expression;
| Reference = Expression;
| Reference ( ArgumentList? );
| if (Expression) Statement (else Statement)?
| while (Expression) Statement
Expression ::=
num | true | false
| ( Expression )
| new (id() | int [ Expression ] | id [ Expression ] )
| Reference ((ArgumentList?))?
| DExpression
DExpression ::= CExpression (|| CExpression)*
CExpression ::= EExpression (&& EExpression)*
EExpression ::= RExpression ((==|!=) RExpression)*
RExpression ::= AExpression ((<=|<|>|>=) AExpression)*
AExpression ::= MExpression ((+|-) MExpression)*
MExpression ::= Expression ((*|/) Expression)*

View File

@ -1,7 +1,12 @@
// PA1 parse assign fail // Simple PA2 Example
class Test { class PA2 {
void p(int a) { public boolean c;
that.this = 4;
} public static void main(String[] args) {
if(x > 1)
x = 1 + 2 * x;
else
b[3].a = 4;
}
} }