summaryrefslogtreecommitdiff
path: root/src/main/java/io/devnulllabs/openjava/ptree/ParseTreeObject.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/io/devnulllabs/openjava/ptree/ParseTreeObject.java')
-rw-r--r--src/main/java/io/devnulllabs/openjava/ptree/ParseTreeObject.java267
1 files changed, 267 insertions, 0 deletions
diff --git a/src/main/java/io/devnulllabs/openjava/ptree/ParseTreeObject.java b/src/main/java/io/devnulllabs/openjava/ptree/ParseTreeObject.java
new file mode 100644
index 0000000..f52dec0
--- /dev/null
+++ b/src/main/java/io/devnulllabs/openjava/ptree/ParseTreeObject.java
@@ -0,0 +1,267 @@
+/*
+ * ParseTreeObject.java 1.0
+ *
+ * This subclass of symbol represents (at least) terminal symbols returned
+ * by the scanner and placed on the parse stack. At present, this
+ * class does nothing more than its super class.
+ *
+ * Jun 11, 1997
+ * Sep 5, 1997
+ *
+ * @see java_cup.runtime.symbol
+ * @version 1.0 last updated: Sep 5, 1997
+ * @author Michiaki Tatsubori
+ */
+package io.devnulllabs.openjava.ptree;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.StringTokenizer;
+
+import io.devnulllabs.openjava.ptree.util.ParseTreeVisitor;
+import io.devnulllabs.openjava.ptree.util.SourceCodeWriter;
+
+/**
+ * The ParseTree class presents for the node of parse tree.
+ * This may be a token node, Leaf, or may be a nonterminal node, NonLeaf.
+ *
+ * @see io.devnulllabs.openjava.ptree.Leaf
+ * @see io.devnulllabs.openjava.ptree.NonLeaf
+ */
+public abstract class ParseTreeObject
+ extends Object
+ implements ParseTree, Cloneable {
+ /**
+ * Why this modifier is not final ?
+ * - Because of javac bug in excuting it with -O option.
+ */
+ protected static String LN;
+ static {
+ StringWriter strw = new StringWriter();
+ PrintWriter pw = new PrintWriter(strw);
+ pw.println();
+ pw.close();
+ LN = strw.toString();
+ }
+
+ private ParseTreeObject parent;
+ /*************/
+ public /*private*/
+ final ParseTreeObject getParent() {
+ return parent;
+ }
+ protected final void setParent(ParseTreeObject parent) {
+ this.parent = parent;
+ }
+ public final void replace(ParseTree replacement)
+ throws ParseTreeException {
+ ParseTreeObject p = getParent();
+ if (p == null)
+ throw new ParseTreeException("no parent");
+ p.replaceChildWith(this, replacement);
+ }
+ protected abstract void replaceChildWith(
+ ParseTree dist,
+ ParseTree replacement)
+ throws ParseTreeException;
+
+ /**
+ * Arrocates new parse-tree object and set identifier number
+ * on the object.
+ *
+ */
+ public ParseTreeObject() {
+ setObjectID();
+ }
+
+ /**
+ * clone() is fixed as a shallow copy.
+ *
+ * @return the copy of this ptree-node.
+ */
+ protected final Object clone() {
+ try {
+ ParseTreeObject result = (ParseTreeObject) super.clone();
+ result.setObjectID();
+ return result;
+ } catch (CloneNotSupportedException e) {
+ return null;
+ }
+ }
+
+ /**
+ * shallow copy
+ */
+ public ParseTree makeCopy() {
+ return (ParseTree) clone();
+ }
+
+ /**
+ * deep copy
+ */
+ public abstract ParseTree makeRecursiveCopy();
+
+ /**
+ * Tests if this parse-tree-node's value equals to the specified
+ * ptree-node's.
+ *
+ * @return true if two values are same.
+ */
+ public abstract boolean equals(ParseTree p);
+
+ public int hashCode() {
+ return getObjectID();
+ }
+
+ /**
+ * Generates a string object of regular Java source code
+ * representing this parse-tree.
+ *
+ * @return string which represents this parse-tree
+ */
+ public String toString() {
+ StringWriter strwriter = new StringWriter();
+ PrintWriter out = new PrintWriter(strwriter);
+ SourceCodeWriter writer = new SourceCodeWriter(out);
+ try {
+ this.accept(writer);
+ } catch (ParseTreeException e) {
+ System.err.println("fail in toString()");
+ }
+ out.close();
+ return strwriter.toString();
+ }
+
+ /**
+ * May return true if two ptree-nodes don't refer to not the
+ * same objects but their contents are equivalent.
+ *
+ * @param p the node
+ * @param q the node to compare
+ * @return true if p equals c
+ */
+ public static final boolean equal(ParseTree p, ParseTree q) {
+ if (p == null && q == null)
+ return true;
+ if (p == null || q == null)
+ return false;
+ if (p == q)
+ return true;
+ return p.equals(q);
+ }
+
+ /**
+ * The object ID is object identifier number in order to determine
+ * two ptree variables refer to the same object.
+ */
+ private int objectID = -1;
+
+ /** The idCount counts up generated ptree objects */
+ private static int idCount = 0;
+
+ public static final int lastObjectID() {
+ return idCount;
+ }
+
+ /**
+ * Increments idCount class variable and set the instance's
+ * object identifier number to the number of idCount variable.
+ *
+ */
+ private synchronized final void setObjectID() {
+ idCount++;
+ objectID = idCount;
+ }
+
+ /**
+ * Returns
+ *
+ * @param id ID
+ * @return Name the ID represents
+ */
+ public final int getObjectID() {
+ return objectID;
+ }
+
+ /**
+ * Generates the string expression from this node. Returned
+ * string doesn't have '"' without cancel ( \" ) and doesn't have
+ * newline.<p>
+ *
+ * This method is useful to embed ptree objects as a string literal
+ * in source code.
+ *
+ * @return the flatten string which this node represents
+ */
+ public String toFlattenString() {
+ StringBuffer ret = null;
+
+ /* cancel double quotes and back slashs */
+ java.util.StringTokenizer canceller =
+ new StringTokenizer(this.toString(), "\\\"", true);
+ ret = new StringBuffer();
+
+ while (canceller.hasMoreTokens()) {
+ String buf = canceller.nextToken();
+ if (buf.equals("\\") || buf.equals("\"")) {
+ ret.append("\\");
+ }
+ ret.append(buf);
+ }
+
+ /* remove new line chars */
+ java.util.StringTokenizer lnremover =
+ new StringTokenizer(ret.toString(), "\n\r", false);
+ ret = new StringBuffer();
+
+ while (lnremover.hasMoreTokens()) {
+ ret.append(" " + lnremover.nextToken());
+ }
+
+ return ret.toString();
+ }
+
+ /**
+ * Accepts a <code>ParseTreeVisitor</code> object as the role of a
+ * Visitor in the Visitor pattern, as the role of an Element in
+ * the Visitor pattern.<p>
+ *
+ * This invoke an appropriate <code>visit()</code> method on the
+ * accepted visitor.
+ *
+ * @param visitor a visitor
+ */
+ public abstract void accept(ParseTreeVisitor visitor)
+ throws ParseTreeException;
+
+ /*
+ public void accept( ParseTreeVisitor visitor ) throws ParseTreeException {
+ Class active_type = this.getClass();
+ Class visitor_clazz = visitor.getClass();
+ try {
+ Method visit_method
+ = visitor_clazz.getMethod( "visit",
+ new Class[]{ active_type } );
+ visit_method.invoke( visitor, new Object[]{ this } );
+ } catch ( Exception e ) {
+ System.err.println( e.toString() );
+ System.err.println( "\telement\t-" + active_type.toString() );
+ System.err.println( "\tvisitor\t-" + visitor_clazz.toString() );
+ }
+ }
+ */
+
+ /**
+ * Accepts a <code>ParseTreeVisitor</code> object as the role of a
+ * Visitor in the Visitor pattern, as the role of an Element in the
+ * Visitor pattern.<p>
+ *
+ * This invoke an appropriate <code>visit()</code> method on each
+ * child <code>ParseTree</code> object with this visitor.
+ *
+ * @param visitor a visitor
+ **/
+ public abstract void childrenAccept(ParseTreeVisitor visitor)
+ throws ParseTreeException;
+
+}