--- /dev/null
+package IR;
+
+/**
+ * Descriptor
+ *
+ * represents a symbol in the language (var name, function name, etc).
+ */
+
+public abstract class Descriptor {
+
+ protected String name;
+ protected String safename;
+ static int count=0;
+ int uniqueid;
+
+ public Descriptor(String name) {
+ this.name = name;
+ this.safename = "__" + name + "__";
+ this.uniqueid=count++;
+ }
+
+ protected Descriptor(String name, String safename) {
+ this.name = name;
+ this.safename = safename;
+ this.uniqueid=count++;
+ }
+
+ public String toString() {
+ return name;
+ }
+
+ public String getSymbol() {
+ return name;
+ }
+
+ public String getSafeSymbol() {
+ return safename;
+ }
+ public int getNum() {
+ return uniqueid;
+ }
+}
--- /dev/null
+package IR;
+import IR.Tree.Modifiers;
+
+/**
+ * Descriptor
+ *
+ * represents a symbol in the language (var name, function name, etc).
+ */
+
+public class FieldDescriptor extends Descriptor {
+
+ protected Modifiers modifier;
+ protected TypeDescriptor td;
+
+ public FieldDescriptor(Modifiers m, TypeDescriptor t, String name) {
+ super(name);
+ this.modifier=m;
+ this.td=t;
+ this.safename = "__" + name + "__";
+ this.uniqueid=count++;
+ }
+
+ public String toString() {
+ return modifier.toString()+";";
+ }
+}
-class State {
+package IR;
+import IR.Tree.*;
+public class State {
+ public State(ParseNode parsetree) {
+ globals=new SymbolTable();
+ this.parsetree=parsetree;
+ }
+ public SymbolTable globals;
+ public ParseNode parsetree;
}
--- /dev/null
+package IR;
+
+import java.util.*;
+
+public class SymbolTable {
+
+ private Hashtable table;
+ private SymbolTable parent;
+
+ public SymbolTable() {
+ table = new Hashtable();
+ this.parent = null;
+ }
+
+ public SymbolTable(SymbolTable parent) {
+ table = new Hashtable();
+ this.parent = parent;
+ }
+
+ //public void add(String name, Descriptor d) {
+ //table.put(name, d);
+ //}
+
+ public void add(Descriptor d) {
+ table.put(d.getSymbol(), d);
+ }
+
+ public void add(String name, Descriptor d) {
+ table.put(name, d);
+
+ }
+
+ public void dump() {
+ Enumeration e = getDescriptors();
+ while (e.hasMoreElements()) {
+ Descriptor d = (Descriptor) e.nextElement();
+ System.out.println(d.getSymbol());
+ }
+ if (parent != null) {
+ System.out.println("parent:");
+ parent.dump();
+ }
+ }
+
+ public Descriptor get(String name) {
+ Descriptor d = (Descriptor) table.get(name);
+ if (d == null && parent != null) {
+ return parent.get(name);
+ } else {
+ return d;
+ }
+ }
+
+ public Descriptor getFromSameScope(String name) {
+ return (Descriptor)table.get(name);
+ }
+
+ public Enumeration getNames() {
+ return table.keys();
+ }
+
+ public Enumeration getDescriptors() {
+ return table.elements();
+ }
+
+ public Iterator descriptors() {
+ return table.values().iterator();
+ }
+
+ public Vector getAllDescriptors() {
+ Vector d;
+ if (parent == null) {
+ d = new Vector();
+ } else {
+ d = parent.getAllDescriptors();
+ }
+
+ Enumeration e = getDescriptors();
+ while(e.hasMoreElements()) {
+ d.addElement(e.nextElement());
+ }
+
+ return d;
+ }
+
+ public boolean contains(String name) {
+ return (get(name) != null);
+ }
+
+
+ public int size() {
+ return table.size();
+ }
+
+ public int sizeAll() {
+ if (parent != null) {
+ return parent.sizeAll() + table.size();
+ } else {
+ return table.size();
+ }
+ }
+
+ public SymbolTable getParent() {
+ return parent;
+ }
+
+ public void setParent(SymbolTable parent) {
+ this.parent = parent;
+ }
+
+ /**
+ * Adds contents of st2.table to this.table and returns a
+ * Vector of shared names, unless there are no shared names,
+ * in which case returns null.
+ */
+ public Vector merge(SymbolTable st2) {
+ Vector v = new Vector();
+ Enumeration names = st2.table.keys();
+
+ while (names.hasMoreElements()) {
+ Object o = names.nextElement();
+
+ if (table.containsKey(o)) {
+ v.addElement(o);
+ } else {
+ table.put(o, st2.table.get(o));
+ }
+ }
+
+ if (v.size() == 0) {
+ return null;
+ } else {
+ return v;
+ }
+ }
+
+ public String toString() {
+ return "ST: " + table.toString();
+ }
+}
--- /dev/null
+package IR.Tree;
+import IR.*;
+
+public class BuildIR {
+ State state;
+ public BuildIR(State state) {
+ this.state=state;
+ }
+ public void buildtree() {
+ ParseNode pn=state.parsetree;
+ FileNode fn=parseFile(pn);
+ System.out.println(fn.printNode());
+ }
+
+ /** Parse the classes in this file */
+ public FileNode parseFile(ParseNode pn) {
+ FileNode fn=new FileNode();
+ ParseNode tpn=pn.getChild("type_declaration_list");
+ if (tpn!=null) {
+ ParseNodeVector pnv=tpn.getChildren();
+ for(int i=0;i<pnv.size();i++) {
+ ParseNode type_pn=pnv.elementAt(i);
+ if (isEmpty(type_pn)) /* Skip the semicolon */
+ continue;
+ ClassNode cn=parseTypeDecl(type_pn);
+ fn.addClass(cn);
+ }
+ }
+ return fn;
+ }
+
+ public ClassNode parseTypeDecl(ParseNode pn) {
+ if (isNode(pn, "class_declaration")) {
+ ClassNode cn=new ClassNode();
+ cn.setName(pn.getChild("name").getTerminal());
+ if (!isEmpty(pn.getChild("super").getTerminal())) {
+ /* parse superclass name */
+ }
+ cn.setModifiers(parseModifiersList(pn.getChild("modifiers")));
+ parseClassBody(cn, pn.getChild("classbody"));
+ return cn;
+ } else throw new Error();
+ }
+
+ private void parseClassBody(ClassNode cn, ParseNode pn) {
+ ParseNode decls=pn.getChild("class_body_declaration_list");
+ if (decls!=null) {
+ ParseNodeVector pnv=decls.getChildren();
+ for(int i=0;i<pnv.size();i++) {
+ ParseNode decl=pnv.elementAt(i);
+ if (isNode(decl,"member")) {
+ parseClassMember(cn,decl);
+ } else if (isNode(decl,"constructor")) {
+ } else if (isNode(decl,"block")) {
+ } else throw new Error();
+ }
+ }
+ }
+
+ private void parseClassMember(ClassNode cn, ParseNode pn) {
+ ParseNode fieldnode=pn.getChild("field");
+
+ if (fieldnode!=null) {
+ FieldDescriptor fd=parseFieldDecl(fieldnode.getChild("field_declaration"));
+ cn.addField(fd);
+ return;
+ }
+ ParseNode methodnode=pn.getChild("method");
+ if (methodnode!=null) {
+ parseMethodDecl(cn,methodnode);
+ return;
+ }
+ throw new Error();
+ }
+
+ private FieldDescriptor parseFieldDecl(ParseNode pn) {
+ ParseNode mn=pn.getChild("modifier");
+ Modifiers m=parseModifiersList(mn);
+ return new FieldDescriptor(m,null,null);
+ }
+
+ private void parseMethodDecl(ClassNode cn, ParseNode pn) {
+
+ }
+
+ public Modifiers parseModifiersList(ParseNode pn) {
+ Modifiers m=new Modifiers();
+ ParseNode modlist=pn.getChild("modifier_list");
+ if (modlist!=null) {
+ ParseNodeVector pnv=modlist.getChildren();
+ for(int i=0;i<pnv.size();i++) {
+ ParseNode modn=pnv.elementAt(i);
+ if (isNode(modn,"public"))
+ m.addModifier(Modifiers.PUBLIC);
+ if (isNode(modn,"protected"))
+ m.addModifier(Modifiers.PROTECTED);
+ if (isNode(modn,"private"))
+ m.addModifier(Modifiers.PRIVATE);
+ if (isNode(modn,"static"))
+ m.addModifier(Modifiers.STATIC);
+ if (isNode(modn,"final"))
+ m.addModifier(Modifiers.FINAL);
+ if (isNode(modn,"native"))
+ m.addModifier(Modifiers.NATIVE);
+ }
+ }
+ return m;
+ }
+
+ private boolean isNode(ParseNode pn, String label) {
+ if (pn.getLabel().equals(label))
+ return true;
+ else return false;
+ }
+
+ private static boolean isEmpty(ParseNode pn) {
+ if (pn.getLabel().equals("empty"))
+ return true;
+ else
+ return false;
+ }
+
+ private static boolean isEmpty(String s) {
+ if (s.equals("empty"))
+ return true;
+ else
+ return false;
+ }
+
+
+ /** Throw an exception if something is unexpected */
+ private void check(ParseNode pn, String label) {
+ if (pn == null) {
+ throw new Error(pn+ "IE: Expected '" + label + "', got null");
+ }
+ if (! pn.getLabel().equals(label)) {
+ throw new Error(pn+ "IE: Expected '" + label + "', got '"+pn.getLabel()+"'");
+ }
+ }
+
+}
--- /dev/null
+package IR.Tree;
+import java.util.Vector;
+import IR.FieldDescriptor;
+
+class ClassNode extends TreeNode {
+ ClassNode() {
+ classname=null;
+ superclass=null;
+ fields=new Vector();
+ }
+ String classname;
+ Name superclass;
+ Modifiers modifiers;
+ Vector fields;
+
+ public String printNode() {
+ String st=modifiers.toString()+classname;
+ if (superclass!=null)
+ st+="extends "+superclass.toString();
+ st+=" {\n";
+ for(int i=0;i<fields.size();i++) {
+ FieldDescriptor fd=(FieldDescriptor)fields.get(i);
+ st+=fd.toString()+"\n";
+ }
+ st+="}\n";
+ return st;
+ }
+
+ public void addField(FieldDescriptor fd) {
+ fields.add(fd);
+ }
+
+ public void setModifiers(Modifiers modifiers) {
+ this.modifiers=modifiers;
+ }
+ void setName(String name) {
+ classname=name;
+ }
+ void setSuper(Name superclass) {
+ this.superclass=superclass;
+ }
+}
--- /dev/null
+package IR.Tree;
+import java.util.Vector;
+
+class FileNode extends TreeNode {
+ private Vector type_decls;
+
+ FileNode() {
+ type_decls=new Vector();
+ }
+
+ public void addClass(ClassNode tdn) {
+ type_decls.add(tdn);
+ }
+
+ public String printNode() {
+ String st="";
+ for(int i=0;i<type_decls.size();i++) {
+ ClassNode cn=(ClassNode) type_decls.get(i);
+ st+=cn.printNode();
+
+ }
+ return st;
+ }
+}
--- /dev/null
+package IR.Tree;
+
+public class Modifiers {
+ public static final int PUBLIC=1;
+ public static final int PROTECTED=2;
+ public static final int PRIVATE=4;
+ public static final int STATIC=8;
+// ABSTRACT=16
+ public static final int FINAL=32;
+ public static final int NATIVE=64;
+// SYNCHRONIZED=128
+// TRANSIENT=256
+// VOLATILE=512
+// STRICTFP=1024
+
+ private int value;
+
+ public Modifiers() {
+ value=0;
+ }
+
+ public void addModifier(int mod) {
+ value|=mod;
+ }
+
+ public String toString() {
+ String st="";
+ if ((value&PUBLIC)!=0)
+ st+="public ";
+ if ((value&PROTECTED)!=0)
+ st+="protected ";
+ if ((value&PRIVATE)!=0)
+ st+="private ";
+ if ((value&STATIC)!=0)
+ st+="static ";
+ if ((value&FINAL)!=0)
+ st+="final ";
+ if ((value&NATIVE)!=0)
+ st+="native ";
+ return st;
+ }
+}
--- /dev/null
+package IR.Tree;
+
+class TreeNode {
+
+ public String printNode() {
+ return null;
+ }
+}
--- /dev/null
+package IR;
+
+/**
+ * Descriptor
+ *
+ * represents a symbol in the language (var name, function name, etc).
+ */
+
+public class TypeDescriptor extends Descriptor {
+
+ public TypeDescriptor(String name) {
+ super(name);
+ }
+
+
+}
import java.io.BufferedReader;
import java.io.FileReader;
import IR.Tree.ParseNode;
+import IR.Tree.BuildIR;
+import IR.State;
/* Test skeleton for java parser/lexer.
* Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu>
g = new Parse.Parser(l);
ParseNode p=(ParseNode) g./*debug_*/parse().value;
System.out.println(p.PPrint(4,true));
+ State state=new State(p);
+ BuildIR bir=new BuildIR(state);
+ bir.buildtree();
System.exit(l.numErrors());
}
}
Lex/StringLiteral.class Lex/Token.class Lex/TraditionalComment.class \
Lex/WhiteSpace.class IR/Tree/ParseNode.class \
IR/Tree/ParseNodeDOTVisitor.class IR/Tree/ParseNodeVector.class \
-IR/Tree/Walkable.class
+IR/Tree/Walkable.class IR/State.class IR/SymbolTable.class \
+IR/Descriptor.class IR/Tree/Modifiers.class IR/Tree/FileNode.class \
+IR/Tree/ClassNode.java IR/Tree/TreeNode.class IR/Tree/BuildIR.class \
+IR/TypeDescriptor.java IR/FieldDescriptor.java
all: Parse/Sym.class Parse/Parser.class $(CLASSFILES)
// 19.2) The Syntactic Grammar
goal ::= compilation_unit:cu
{:
- RESULT = (new ParseNode("goal")).addChild(cu).getRoot();
+ RESULT = cu;
:}
;
// import_declarations_opt
type_declarations_opt:tdo {:
ParseNode pn=new ParseNode("compilation_unit");
- pn.addChild("types").addChild(tdo);
+ pn.addChild(tdo);
RESULT=pn;
:}
;
type_declaration ::=
class_declaration:cd
{:
- RESULT=(new ParseNode("type_declaration")).addChild("class").addChild(cd);
+ RESULT=cd;
:}
// | interface_declaration
| SEMICOLON {: RESULT=new ParseNode("empty"); :}
// 19.8.1) Class Declaration:
class_declaration ::=
- modifiers_opt:mo CLASS IDENTIFIER:id super_opt:so {:
- ParseNode pn=new ParseNode("class_declaration");
- pn.addChild("modifiers").addChild(mo);
- pn.addChild("name").addChild(id);
- pn.addChild("super").addChild(so);
- RESULT=pn;
- :}
-//interfaces_opt
+ modifiers_opt:mo CLASS IDENTIFIER:id super_opt:so //interfaces_opt
class_body:body
{:
ParseNode pn=new ParseNode("class_declaration");
pn.addChild("modifiers").addChild(mo);
pn.addChild("name").addChild(id);
pn.addChild("super").addChild(so);
- pn.addChild("body").addChild(body);
+ pn.addChild("classbody").addChild(body);
RESULT=pn;
:}
;
super ::= EXTENDS class_type:classtype {:
- ParseNode pn=new ParseNode("super");
- pn.addChild(classtype);
- RESULT=pn;
+ RESULT=classtype;
:}
;
super_opt ::=
class_body_declaration ::=
class_member_declaration:member {:
- RESULT=(new ParseNode("class_body_declaration")).addChild("member").addChild(member).getRoot();
+ RESULT=(new ParseNode("member")).addChild(member).getRoot();
:}
// | static_initializer
| constructor_declaration:constructor {:
- RESULT=(new ParseNode("class_body_declaration")).addChild("constructor").addChild(constructor).getRoot();
+ RESULT=(new ParseNode("constructor")).addChild(constructor).getRoot();
:}
| block:block {:
- RESULT=(new ParseNode("class_body_declaration")).addChild("block").addChild(block).getRoot();
+ RESULT=(new ParseNode("block")).addChild(block).getRoot();
:}
;
class_member_declaration ::=
field_declaration:field {:
- RESULT=(new ParseNode("class_member_declaration")).addChild("field").addChild(field).getRoot();
+ RESULT=(new ParseNode("field")).addChild(field).getRoot();
:}
| method_declaration:method {:
- RESULT=(new ParseNode("class_member_declaration")).addChild("method").addChild(method).getRoot();
+ RESULT=(new ParseNode("method")).addChild(method).getRoot();
:}
/* repeat the prod for 'class_declaration' here: */
// | modifiers_opt CLASS IDENTIFIER super_opt class_body