001: package antlr;
002:
003: import antlr.collections.AST;
004: import java.io.IOException;
005: import java.io.ObjectInputStream;
006: import java.io.ObjectOutputStream;
007:
008: public class Utils {
009: private static boolean useSystemExit = true;
010: private static boolean useDirectClassLoading = false;
011: static {
012: if ("true".equalsIgnoreCase(System.getProperty(
013: "ANTLR_DO_NOT_EXIT", "false")))
014: useSystemExit = false;
015: if ("true".equalsIgnoreCase(System.getProperty(
016: "ANTLR_USE_DIRECT_CLASS_LOADING", "false")))
017: useDirectClassLoading = true;
018: }
019:
020: /** Thanks to Max Andersen at JBOSS and Scott Stanchfield */
021: public static Class loadClass(String name)
022: throws ClassNotFoundException {
023: try {
024: ClassLoader contextClassLoader = Thread.currentThread()
025: .getContextClassLoader();
026: if (!useDirectClassLoading && contextClassLoader != null) {
027: return contextClassLoader.loadClass(name);
028: }
029: return Class.forName(name);
030: } catch (Exception e) {
031: return Class.forName(name);
032: }
033: }
034:
035: public static Object createInstanceOf(String name)
036: throws ClassNotFoundException, InstantiationException,
037: IllegalAccessException {
038: return loadClass(name).newInstance();
039: }
040:
041: public static void error(String message) {
042: if (useSystemExit)
043: System.exit(1);
044: throw new RuntimeException("ANTLR Panic: " + message);
045: }
046:
047: public static void error(String message, Throwable t) {
048: if (useSystemExit)
049: System.exit(1);
050: throw new RuntimeException("ANTLR Panic", t);
051: }
052:
053: static public void writeAST(ObjectOutputStream out, AST ast)
054: throws IOException {
055: out.writeObject(ast);
056: if (ast != null) {
057: // the tree structure has a lot of siblings =>
058: // StackOverflow exceptions during serialization of "next" field
059: // we try to prevent it by using own procedure of writing
060: // tree structure
061: writeTree(out, ast);
062: }
063: }
064:
065: // symmetric to writeObject
066: static public AST readAST(ObjectInputStream in) throws IOException,
067: ClassNotFoundException {
068: AST ast = (AST) in.readObject();
069: if (ast != null) {
070: // read tree structure into this node
071: readTree(in, ast);
072: }
073: return ast;
074: }
075:
076: ////////////////////////////////////////////////////////////////////////////
077: // we have StackOverflow when serialize AST due to it's tree structure:
078: // to many recurse calls to writeObject on writing "next" field
079: // let's try to reduce depth of recursion by depth of tree
080:
081: private static final int CHILD = 1;
082: private static final int SIBLING = 2;
083: private static final int END_AST = 3;
084:
085: static private void writeTree(ObjectOutputStream out, AST root)
086: throws IOException {
087: assert (root != null) : "there must be something to write";
088: AST node = root;
089: do {
090: AST child = node.getFirstChild();
091: if (child != null) {
092: // due to not huge depth of the tree
093: // write child without optimization
094: out.writeInt(CHILD);
095: writeAST(out, child);
096: }
097: node = node.getNextSibling();
098: if (node != null) {
099: // we don't want to use recursion on writing sibling
100: // to prevent StackOverflow,
101: // we use while loop for writing siblings
102: out.writeInt(SIBLING);
103: // write node data
104: out.writeObject(node);
105: }
106: } while (node != null);
107: out.writeInt(END_AST);
108: }
109:
110: static private void readTree(ObjectInputStream in, AST root)
111: throws IOException, ClassNotFoundException {
112: assert (root != null) : "there must be something to read";
113: AST node = root;
114: do {
115: int kind = in.readInt();
116: switch (kind) {
117: case END_AST:
118: return;
119: case CHILD:
120: node.setFirstChild(readAST(in));
121: break;
122: case SIBLING:
123: AST sibling = (AST) in.readObject();
124: node.setNextSibling(sibling);
125: node = sibling;
126: break;
127: default:
128: assert (false);
129: }
130: } while (node != null);
131: }
132: }
|