[e-cvs] cvs commit: e/src/jsrc/org/quasiliteral/term Functor.java Term.java Term.updoc TermBuilder.java TermLexer.java TermParser.java term.y

markm@eros.cs.jhu.edu markm@eros.cs.jhu.edu
Sun, 2 Dec 2001 22:30:56 -0500


markm       01/12/02 22:30:56

  Modified:    src/jsrc Makefile
               src/jsrc/org/capml/dom Element.java Node.java Text.java
               src/jsrc/org/capml/quasi XMLQuasiParser.java
               src/jsrc/org/erights/e/elang/syntax ELexer.java EParser.java
                        e.y
               src/jsrc/org/quasiliteral/astro Astro.java AstroSchema.java
                        AstroToken.java BaseSchema.java
               src/jsrc/org/quasiliteral/syntax BaseLexer.java
               src/jsrc/org/quasiliteral/term Functor.java Term.java
                        Term.updoc TermBuilder.java TermLexer.java
                        TermParser.java term.y
  Log:
  Successfully converted a trivial sml dom tree to an AST

Revision  Changes    Path
1.62      +3 -3      e/src/jsrc/Makefile

Index: Makefile
===================================================================
RCS file: /cvs/e/src/jsrc/Makefile,v
retrieving revision 1.61
retrieving revision 1.62
diff -u -r1.61 -r1.62
--- Makefile	2001/12/02 18:42:01	1.61
+++ Makefile	2001/12/03 03:30:54	1.62
@@ -53,7 +53,7 @@
 	find org/quasiliteral/astro  -name '*.java' > files.tmp
 	find org/quasiliteral/syntax -name '*.java' >> files.tmp
 	$(JCOMPILE) @files.tmp
-	# (cd $(TOP)/src/jsrc/org/quasiliteral/term; $(MAKE) all)
+	(cd $(TOP)/src/jsrc/org/quasiliteral/term; $(MAKE) all)
 	(cd $(ER)/elang/syntax; $(MAKE) all)
 
 # space-time-local elang
@@ -61,8 +61,8 @@
 stl_elang:
 	find $(ER)/elang                -name '*.java' > files.tmp
 	find org/capml                  -name '*.java' >> files.tmp
-	# find org/quasiliteral/term      -name '*.java' >> files.tmp
-	# find org/quasiliteral/quasiterm -name '*.java' >> files.tmp
+	find org/quasiliteral/term      -name '*.java' >> files.tmp
+	find org/quasiliteral/quasiterm -name '*.java' >> files.tmp
 	$(JCOMPILE) @files.tmp
 
 # elmer



1.6       +25 -3     e/src/jsrc/org/capml/dom/Element.java

Index: Element.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/capml/dom/Element.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- Element.java	2001/12/02 06:01:41	1.5
+++ Element.java	2001/12/03 03:30:54	1.6
@@ -20,6 +20,9 @@
 import org.erights.e.elib.prim.E;
 import org.erights.e.elib.prim.StaticMaker;
 import org.erights.e.elib.tables.ConstList;
+import org.erights.e.elib.tables.EmptyTwine;
+import org.quasiliteral.astro.AstroBuilder;
+import org.quasiliteral.astro.AstroTag;
 
 import java.io.IOException;
 
@@ -112,8 +115,8 @@
     }
 
     /**
-     * Does 'visitor visit<TagName>(children...)', where the first letter of
-     * tagName is upperCased. <p>
+     * Does 'visitor visit&lt;TagName&gt;(children...)', where the first
+     * letter of tagName is upperCased. <p>
      *
      * For example, if the tag name is "foo", then the visitor will be called
      * as 'visitor visitFoo(children...)'
@@ -144,5 +147,24 @@
         out.println();
         out.print("</", myTagName, ">");
     }
-}
 
+    /**
+     * Currently returns a Node whose functor-leaf is the token-type for this
+     * Element's tag name, and whose arguments are the converted child nodes
+     * in order.
+     *
+     * @return :Node (see {@link AstroBuilder})
+     */
+    public Object build(AstroBuilder builder) {
+        AstroTag tag = builder.getSchema().getTagForName(myTagName);
+        Object func = builder.leafTag(tag.getOptTypeCode(),
+                                      EmptyTwine.THE_ONE);
+        Object args = builder.argList();
+        int len = myChildren.size();
+        for (int i = 0; i < len; i++) {
+            Node child = (Node)myChildren.get(i);
+            args = builder.argList(args, child.build(builder));
+        }
+        return builder.node(func, args);
+    }
+}



1.8       +7 -0      e/src/jsrc/org/capml/dom/Node.java

Index: Node.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/capml/dom/Node.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- Node.java	2001/12/02 06:01:41	1.7
+++ Node.java	2001/12/03 03:30:54	1.8
@@ -23,6 +23,7 @@
 import org.erights.e.elib.tables.ConstList;
 import org.erights.e.elib.tables.Iteratable;
 import org.erights.e.elib.tables.Selfless;
+import org.quasiliteral.astro.AstroBuilder;
 
 import java.io.IOException;
 
@@ -150,5 +151,11 @@
      */
     public abstract void prettyPrintOn(TextWriter out) throws IOException;
 
+    /**
+     * Used to convert from a Node tree to an AST or Term tree.
+     *
+     * @return :Node (see {@link AstroBuilder})
+     */
+    public abstract Object build(AstroBuilder builder);
 }
 



1.6       +13 -0     e/src/jsrc/org/capml/dom/Text.java

Index: Text.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/capml/dom/Text.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- Text.java	2001/12/02 06:01:41	1.5
+++ Text.java	2001/12/03 03:30:54	1.6
@@ -20,6 +20,8 @@
 import org.erights.e.elib.prim.E;
 import org.erights.e.elib.prim.StaticMaker;
 import org.erights.e.elib.tables.ConstList;
+import org.erights.e.elib.tables.EmptyTwine;
+import org.quasiliteral.astro.AstroBuilder;
 
 import java.io.IOException;
 
@@ -145,6 +147,17 @@
     public void prettyPrintOn(TextWriter out) throws IOException {
         //XXX Have to escape things again
         out.print(myData);
+    }
+
+    /**
+     * Returns a node consisting of this literal text (as a leaf) and zero
+     * arguments.
+     *
+     * @return :Node (see {@link AstroBuilder})
+     */
+    public Object build(AstroBuilder builder) {
+        return builder.node(builder.leafData(myData, EmptyTwine.THE_ONE),
+                            builder.argList());
     }
 }
 



1.11      +1 -1      e/src/jsrc/org/capml/quasi/XMLQuasiParser.java

Index: XMLQuasiParser.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/capml/quasi/XMLQuasiParser.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- XMLQuasiParser.java	2001/12/02 06:01:41	1.10
+++ XMLQuasiParser.java	2001/12/03 03:30:54	1.11
@@ -27,7 +27,7 @@
 import org.erights.e.elib.tables.Twine;
 
 /**
- * An StaticMaker on this class is bound to "xml__quasiParser" in the
+ * A StaticMaker on this class is bound to "xml__quasiParser" in the
  * universal namespace, enabling sml`...` expressions in E containing
  * quasi-literal Minimal-XML (which used to be known as SML). <p>
  *



1.70      +50 -19    e/src/jsrc/org/erights/e/elang/syntax/ELexer.java

Index: ELexer.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/syntax/ELexer.java,v
retrieving revision 1.69
retrieving revision 1.70
diff -u -r1.69 -r1.70
--- ELexer.java	2001/12/02 18:42:01	1.69
+++ ELexer.java	2001/12/03 03:30:54	1.70
@@ -26,6 +26,8 @@
 import org.quasiliteral.astro.AstroSchema;
 import org.quasiliteral.astro.AstroToken;
 import org.quasiliteral.astro.AstroTag;
+import org.quasiliteral.astro.AstroBuilder;
+import org.quasiliteral.astro.BaseBuilder;
 import org.quasiliteral.syntax.BaseLexer;
 import org.quasiliteral.syntax.FileFeeder;
 import org.quasiliteral.syntax.LineFeeder;
@@ -47,7 +49,8 @@
     /**
      *
      */
-    static private final String QUASI_ENDER = "$@`";
+    static public final AstroBuilder FOR_ASTS =
+      new BaseBuilder(EParser.DEFAULT_SCHEMA);
 
     /**
      *
@@ -56,7 +59,7 @@
                   boolean partialFlag,
                   boolean noTabsFlag)
       throws IOException {
-        this(input, partialFlag, noTabsFlag, EParser.DEFAULT_SCHEMA);
+        this(input, partialFlag, noTabsFlag, FOR_ASTS);
     }
 
     /**
@@ -65,9 +68,14 @@
     public ELexer(LineFeeder input,
                   boolean partialFlag,
                   boolean noTabsFlag,
-                  AstroSchema schema)
+                  AstroBuilder builder)
       throws IOException {
-        super(input, partialFlag, noTabsFlag, schema);
+        super(input,
+              partialFlag,
+              false, //For E, the quasiFlag is handled instead by wrapping the
+                     //LineFeeder with a QuasiFeeder
+              noTabsFlag,
+              builder);
     }
 
     /**
@@ -89,16 +97,38 @@
     }
 
     /**
-     *
+     * @return :Leaf (see {@link AstroBuilder}
      */
-    protected boolean isContinuer(int tokenType) {
-        return EParser.isContinuer(tokenType);
+    public Object nextToken() throws IOException, SyntaxException {
+        Object result;
+        try {
+            result = getNextToken();
+        } finally {
+            myOptStartPos = -1;
+            myOptStartText = null;
+        }
+        if (EParser.isContinuer(myBuilder.getCodeOfLeaf(result))) {
+            return continuer(result);
+        } else {
+            return result;
+        }
+    }
+
+    /**
+     * Separated out for use by '>'
+     */
+    protected Object continuer(Object result) throws IOException {
+        if (isWhite(myPos, myLData.length)) {
+            myContinueFlag = true;
+            skipLine();
+        }
+        return result;
     }
 
     /**
      *
      */
-    protected AstroToken getNextToken() throws IOException, SyntaxException {
+    protected Object getNextToken() throws IOException, SyntaxException {
         if (myDelayedNextChar) {
             nextChar();
             myDelayedNextChar = false;
@@ -305,7 +335,7 @@
                         }
                         return leafTag(EParser.OpAsl, endToken());
                     } else if (isIdentifierStart((char)myChar)) {
-                        AstroToken optResult = optUri();
+                        Object optResult = optUri();
                         if (null != optResult) {
                             return optResult;
                         }
@@ -327,7 +357,7 @@
                         return leafTag(EParser.OpAsr, endToken());
                     }
                     Twine closer = endToken();
-                    AstroToken result = leafTag('>', closer);
+                    Object result = leafTag('>', closer);
                     if (myIndenter.getCloser() == '>') {
                         myIndenter.pop('>', closer);
                         return result;
@@ -397,8 +427,9 @@
                         myContinueFlag = true;
                         skipLine();
                         stopToken();
-                        AstroToken result = getNextToken();
-                        if (result.getType() == EParser.EOFTOK) {
+                        Object result = getNextToken();
+                        if (myBuilder.getCodeOfLeaf(result) ==
+                          EParser.EOFTOK) {
                             needMore("continued line");
                             return null; //make compiler happy
                         } else {
@@ -551,7 +582,7 @@
      */
     private int optKeywordType(String name) {
         name = name.toLowerCase();
-        AstroTag optTag = mySchema.getOptTagForName(name);
+        AstroTag optTag = myBuilder.getSchema().getOptTagForName(name);
         if (null == optTag) {
             return -1;
         } else {
@@ -562,7 +593,7 @@
     /**
      * Called with myChar as the first character of the identifier.
      */
-    protected AstroToken identifier() throws IOException, SyntaxException {
+    protected Object identifier() throws IOException, SyntaxException {
         do {
             nextChar();
         } while (myChar != EOFCHAR && isIdentifierPart((char)myChar));
@@ -597,7 +628,7 @@
      * source, we need four ttypes rather than the current two: QuasiOpen
      * and QuasiClose.
      */
-    private AstroToken quasiPart() throws IOException, SyntaxException {
+    private Object quasiPart() throws IOException, SyntaxException {
         StringBuffer buf = new StringBuffer();
         while (true) {
             while (QUASI_ENDER.indexOf(myChar) == -1) {
@@ -665,7 +696,7 @@
      * is not immediately followed by a ":", return null and cause no side
      * effects -- in particular, do not effect the current position.
      */
-    private AstroToken optUri() throws IOException, SyntaxException {
+    private Object optUri() throws IOException, SyntaxException {
         int len = myLData.length;
         int pos = myPos + 1;
         while (pos < len && isIdentifierPart(myLData[pos])) {
@@ -732,17 +763,17 @@
         ELexer lex = new ELexer(lr, false, false);
         while (true) {
             try {
-                AstroToken t;
+                Object t;
                 do {
                     t = lex.nextToken();
                     //XXX should print t as a Functor.
                     stdout.println(t);
-                    if (t.getType() == EParser.EOL) {
+                    if (lex.getCodeOfLeaf(t) == EParser.EOL) {
                         stdout.print("stack: ",
                                      lex.myIndenter.toString(),
                                      "\n");
                     }
-                } while (t.getType() != EParser.EOFTOK);
+                } while (lex.getCodeOfLeaf(t) != EParser.EOFTOK);
                 return;
             } catch (SyntaxException sex) {
                 TextWriter err = new TextWriter(PrintStreamWriter.err(),



1.107     +1 -1      e/src/jsrc/org/erights/e/elang/syntax/EParser.java

Index: EParser.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/syntax/EParser.java,v
retrieving revision 1.106
retrieving revision 1.107
diff -u -r1.106 -r1.107
--- EParser.java	2001/12/02 18:42:01	1.106
+++ EParser.java	2001/12/03 03:30:54	1.107
@@ -1310,7 +1310,7 @@
 private int yylex() {
     AstroToken token = null;
     try {
-        token = myLexer.nextToken();
+        token = (AstroToken)myLexer.nextToken();
     } catch (IOException ex) {
         yyerror("io: " + ex);
     }



1.97      +1 -1      e/src/jsrc/org/erights/e/elang/syntax/e.y

Index: e.y
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elang/syntax/e.y,v
retrieving revision 1.96
retrieving revision 1.97
diff -u -r1.96 -r1.97
--- e.y	2001/12/02 18:42:01	1.96
+++ e.y	2001/12/03 03:30:55	1.97
@@ -1357,7 +1357,7 @@
 private int yylex() {
     AstroToken token = null;
     try {
-        token = myLexer.nextToken();
+        token = (AstroToken)myLexer.nextToken();
     } catch (IOException ex) {
         yyerror("io: " + ex);
     }



1.5       +50 -0     e/src/jsrc/org/quasiliteral/astro/Astro.java

Index: Astro.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/astro/Astro.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- Astro.java	2001/12/01 07:52:14	1.4
+++ Astro.java	2001/12/03 03:30:55	1.5
@@ -4,6 +4,7 @@
 import antlr.CommonToken;
 import antlr.Token;
 import antlr.collections.AST;
+import org.erights.e.elib.tables.Twine;
 
 /**
  * AST node implementation which stores tokens explicitly.
@@ -41,6 +42,55 @@
      */
     public Astro(Token optToken) {
         initialize(optToken);
+    }
+
+    /**
+     * Builds an equivalent of this AST using the building methods of
+     * 'builder'.
+     * <p>
+     * Pattern-wise, the schema functions here as both a visitor and as a
+     * factory.
+     *
+     * @return :Node
+     */
+    public Object build(AstroBuilder builder) {
+        Object func = AstroToken.build(myOptToken, builder);
+        Object args = builder.argList();
+        for (Astro optSub = (Astro)getFirstChild();
+             null != optSub;
+             optSub = (Astro)optSub.getNextSibling()) {
+
+            args = builder.argList(args, optSub.build(builder));
+        }
+        return builder.node(func, args);
+    }
+
+    /**
+     * Since not all {@link AST}s are Astros, this static method
+     * provides the equivalent of the build/1 instance method for ASTs in
+     * general.
+     * <p>
+     * In the understanding of non-Astro ASTs used here, their functor is
+     * only according to the AST's type code, for the tag, and the AST's text,
+     * for the source.
+     * <p>
+     * XXX This should probably be made into a sugar-instance-method of AST.
+     */
+    static public Object build(AST self, AstroBuilder builder) {
+        if (self instanceof Astro) {
+            return ((Astro)self).build(builder);
+        } else {
+            Object func = builder.leafTag(self.getType(),
+                                          Twine.fromString(self.getText()));
+            Object args = builder.argList();
+            for (AST optSub = self.getFirstChild();
+                 null != optSub;
+                 optSub = optSub.getNextSibling()) {
+
+                args = builder.argList(args, build(optSub, builder));
+            }
+            return builder.node(func, args);
+        }
     }
 
     /**



1.5       +1 -94     e/src/jsrc/org/quasiliteral/astro/AstroSchema.java

Index: AstroSchema.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/astro/AstroSchema.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- AstroSchema.java	2001/12/02 18:42:02	1.4
+++ AstroSchema.java	2001/12/03 03:30:55	1.5
@@ -2,29 +2,11 @@
 
 import org.erights.e.elib.serial.PassByConstruction;
 import org.erights.e.elib.serial.Persistent;
-import org.erights.e.elib.tables.Twine;
 
 //This file is hereby placed in the public domain
 
 /**
- * Used to describe an Antlr grammar, and to build a tree that could represent
- * the results of parsing such a grammar.
- * <p>
- * Several arguments and return types are 'Object' below because the actual
- * types are to be determined by the implementors of AstroSchem.  However,
- * these choices need to be consistent.  We express the required consistency
- * using pretend parameterized types encoded in the javadoc comments.
- * Concrete subclasses of AstroSchema should say what concrete types they use
- * for these parameterized types.
- * <p>
- * The pretend parameterized types are: <pre>
- *     Leaf -- Leaves of the tree, representing tokens of the grammar.
- *     Node -- Lnternal nodes of the tree, looks like application of a Leaf
- *             as an functor to Args.
- *     Arg -- An individual argument in a list of arguments.  Typically the
- *            same as Node, but not always.  See QuasiTermSchema.
- *     Args -- Represents a list of Arg.
- * </pre>
+ * Used to describe an Antlr grammar.
  *
  * @author <a href="mailto:markm@caplet.com">Mark Miller</a>
  */
@@ -93,79 +75,4 @@
      * if data is the wrong kind.
      */
     AstroTag getLiteralDataTag(Object data);
-
-    /**
-     * Makes a Leaf (eg, a Token or Functor) not representing literal data,
-     * but just a type code
-     *
-     * @return :Leaf
-     */
-    Object leafTag(int typeCode, Twine source);
-
-    /**
-     * Makes a leaf (eg, a Token or Functor) representing literal data
-     *
-     * @return :Leaf
-     */
-    Object leafData(Object data, Twine source);
-
-    /**
-     * Makes a Leaf or Node representing the given type code as parameterized
-     * by the given data.
-     * <p>
-     * Exists to support legacy usage of Antlr Tokens, and in order to allow
-     * lexers, which wish to emit composites, to still emit only leaves if
-     * allowed by the Schema.
-     * <p>
-     * Schema that don't allow composite leaves (like TermSchema) should
-     * instead emit the equivalent of <pre>
-     *     node(leafTag(typeCode, src),
-     *          argList(node(leafData(data, src), argList())))
-     * </pre>
-     *
-     * @return :(Leaf | Node)
-     */
-    Object composite(int typeCode, Object data, Twine source);
-
-    /**
-     * Names an internal node (eg, an AST or Term), for which 'func' is the
-     * "label" and 'args' are the arguments.
-     * <p>
-     * May be destructive of 'args'
-     *
-     * @param func :Leaf
-     * @param args :Args
-     * @return :Node
-     */
-    Object node(Object func, Object args);
-
-    /**
-     * The empty args list
-     *
-     * @return :Args
-     */
-    Object argList();
-
-    /**
-     * The args list of one element.
-     * <p>
-     * May be destructive of that element, as when it's an AST.
-     * <p>
-     * Should be equivalent to 'argList(argList(), first)'
-     *
-     * @param first :Arg
-     * @return :Args
-     */
-    Object argList(Object first);
-
-    /**
-     * Extend args list with an additional term, like a backwards cons.
-     * <p>
-     * May be destructive of 'list' and 'next'
-     *
-     * @param list :Args
-     * @param next :Arg
-     * @return :Args
-     */
-    Object argList(Object list, Object next);
 }



1.9       +57 -0     e/src/jsrc/org/quasiliteral/astro/AstroToken.java

Index: AstroToken.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/astro/AstroToken.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- AstroToken.java	2001/12/02 06:01:50	1.8
+++ AstroToken.java	2001/12/03 03:30:55	1.9
@@ -65,6 +65,63 @@
     }
 
     /**
+     * Builds an equivalent of this token using the building methods of
+     * 'builder'.
+     * <p>
+     * Pattern-wise, the builder functions here as both a visitor and as a
+     * factory.
+     *
+     * @return :(Leaf | Node), because a composite token will build using
+     *         {@link AstroBuilder#composite(int, Object, Twine)}
+     */
+    public Object build(AstroBuilder builder) {
+        int code;
+        AstroSchema schema = builder.getSchema();
+        if (null == myOptTag) {
+            code = getType();
+        } else {
+            //this case should be sped up to avoid the hash lookup in the
+            //typical case.
+            String name = myOptTag.getTypeName().bare();
+            code = schema.getTagForName(name).getOptTypeCode();
+        }
+        if (null == myOptData) {
+            return builder.leafTag(code, myOptSource);
+        } else if (schema.getOptDataTag(myOptData).getOptTypeCode() == code) {
+            return builder.leafData(myOptData, myOptSource);
+        } else {
+            return builder.composite(code, myOptData, myOptSource);
+        }
+    }
+
+    /**
+     * Since not all {@link Token}s are AstroTokens, this static method
+     * provides the equivalent of the build/1 instance method for Tokens in
+     * general.
+     * <p>
+     * In the understanding of non-Astro Tokens used here, they are considered
+     * to have no data.
+     * <p>
+     * XXX This should probably be made into a sugar-instance-method of Token.
+     *
+     * @return :(Leaf | Node)
+     */
+    static public Object build(Token self, AstroBuilder builder) {
+        if (self instanceof AstroToken) {
+            return ((AstroToken)self).build(builder);
+        } else {
+            SourceSpan span = new SourceSpan("<unknown>",
+                                             false,
+                                             self.getLine(),
+                                             self.getColumn(),
+                                             self.getLine(),
+                                             self.getColumn());
+            return builder.leafTag(self.getType(),
+                                   Twine.fromString(self.getText(), span));
+        }
+    }
+
+    /**
      *
      */
     public AstroTag getOptTag() {



1.5       +1 -95     e/src/jsrc/org/quasiliteral/astro/BaseSchema.java

Index: BaseSchema.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/astro/BaseSchema.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- BaseSchema.java	2001/12/02 18:42:02	1.4
+++ BaseSchema.java	2001/12/03 03:30:55	1.5
@@ -13,15 +13,7 @@
 
 /**
  * The default implementation (and default superclass) for implementing
- * AstroSchema simply, starting with an array of type names, and building
- * Astro-trees with AstroToken leaves.
- * <p>
- * The type parameterization of AstroSchema is: <pre>
- *     Leaf is AstroToken
- *     Node is Astro
- *     Arg is Astro
- *     Args is null (for empty list) or Astro (for it and its siblings).
- * </pre>
+ * AstroSchema simply, starting with an array of type names.
  *
  * @author <a href="mailto:markm@caplet.com">Mark Miller</a>
  */
@@ -197,91 +189,5 @@
         AstroTag result = getOptDataTag(data);
         E.require(null != result, "Not a literal type: ", data.getClass());
         return result;
-    }
-
-    /**
-     * @return :AstroToken
-     */
-    public Object leafTag(int typeCode, Twine source) {
-        return new AstroToken(getTagForCode(typeCode), null, source);
-    }
-
-    /**
-     * @param data Must not be null
-     * @param source
-     * @return :AstroToken
-     */
-    public Object leafData(Object data, Twine source) {
-        return new AstroToken(getLiteralDataTag(data), data, source);
-    }
-
-    /**
-     * Returns a complex token rather than a AST.
-     *
-     * @param data Nust not be null
-     * @return :AstroToken
-     */
-    public Object composite(int typeCode, Object data, Twine source) {
-        return new AstroToken(getTagForCode(typeCode), data, source);
-    }
-
-    /**
-     * @param func :AstroToken
-     * @param args :(Astro | null)
-     * @return :Astro
-     */
-    public Object node(Object func, Object args) {
-        AstroToken funcToken = (AstroToken)func;
-        Astro optArgs = (Astro)args;
-        Astro result = new Astro(funcToken);
-        for (; null != optArgs; optArgs = (Astro)optArgs.getNextSibling()) {
-            result.addChild(optArgs);
-        }
-        return result;
-    }
-
-    /**
-     * @return null
-     */
-    public Object argList() {
-        return null;
-    }
-
-    /**
-     * Returns 'first' after severing its nest sibling pointer
-     *
-     * @param first :Astro
-     * @return :Astro
-     */
-    public Object argList(Object first) {
-        Astro result = (Astro)first;
-        result.setNextSibling(null);
-        return result;
-    }
-
-    /**
-     * Modifies the last sibling in 'list' to be 'next', which is modified to
-     * not have any further siblings.
-     *
-     * @param list :(Astro | null)
-     * @param next :Astro
-     * @return :Astro
-     */
-    public Object argList(Object list, Object next) {
-        Astro optList = (Astro)list;
-        Astro nextNode = (Astro)next;
-        nextNode.setNextSibling(null);
-        if (null == optList) {
-            return next;
-        }
-        Astro sib = optList;
-        while (true) {
-            Astro optNextSib = (Astro)sib.getNextSibling();
-            if (null == optNextSib) {
-                sib.setNextSibling(nextNode);
-                return optList;
-            }
-            sib = optNextSib;
-        }
     }
 }



1.2       +51 -45    e/src/jsrc/org/quasiliteral/syntax/BaseLexer.java

Index: BaseLexer.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/syntax/BaseLexer.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- BaseLexer.java	2001/12/02 18:42:02	1.1
+++ BaseLexer.java	2001/12/03 03:30:55	1.2
@@ -1,8 +1,7 @@
 package org.quasiliteral.syntax;
 
 import org.erights.e.elib.tables.Twine;
-import org.quasiliteral.astro.AstroSchema;
-import org.quasiliteral.astro.AstroToken;
+import org.quasiliteral.astro.AstroBuilder;
 
 import java.io.IOException;
 import java.math.BigInteger;
@@ -22,6 +21,11 @@
     /**
      *
      */
+    static protected final String QUASI_ENDER = "$@`";
+
+    /**
+     *
+     */
     static public final int EOFCHAR = -1;
 
     /** contains all lines after the current line */
@@ -65,6 +69,11 @@
     protected boolean myPartialFlag;
 
     /**
+     * Should doubled '@', '$' and '`' in literals be collapsed to singles?
+     */
+    protected boolean myQuasiFlag;
+
+    /**
      * Should tabs be rejected as valid whitespace?
      */
     protected boolean myNoTabsFlag;
@@ -82,15 +91,16 @@
     /**
      *
      */
-    protected AstroSchema mySchema;
+    protected AstroBuilder myBuilder;
 
     /**
      *
      */
     public BaseLexer(LineFeeder input,
                      boolean partialFlag,
+                     boolean quasiFlag,
                      boolean noTabsFlag,
-                     AstroSchema schema)
+                     AstroBuilder builder)
       throws IOException {
 
         myInput = input;
@@ -103,10 +113,11 @@
             myLData = myLTwine.bare().toCharArray();
         }
         nextChar();
+        myQuasiFlag = quasiFlag;
         myNoTabsFlag = noTabsFlag;
         myIndenter = new Indenter();
         myContinueFlag = false;
-        mySchema = schema;
+        myBuilder = builder;
     }
 
     /**
@@ -214,40 +225,18 @@
     }
 
     /**
-     *
+     * @return :Leaf (see {@link AstroBuilder}
      */
-    protected abstract boolean isContinuer(int tokenType);
-
-    /**
-     *
-     */
-    public AstroToken nextToken() throws IOException, SyntaxException {
-        AstroToken result;
+    public Object nextToken() throws IOException, SyntaxException {
         try {
-            result = getNextToken();
+            return getNextToken();
         } finally {
             myOptStartPos = -1;
             myOptStartText = null;
         }
-        if (isContinuer(result.getType())) {
-            return continuer(result);
-        } else {
-            return result;
-        }
     }
 
     /**
-     * Separated out for use by '>'
-     */
-    protected AstroToken continuer(AstroToken result) throws IOException {
-        if (isWhite(myPos, myLData.length)) {
-            myContinueFlag = true;
-            skipLine();
-        }
-        return result;
-    }
-
-    /**
      * Throws a {@link SyntaxException} that also captures the current line
      * and position as the position of the error.
      */
@@ -364,36 +353,43 @@
     }
 
     /**
+     * Just forwards to myBuilder
+     */
+    public int getCodeOfLeaf(Object leaf) {
+        return myBuilder.getCodeOfLeaf(leaf);
+    }
+
+    /**
      *
      */
-    protected AstroToken leafTag(int typeCode, Twine source) {
-        return (AstroToken)mySchema.leafTag(typeCode, source);
+    protected Object leafTag(int typeCode, Twine source) {
+        return myBuilder.leafTag(typeCode, source);
     }
 
     /**
      *
      */
-    protected AstroToken leafData(Object data, Twine source) {
-        return (AstroToken)mySchema.leafData(data, source);
+    protected Object leafData(Object data, Twine source) {
+        return myBuilder.leafData(data, source);
     }
 
     /**
      *
      */
-    protected AstroToken composite(int typeCode, Object data, Twine source) {
-        return (AstroToken)mySchema.composite(typeCode, data, source);
+    protected Object composite(int typeCode, Object data, Twine source) {
+        return myBuilder.composite(typeCode, data, source);
     }
 
     /**
      *
      */
-    protected abstract AstroToken getNextToken()
+    protected abstract Object getNextToken()
       throws IOException, SyntaxException;
 
     /**
      *
      */
-    protected AstroToken openBracket(char closer) throws IOException {
+    protected Object openBracket(char closer) throws IOException {
         int tokenType = myChar;
         nextChar();
         Twine openner = endToken();
@@ -403,9 +399,9 @@
     /**
      *
      */
-    protected AstroToken openBracket(int tokenType,
-                                     Twine openner,
-                                     char closer)
+    protected Object openBracket(int tokenType,
+                                 Twine openner,
+                                 char closer)
       throws IOException {
         if (isWhite(myPos, myLData.length)) {
             myIndenter.nest(openner, closer);
@@ -419,7 +415,7 @@
     /**
      *
      */
-    protected AstroToken closeBracket() throws IOException {
+    protected Object closeBracket() throws IOException {
         char closerChar = (char)myChar;
         nextChar();
         Twine closer = endToken();
@@ -435,6 +431,8 @@
     protected char charConstant() throws IOException, SyntaxException {
         if (myChar == '\\') {
             nextChar();
+            //Since all the non-error cases below don't involve any
+            //quasi-enders, we can ignore myQuasiFlag during the switch.
             switch (myChar) {
                 case 'b':
                     return '\b';
@@ -480,6 +478,14 @@
             }
         } else if (myChar == EOFCHAR) {
             syntaxError("End of file in middle of literal");
+        } else if (myQuasiFlag && QUASI_ENDER.indexOf(myChar) != -1) {
+            char c = (char)myChar;
+            nextChar();
+            if (c != (char)myChar) {
+                syntaxError("When quasi-parsing, '" +
+                            c + "' must be doubled");
+            }
+            return c;
         } else {
             return (char)myChar;
         }
@@ -489,7 +495,7 @@
     /**
      *
      */
-    protected AstroToken charLiteral() throws IOException, SyntaxException {
+    protected Object charLiteral() throws IOException, SyntaxException {
         nextChar();
         char value = charConstant();
         nextChar();
@@ -552,7 +558,7 @@
     /**
      *
      */
-    protected AstroToken numberLiteral()
+    protected Object numberLiteral()
       throws IOException, SyntaxException {
         // Now handles floating point numbers as well as integers
         boolean floating = false;
@@ -694,7 +700,7 @@
     /**
      *
      */
-    protected AstroToken stringLiteral() throws IOException, SyntaxException {
+    protected Object stringLiteral() throws IOException, SyntaxException {
         nextChar();
         Twine openner = (Twine)myLTwine.run(myOptStartPos, myPos);
         myIndenter.push(openner, '"', 0);



1.13      +40 -162   e/src/jsrc/org/quasiliteral/term/Functor.java

Index: Functor.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/term/Functor.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- Functor.java	2001/12/01 03:44:02	1.12
+++ Functor.java	2001/12/03 03:30:56	1.13
@@ -1,48 +1,18 @@
 package org.quasiliteral.term;
 
-import antlr.Token;
-import org.erights.e.develop.format.StringHelper;
-import org.erights.e.elib.base.SourceSpan;
-import org.erights.e.elib.base.ClassDesc;
-import org.erights.e.elib.prim.E;
 import org.erights.e.elib.prim.StaticMaker;
 import org.erights.e.elib.serial.PassByConstruction;
 import org.erights.e.elib.serial.Persistent;
-import org.erights.e.elib.tables.ConstList;
-import org.erights.e.elib.tables.ConstMap;
 import org.erights.e.elib.tables.Selfless;
 import org.erights.e.elib.tables.Twine;
-import org.erights.e.elib.tables.EmptyTwine;
-import org.erights.e.elib.ref.Ref;
-import org.quasiliteral.astro.AstroToken;
+import org.quasiliteral.astro.AstroBuilder;
 import org.quasiliteral.astro.AstroTag;
-import org.quasiliteral.astro.AstroSchema;
-import org.quasiliteral.astro.TreeBuilder;
 
-import java.math.BigInteger;
+//This file is hereby placed in the public domain
 
 /**
- * Like an Antlr {@link Token}, but with differences that make it suitable
- * for quasiliteral processing.
- * <p>
- * The differences are
- * <ul>
- * <li>It knows how to convert to and from an Antlr Token, in a way that
- *     preserves the semantics of vanilla Tokens.
- * <li>It's PassByCopy, necessitating it be Immutable.</li>
- * <li>The token-type is identified by a string instead of a number,
- *     enabling it to make sense wrt a source grammar instead of a compiled
- *     grammar.</li>
- * <li>The token-text is a {@link Twine} instead of a string, and can
- *     therefore remember its source positions.</li>
- * <li>The semantically significant value is separate from the source
- *     text.</li>
- * <li>It has a convenient printed form.</li>
- * </ul>
  *
- * @author <a href="mailto:markm@caplet.com">Mark S Miller</a>
- * @author Many ideas from Danfuzz Bornstein
- * @author Many thanks also to Dean Tribble
+ * @author <a href="mailto:markm@caplet.com">Mark Miller</a>
  */
 public class Functor
   implements Selfless, PassByConstruction, Persistent {
@@ -50,175 +20,83 @@
     /**
      *
      */
-    public static StaticMaker FunctorMaker = StaticMaker.make(Functor.class);
+    static public final StaticMaker FunctorMaker =
+      StaticMaker.make(Functor.class);
 
     /**
-     * @serial The name of an Antlr token type int in a particular grammar.
+     * @serial Represents the token-type of the functor.
      */
     private final AstroTag myTag;
 
     /**
-     * @serial The source text corresponding to the original source of the
-     *         token.
+     * @serial If the functor represents a literal-data token, then this is
+     * the data, and myTag must represent the cononical corresponding
+     * token-type for this kind of data in this schema.
      */
-    private final Twine mySource;
+    private final Object myOptData;
 
     /**
-     * @serial null, {@link Character}, {@link BigInteger}, {@link Double},
-     * or {@link Twine}, presumably calculated from lexing the token
+     * @serial What source text was originally lexed or parsed to produce
+     *         this token?
      */
-    private final Object myOptData;
+    private final Twine mySource;
 
     /**
-     * Makes a Functor that represents a Token of some grammar.
-     *
-     * @param tag Represents a token type in a particular grammar.
-     * @param source The source text corresponding to the original source of
-     *               the token, although it isn't necessarily the same as the
-     *               original source text.  In any case, its source span
-     *               information says what positions in the original source
-     *               it corresponds to. This is not part of the normal
-     *               printed form.
-     * @param optData null,
-     *                or a {@link Character},
-     *                or a {@link BigInteger},
-     *                or a {@link Double},
-     *                or a {@link Twine}
-     *                If non-null, the data as a literal is the printed form.
+     * @param tag Represents the token-type of the functor.
+     * @param optData Either literal data or null.  If not null, then the tag
+     *                must represent the canonical literal type for this
+     *                kind of data in this schema.
+     * @param source What source text was originally lexed or parsed to
+     *               produce this token?
      */
-    public Functor(AstroTag tag, Twine source, Object optData) {
+    public Functor(AstroTag tag, Object optData, Twine source) {
         myTag = tag;
-        mySource = source;
         myOptData = optData;
-        if (null != optData) {
-            E.require(Ref.same(tag.getOptSchema().getOptLiteralDataTag(optData),
-                               tag));
-        }
-    }
-
-    /**
-     * Converts to an equivalent {@link AstroToken}, for use with Antlr.
-     * <p>
-     * This should be compatible with Antlr code that just assumes a Token.
-     */
-    public Token asToken(ConstMap typeNums) {
-        return myTag.getOptSchema().tokenFromFunctor(this);
-    }
-
-    /**
-     * Call the builder's productions in order to represent this Functor.
-     * <p>
-     * This is a kind of visitor pattern.  If the builder provided is the
-     * SimpleTermBuilder, this should make a semantically equivalent copy
-     * of this Functor.
-     */
-    public Object build(TreeBuilder builder) {
-//        if (null == myOptData) {
-//            return builder.functor(new AstroToken(TermParser.ID,
-//                                                  mySource,
-//                                                  myTag),
-//                                   null);
-//        } else if (isLiteral()) {
-//            return builder.functor(null,
-//                                   new AstroToken(myValueType,
-//                                                  mySource,
-//                                                  myOptData));
-//        } else {
-//            return builder.functor(new AstroToken(TermParser.ID,
-//                                                  EmptyTwine.THE_ONE,
-//                                                  myTag),
-//                                   new AstroToken(myValueType,
-//                                                  mySource,
-//                                                  myOptData));
-//        }
-        throw new RuntimeException("XXX not yet implemented");
+        mySource = source;
     }
 
     /**
-     * 'FunctorMaker new(myTag, mySource, myValue)'
+     * Uses 'FunctorMaker new(myTag, myOptData, mySource)'
      */
     public Object[] getCanonicalState() {
         Object[] result = {
-            FunctorMaker, "new", myTag, mySource, myOptData
+            FunctorMaker, "new", myTag, myOptData, mySource
         };
         return result;
     }
 
-    /**
-     * An identifier typically representing a type of AST node.
-     */
-    public AstroTag getTag() {
-        return myTag;
-    }
-
     /**
-     *
+     * @return :Leaf
      */
-    public AstroSchema getSchema() {
-        return myTag.getOptSchema();
+    public Object build(AstroBuilder builder) {
+        if (null == myOptData) {
+            return builder.leafTag(myTag.getOptTypeCode(), mySource);
+        } else {
+            //Assumes tag adds no more info.
+            return builder.leafData(myOptData, mySource);
+        }
     }
 
     /**
-     * Presumably, some of the source text that produced this Functor.
-     * <p>
-     * Only the source-position-tracking info is really significant here.
-     * If absent, the absence is indicated with an empty string rather than
-     * null.
+     * Represents the token-type of the functor.
      */
-    public Twine getSource() {
-        return mySource;
+    public AstroTag getTag() {
+        return myTag;
     }
 
     /**
-     * null, or the actual literal data in canonical form.
-     * <p>
-     * For example, if the Functor was made using an Integer, getOptData()
-     * will return a corresponding BigInteger.
+     * If the functor represents a literal-data token, then this is
+     * the data, and myTag must represent the cononical corresponding
+     * token-type for this kind of data in this schema.
      */
     public Object getOptData() {
         return myOptData;
     }
 
     /**
-     * If this token represents literal data, return that data,
-     * else throw an exception.
+     * What source text was originally lexed or parsed to produce this token?
      */
-    public Object getData() {
-        E.require(null != myOptData, "No data: ", this);
-        return myOptData;
-    }
-
-    /**
-     *
-     */
-    public double compareTo(Functor other) {
-        double result = myTag.compareTo(other.myTag);
-        if (0.0 != result) {
-            return result;
-        }
-        return E.asFloat64(E.call(myOptData, "compareTo", other.myOptData));
-    }
-
-    /**
-     * quasiFlag defaults to false
-     */
-    public String toString() {
-        return toString(false);
-    }
-
-    /**
-     *
-     */
-    public String toString(boolean quasiFlag) {
-        if (null == myOptData) {
-            return myTag.getTypeName().bare();
-        }
-        String result = E.toQuote(myOptData).bare();
-        if (quasiFlag) {
-            result = StringHelper.replaceAll(result, "$", "$$");
-            result = StringHelper.replaceAll(result, "@", "@@");
-            result = StringHelper.replaceAll(result, "`", "``");
-        }
-        return result;
+    public Twine getSource() {
+        return mySource;
     }
 }



1.9       +22 -169   e/src/jsrc/org/quasiliteral/term/Term.java

Index: Term.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/term/Term.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- Term.java	2001/12/01 03:44:02	1.8
+++ Term.java	2001/12/03 03:30:56	1.9
@@ -1,41 +1,17 @@
 package org.quasiliteral.term;
 
-import antlr.CommonToken;
-import antlr.Token;
-import antlr.collections.AST;
-import org.erights.e.develop.format.StringHelper;
-import org.erights.e.elib.eio.TextWriter;
-import org.erights.e.elib.prim.E;
 import org.erights.e.elib.prim.StaticMaker;
 import org.erights.e.elib.serial.PassByConstruction;
 import org.erights.e.elib.serial.Persistent;
 import org.erights.e.elib.tables.ConstList;
-import org.erights.e.elib.tables.ConstMap;
-import org.erights.e.elib.tables.FlexList;
 import org.erights.e.elib.tables.Selfless;
-import org.quasiliteral.astro.Astro;
-import org.quasiliteral.astro.TreeBuilder;
+import org.quasiliteral.astro.AstroBuilder;
 
-import java.io.IOException;
+//This file is hereby placed in the public domain
 
 /**
- * Like an Antlr {@link AST}, but with differences that make it suitable for
- * quasiliteral processing.
- * <p>
- * The differences are:<ul>
- * <li>It knows how to convert to and from an Antlr AST, in a way that
- *     preserves the semantics of vanilla ASTs.
- * <li>It's PassByCopy, necessitating it be Immutable.</li>
- * <li>Each Term only points downward, not rightward, making them
- *     sharable by different containing contexts.</li>
- * <li>The functor is a {@link Functor}, which is likewise like an Antlr
- *     {@link Token}, rather than just storing a String and an int.</li>
- * <li>It has a more conventional printed form, like a prolog term tree.</li>
- * </ul>
  *
- * @author <a href="mailto:markm@caplet.com">Mark S Miller</a>
- * @author Many ideas from Danfuzz Bornstein
- * @author Many thanks also to Dean Tribble
+ * @author <a href="mailto:markm@caplet.com">Mark Miller</a>
  */
 public class Term
   implements Selfless, PassByConstruction, Persistent {
@@ -46,92 +22,46 @@
     static public final StaticMaker TermMaker =
       StaticMaker.make(Term.class);
 
-    /** @serial Tags this Term to explain its meaning. */
+    /**
+     *
+     */
     private final Functor myFunctor;
 
-    /** @serial A list of Terms */
-    private final ConstList myArgs;
-
     /**
-     * Just used to decide how to pretty print.
-     * <p>
-     * Initialized lazily.  0 if uninitialized, so does not need to be
-     * recalculated on revival.
+     *
      */
-    private transient int myHeight = 0;
+    private final ConstList myArgs;
 
     /**
-     * @param functor "explains" what kind of node this Term is, and how
-     *                to interpret the args.
-     * @param args A list of the children Terms.
+     *
      */
     public Term(Functor functor, ConstList args) {
         myFunctor = functor;
         myArgs = args;
-        E.require(null != functor);
-        E.require(null != args);
-    }
-
-    /**
-     * Converts an Antlr AST to a Term tree, while preserving all the vanilla
-     * AST semantics.
-     */
-    static public Term fromAST(AST ast,
-                               String url,
-                               ConstList typeNames) {
-        Token optToken = null;
-        if (ast instanceof Astro) {
-            optToken = ((Astro)ast).getOptToken();
-        }
-        if (null == optToken) {
-            optToken = new CommonToken(ast.getType(), ast.getText());
-        }
-        FlexList args = FlexList.fromType(Term.class);
-        for (AST arg = ast.getFirstChild();
-             null != arg;
-             arg = arg.getNextSibling())
-        {
-            args.push(Term.fromAST(arg, url, typeNames));
-        }
-        return new Term(Functor.fromToken(optToken, url, typeNames),
-                        args.snapshot());
     }
 
     /**
-     * Convert this Term tree to an equivalent Antlr AST representation.
+     * Uses 'TermMaker new(myFunctor, myArgs)'
      */
-    public Astro asAST(ConstMap typeNums) {
-        Token token = myFunctor.asToken(typeNums);
-        Astro result = new Astro(token);
-        for (int i = 0; i < myArgs.size(); i++) {
-            result.addChild(((Term)myArgs.get(i)).asAST(typeNums));
-        }
+    public Object[] getCanonicalState() {
+        Object[] result = {
+            TermMaker, "new", myFunctor, myArgs
+        };
         return result;
     }
 
     /**
-     * Like a visitor pattern, where 'builder' is the visitor.
-     * <p>
-     * When built using the SimpleTermBuilder, the result should be
-     * a semantically equivalent copy except for source tracking.
-     */
-    public Object build(TreeBuilder builder) {
-        Object builtFunctor = myFunctor.build(builder);
-        Object builtArgs = builder.argList();
+     * @return :Node
+     */
+    public Object build(AstroBuilder builder) {
+        Object func = myFunctor.build(builder);
+        Object args = builder.argList();
         int len = myArgs.size();
         for (int i = 0; i < len; i++) {
-            Term arg = (Term)myArgs.get(i);
-            builtArgs = builder.argList(builtArgs, arg.build(builder));
+            Object arg = ((Term)myArgs.get(i)).build(builder);
+            args = builder.argList(args, arg);
         }
-        return builder.term(builtFunctor, builtArgs);
-    }
-
-    /**
-     *
-     */
-    public Object[] getCanonicalState() {
-        Object[] result = { TermMaker, "new", myFunctor, myArgs };
-        return result;
+        return builder.node(func, args);
     }
 
     /**
@@ -146,82 +76,5 @@
      */
     public ConstList getArgs() {
         return myArgs;
-    }
-
-    /**
-     *
-     */
-    public double compareTo(Term other) {
-        double result = myFunctor.compareTo(other.myFunctor);
-        if (0.0 != result) {
-            return result;
-        }
-        return myArgs.compareTo(other.myArgs);
-    }
-
-    /**
-     * What's the longest distance to the bottom?
-     * <p>
-     * A leaf node is height 1.  All other nodes are one more than the height
-     * of their highest child.  This is used for pretty printing.
-     */
-    public int getHeight() {
-        if (myHeight <= 0) {
-            myHeight = 1;
-            for (int i = 0; i < myArgs.size(); i++) {
-                int h = ((Term)myArgs.get(i)).getHeight();
-                myHeight = Math.max(myHeight, h + 1);
-            }
-        }
-        return myHeight;
-    }
-
-    /**
-     *
-     */
-    public void printOn(TextWriter out) throws IOException {
-        out.print("term`");
-        prettyPrintOn(out.indent("     "), true);
-        out.print("`");
-    }
-
-    /**
-     *
-     */
-    public void prettyPrintOn(TextWriter out, boolean quasiFlag)
-      throws IOException {
-        String functorStr = myFunctor.toString(quasiFlag);
-        out.print(functorStr);
-        int h = getHeight();
-        if (h <= 1) {
-            if (myArgs.size() != 0) {
-                throw new RuntimeException("internal: bad height " + h);
-            }
-            //If it's a leaf, don't show parens either
-            return;
-        }
-        if (h == 2) {
-            //If it only contains leaves, do it on one line
-            out.print("(");
-            ((Term)myArgs.get(0)).prettyPrintOn(out, quasiFlag);
-            for (int i = 1; i < myArgs.size(); i++) {
-                out.print(", ");
-                ((Term)myArgs.get(i)).prettyPrintOn(out, quasiFlag);
-            }
-            out.print(")");
-            return;
-        }
-        //print each child lined up.
-        out.print("(");
-        int reps = functorStr.length() + 1;
-        String spaces = StringHelper.multiply(" ", reps);
-        TextWriter sub = out.indent(spaces);
-
-        ((Term)myArgs.get(0)).prettyPrintOn(sub, quasiFlag);
-        for (int i = 1; i < myArgs.size(); i++) {
-            sub.println(",");
-            ((Term)myArgs.get(i)).prettyPrintOn(sub, quasiFlag);
-        }
-        sub.print(")");
     }
 }



1.12      +47 -1     e/src/jsrc/org/quasiliteral/term/Term.updoc

Index: Term.updoc
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/term/Term.updoc,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- Term.updoc	2001/12/01 07:52:14	1.11
+++ Term.updoc	2001/12/03 03:30:56	1.12
@@ -1,8 +1,54 @@
     ? 2 + 3
     # value: 5
     
+    ? def dom := sml`<tag>text</tag>`
+    # value: sml`<tag>
+    #                text
+    #            </tag>`
+    
+    ? def qq__uriGetter := <unsafe:org.quasiliteral.*>
+    # value: <unsafe:org.quasiliteral.*>
+    
+    ? def miniSchema := <qq:astro.BaseSchema> new(["tag", "foo", "LiteralString"])
+    # value: org.quasiliteral.astro.BaseSchema@127cb58
+    
+    ? def miniBuilder := <qq:astro.BaseBuilder> new(miniSchema)
+    # value: org.quasiliteral.astro.BaseBuilder@127df6a
+    
+    ? def ast := dom build(miniBuilder)
+    # value: 
+    
+    ? ast getType()
+    # value: 0
+    
+    ? ast getText()
+    # value: ""
+    
+    ? def token := ast getOptToken()
+    # value: ["",<0>]
+    
+    ? def tag := token getOptTag()
+    # value: org.quasiliteral.astro.AstroTag@127cae3
+    
+    ? tag getTypeName()
+    # value: "tag"
+    
+    ? ast getNextSibling()
+    ? def c1 := ast getFirstChild()
+    # value: 
+    
+    ? c1 getType()
+    # value: 2
+    
+    ? def tok1 := c1 getOptToken()
+    # value: ["",<2>]
+    
+    ? tok1 getOptData()
+    # value: "text"
+    
     ? 
-
+    ? 
+    ? 
     ? def t1 := term`"foo"`
     # value: term`"foo"`
     



1.9       +106 -83   e/src/jsrc/org/quasiliteral/term/TermBuilder.java

Index: TermBuilder.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/term/TermBuilder.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- TermBuilder.java	2001/12/01 03:44:02	1.8
+++ TermBuilder.java	2001/12/03 03:30:56	1.9
@@ -1,111 +1,134 @@
 package org.quasiliteral.term;
 
+import org.erights.e.elib.prim.E;
+import org.erights.e.elib.tables.ConstList;
+import org.erights.e.elib.tables.Twine;
+import org.quasiliteral.astro.AstroBuilder;
+import org.quasiliteral.astro.AstroSchema;
+import org.quasiliteral.astro.BaseBuilder;
 
-import org.quasiliteral.astro.AstroToken;
-import org.quasiliteral.astro.TreeBuilder;
+//This file is hereby placed in the public domain
 
 /**
- * Used by the actions of term.y / TermParser.
+ * Builds Term/Functor trees.
  * <p>
- * XXX TreeBuilder, TermParser, term.y, and TermLexer are all to be replaced
- * with Antlr-based equivalents.  We hope that the abstraction provided by
- * TreeBuilder may allow it, its subclasses, and its clients to survive this
- * transition without great change.
- * <p>
- * The arguments and return types are all 'Object' below, because the actual
- * types are to be determined by the subclasses.  However, these choices
- * need to be consistent.  We express the required consistency using pretend
- * parameterized types encoded in the javadoc comments.  The types tags are
- * based on the productions in term.y.  Concrete subclasses should say what
- * concrete types they use for these parameterized types.
- * <p>
- * The pretend parameterized types, approximately bottom to top, are:<ul>
- * <li>PLitHole -- as returned by dollarHole/1 and atHole/1.</li>
- * <li>PFunctorHole -- as returned by functorHole/1.</li>
- * <li>PTermHole -- as returned by termHole/2.</li>
- * <li>PArgHole -- as returned by argHole/2.</li>
- * </ul>
- * <ul>
- * <li>{@link AstroToken} -- the actual concrete token type.</li>
- * <li>PLit -- AstroToken(Literal*).<.li>
- * <li>PFunctor -- a PFunctorHole or as returned by functor/2.</li>
- * <li>PTerm -- as returned by term/2 or termHole/2.</li>
- * <li>PArg -- a PTerm or PArgHole.</li>
- * <li>PArgs -- a list of PArgs, as returned by argList/0, argList/1,
- *     or argList/2.</li>
- * </ul>
+ * The type parameters of AstroBuilder are bound as follows:<pre>
+ *     Leaf -- {@link Functor}
+ *     Node -- {@link Term}
+ *     Arg -- {@link Term}
+ *     Args -- a {@link ConstList} of Term
+ * </pre>
  *
- * @author <a href="mailto:markm@caplet.com">Mark S Miller</a>
+ * @author <a href="mailto:markm@caplet.com">Mark Miller</a>
  */
-public interface TermBuilder extends TreeBuilder {
+public class TermBuilder implements AstroBuilder {
 
     /**
-     * If true, then this builder accepts the hole productions, and the
-     * corresponding lexer should collapse doubled '$', '@', and '`' into
-     * single ones, and should also reject single ones that appear in
-     * uninterpreted contexts.
-     * <p>
-     * If false, then all the hole productions should throw, and
-     * uninterpreted '$', '@', '`' characters should be left alone.
+     * Builds Term trees according to the term.y grammar
      */
-    boolean doesQuasis();
+    static public final TermBuilder FOR_TERMS =
+      new TermBuilder(TermParser.DEFAULT_SCHEMA);
 
     /**
-     * Promotes a functor-hole to a term-hole.
-     * <p>
-     * If the optIdent is provided, then it constrains the hole to only match
-     * Terms whose functor has that tag.
      *
-     * @param optIdent :(AstroToken(ID) | null)
-     * @param functorHole :PFunctorHole
-     * @return :PTermHole
-     */
-    Object termHole(AstroToken optIdent, Object functorHole);
-
-    /**
-     * Promotes a term or term-hole to an arg, which represents a sequence of
-     * terms.
-     * <p>
-     * An element of an args list may be an optional term or term-hole
-     * annotated with a quantity indicator: '?', '+', or '*' (with the usual
-     * meanings).
-     * <p>
-     * This should extract the maximal list of matching terms from the
-     * specimen, within the constraints of the quantity indicator and
-     * the term-hole's optional type tag.
-     *
-     * @param optTerm :(PTerm | null)
-     * @param quant :("?" | "+" | "*" | ".")
-     * @return :PArg
      */
-    Object arg(Object optTerm, String quant);
+    private AstroSchema mySchema;
 
     /**
+     * Builds Term trees according to the term.y grammar
+     */
+    static public final BaseBuilder FOR_ASTS =
+      new BaseBuilder(TermParser.DEFAULT_SCHEMA);
+
+    /**
      *
      */
-    Object argGroup(Object args, String quant);
+    public TermBuilder(AstroSchema schema) {
+        mySchema = schema;
+    }
 
     /**
-     * A dollar-hole corresponds to an extracted expression whose value
-     * should be substituted in at runtime.
-     * <p>
-     * As returned by dollarHole, this starts as a functor-hole, but will
-     * often get promoted to another kind of hole.
      *
-     * @param index :AstroToken(LiteralInteger)
-     * @return :PLitHole
+     */
+    public AstroSchema getSchema() {
+        return mySchema;
+    }
+
+    /**
+     * @return :Functor
      */
-    Object dollarHole(AstroToken index);
+    public Object leafTag(int typeCode, Twine source) {
+        return new Functor(mySchema.getTagForCode(typeCode),
+                           null,
+                           source);
+    }
 
     /**
-     * An at-hole corresponds to an extracted pattern to be matched against
-     * the corresponding part of the specimen at runtime.
-     * <p>
-     * As returned by atHole, this starts as a functor-hole, but will
-     * often get promoted to another kind of hole.
+     * @return :Functor
+     */
+    public Object leafData(Object data, Twine source) {
+        return new Functor(mySchema.getOptDataTag(data),
+                           data,
+                           source);
+    }
+
+    /**
+     * Since Term/Functor trees don't allow composite leaves (Functors), this
+     * instead returns a 1-argument Term whose functor represents the type
+     * code, and whose argument represents the data.
      *
-     * @param index :AstroToken(LiteralInteger)
-     * @return :PLitHole
+     * @return :Term
+     */
+    public Object composite(int typeCode, Object data, Twine source) {
+        return node(leafTag(typeCode, source),
+                    argList(leafData(data, source)));
+    }
+
+    /**
+     * @param leaf :Functor
+     */
+    public int getCodeOfLeaf(Object leaf) {
+        Functor functor = (Functor)leaf;
+        return functor.getTag().getOptTypeCode();
+    }
+
+    /**
+     * @param func :(Functor | Term)
+     * @param args :(ConstList of(Term))
+     * @return :Term
+     */
+    public Object node(Object func, Object args) {
+        ConstList argList = (ConstList)E.as(args, ConstList.class);
+        if (func instanceof Term) {
+            E.require(argList.size() == 0,
+                      "Cannot doubly parameterize: ", func);
+            return func;
+        }
+        return new Term(((Functor)func), argList);
+    }
+
+    /**
+     * @return :(ConstList of(Term))
+     */
+    public Object argList() {
+        return ConstList.EmptyList;
+    }
+
+    /**
+     * @param first :Term
+     * @return :(ConstList of(Term))
+     */
+    public Object argList(Object first) {
+        return ConstList.EmptyList.with(first);
+    }
+
+    /**
+     * @param list :(ConstList of(Term))
+     * @param next :Term
+     * @return :(ConstList of(Term))
      */
-    Object atHole(AstroToken index);
+    public Object argList(Object list, Object next) {
+        ConstList argList = (ConstList)E.as(list, ConstList.class);
+        return argList.with(next);
+    }
 }



1.9       +34 -18    e/src/jsrc/org/quasiliteral/term/TermLexer.java

Index: TermLexer.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/term/TermLexer.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- TermLexer.java	2001/12/02 18:42:02	1.8
+++ TermLexer.java	2001/12/03 03:30:56	1.9
@@ -23,9 +23,7 @@
 import org.erights.e.elib.eio.TextWriter;
 import org.erights.e.elib.tables.EmptyTwine;
 import org.erights.e.elib.tables.Twine;
-import org.quasiliteral.astro.AstroSchema;
-import org.quasiliteral.astro.AstroToken;
-import org.quasiliteral.astro.AstroTag;
+import org.quasiliteral.astro.AstroBuilder;
 import org.quasiliteral.syntax.BaseLexer;
 import org.quasiliteral.syntax.FileFeeder;
 import org.quasiliteral.syntax.LineFeeder;
@@ -54,9 +52,14 @@
      */
     public TermLexer(LineFeeder input,
                      boolean partialFlag,
+                     boolean quasiFlag,
                      boolean noTabsFlag)
       throws IOException {
-        this(input, partialFlag, noTabsFlag, TermParser.DEFAULT_SCHEMA);
+        this(input,
+             partialFlag,
+             quasiFlag,
+             noTabsFlag,
+             TermBuilder.FOR_TERMS);
     }
 
     /**
@@ -64,10 +67,15 @@
      */
     public TermLexer(LineFeeder input,
                      boolean partialFlag,
+                     boolean quasiFlag,
                      boolean noTabsFlag,
-                     AstroSchema schema)
+                     AstroBuilder builder)
       throws IOException {
-        super(input, partialFlag, noTabsFlag, schema);
+        super(input,
+              partialFlag,
+              quasiFlag,
+              noTabsFlag,
+              builder);
     }
 
     /**
@@ -78,23 +86,31 @@
      *                   property.
      */
     static public TermLexer make(Twine sourceCode,
+                                 boolean quasiFlag,
                                  boolean noTabsFlag)
       throws IOException {
         LineFeeder lineFeeder = new TwineFeeder(sourceCode);
-        return new TermLexer(lineFeeder, false, noTabsFlag);
+        return new TermLexer(lineFeeder,
+                             false,
+                             quasiFlag,
+                             noTabsFlag);
     }
 
     /**
-     *
+     * Override to skip newlines.
      */
-    protected boolean isContinuer(int tokenType) {
-        return false;
+    public Object nextToken() throws IOException, SyntaxException {
+        Object result;
+        do {
+            result = super.nextToken();
+        } while (getCodeOfLeaf(result) == TermParser.EOL);
+        return result;
     }
 
     /**
      *
      */
-    protected AstroToken getNextToken() throws IOException, SyntaxException {
+    protected Object getNextToken() throws IOException, SyntaxException {
         if (myDelayedNextChar) {
             nextChar();
             myDelayedNextChar = false;
@@ -178,8 +194,8 @@
                         myContinueFlag = true;
                         skipLine();
                         stopToken();
-                        AstroToken result = getNextToken();
-                        if (result.getType() == TermParser.EOFTOK) {
+                        Object result = getNextToken();
+                        if (getCodeOfLeaf(result) == TermParser.EOFTOK) {
                             needMore("continued line");
                             return null; //make compiler happy
                         } else {
@@ -227,7 +243,7 @@
     /**
      * Called with myChar as the first character of the identifier.
      */
-    protected AstroToken identifier() throws IOException, SyntaxException {
+    protected Object identifier() throws IOException, SyntaxException {
         do {
             nextChar();
         } while (myChar != EOFCHAR && isIdentifierPart((char)myChar));
@@ -258,20 +274,20 @@
               ("usage: java org.erights.e.elang.syntax.ELexer file");
         }
         LineFeeder lr = new FileFeeder(url, ins, stdout);
-        TermLexer lex = new TermLexer(lr, false, false);
+        TermLexer lex = new TermLexer(lr, false, false, false);
         while (true) {
             try {
-                AstroToken t;
+                Object t;
                 do {
                     t = lex.nextToken();
                     //XXX should print t as a Functor.
                     stdout.println(t);
-                    if (t.getType() == TermParser.EOL) {
+                    if (lex.getCodeOfLeaf(t) == TermParser.EOL) {
                         stdout.print("stack: ",
                                      lex.myIndenter.toString(),
                                      "\n");
                     }
-                } while (t.getType() != TermParser.EOFTOK);
+                } while (lex.getCodeOfLeaf(t) != TermParser.EOFTOK);
                 return;
             } catch (SyntaxException sex) {
                 TextWriter err = new TextWriter(PrintStreamWriter.err(),



1.10      +56 -67    e/src/jsrc/org/quasiliteral/term/TermParser.java

Index: TermParser.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/term/TermParser.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- TermParser.java	2001/12/02 18:42:02	1.9
+++ TermParser.java	2001/12/03 03:30:56	1.10
@@ -12,15 +12,17 @@
 package org.quasiliteral.term;
 
 
+import org.erights.e.develop.exception.ThrowableSugar;
+import org.erights.e.elib.tables.ConstList;
+import org.erights.e.elib.tables.Twine;
 import org.quasiliteral.astro.AstroSchema;
-import org.quasiliteral.astro.AstroToken;
 import org.quasiliteral.astro.BaseSchema;
+import org.quasiliteral.quasiterm.QuasiBuilder;
+import org.quasiliteral.quasiterm.QuasiBuilderAdaptor;
 import org.quasiliteral.syntax.SyntaxException;
-import org.erights.e.elib.tables.ConstList;
-import org.erights.e.elib.tables.Twine;
 
 import java.io.IOException;
-//#line 22 "TermParser.java"
+//#line 24 "TermParser.java"
 
 
 
@@ -300,7 +302,7 @@
 "functorHole : '@' '{' LiteralInteger '}'",
 };
 
-//#line 133 "term.y"
+//#line 135 "term.y"
 
 
 /**
@@ -311,7 +313,7 @@
 /**
  *
  */
-private TermSchema b;
+private QuasiBuilder b;
 
 /**
  *
@@ -321,28 +323,35 @@
 /**
  *
  */
-public TermParser(TermLexer lexer, TermSchema builder) {
+public TermParser(TermLexer lexer, QuasiBuilder builder) {
     myLexer = lexer;
     b = builder;
     myOptResult = null;
 }
 
 /**
- * builder defaults to the SimpleTermSchema instance
+ * builder defaults to the quasi-adapted, non-quasi builder for
+ * building Term trees. 
  */
 static public Term run(Twine source) {
-    return (Term)run(source, SimpleTermSchema.THE_ONE);
+    return (Term)run(source, QuasiBuilderAdaptor.FOR_TERMS);
 }
 
 /**
  *
  */
-static public Object run(Twine source, TermSchema builder) {
-    TermLexer lexer = TermLexer.make(source, builder.doesQuasis());
-    TermParser parser = new TermParser(lexer, builder);
-    return parser.parse();
+static public Object run(Twine source, QuasiBuilder builder) {
+    try {
+        TermLexer lexer = TermLexer.make(source, builder.doesQuasis(), false);
+        TermParser parser = new TermParser(lexer, builder);
+        return parser.parse();
+    } catch (IOException iox) {
+        throw ThrowableSugar.backtrace(iox, "parsing a string?!");
+    }
 }
 
+
+
 /**
  *
  */
@@ -360,21 +369,21 @@
  *
  */
 private int yylex() {
-    AstroToken token = null;
+    Object token = null;
     try {
         token = myLexer.nextToken();
     } catch (IOException ex) {
         yyerror("io: " + ex);
     }
     yylval = token;
-    return token.getType();
+    return myLexer.getCodeOfLeaf(token);
 }
 
 /**
  *
  */
 private void yyerror(String s) throws SyntaxException {
-    int ttype = ((AstroToken)yylval).getType();
+    int ttype = myLexer.getCodeOfLeaf(yylval);
     if (TermParser.EOFTOK == ttype && "syntax error".equals(s)) {
         myLexer.syntaxError("Unexpected EOF");
     } else {
@@ -422,12 +431,12 @@
 }
 
 /**
- *
+ * Builds ASTs according to the term.y grammar
  */
 static public final AstroSchema DEFAULT_SCHEMA =
   new BaseSchema(ConstList.fromArray(TheTokens));
 
-//#line 379 "TermParser.java"
+//#line 388 "TermParser.java"
 //###############################################################
 // method: yylexdebug : check lexer state
 //###############################################################
@@ -574,110 +583,90 @@
       {
 //########## USER-SUPPLIED ACTIONS ##########
 case 1:
-//#line 70 "term.y"
+//#line 72 "term.y"
 { myOptResult = val_peek(0); }
 break;
 case 2:
-//#line 74 "term.y"
-{ yyval = b.term(val_peek(0), b.argList()); }
+//#line 76 "term.y"
+{ yyval = b.node(val_peek(0), b.argList()); }
 break;
 case 3:
-//#line 75 "term.y"
-{ yyval = b.term(val_peek(3), val_peek(1)); }
+//#line 77 "term.y"
+{ yyval = b.node(val_peek(3), val_peek(1)); }
 break;
 case 4:
-//#line 76 "term.y"
-{ yyval = b.term(val_peek(3), val_peek(1)); }
+//#line 78 "term.y"
+{ yyval = b.node(val_peek(3), val_peek(1)); }
 break;
 case 5:
-//#line 78 "term.y"
+//#line 80 "term.y"
 { yyval = b.termHole(null, val_peek(0)); }
 break;
 case 6:
-//#line 79 "term.y"
-{ yyval = b.termHole((AstroToken)val_peek(1), val_peek(0));}
+//#line 81 "term.y"
+{ yyval = b.termHole(val_peek(1), val_peek(0));}
 break;
 case 7:
-//#line 83 "term.y"
+//#line 85 "term.y"
 { yyval = b.argList(); }
 break;
 case 9:
-//#line 88 "term.y"
+//#line 90 "term.y"
 { yyval = b.argList(val_peek(0)); }
 break;
 case 10:
-//#line 89 "term.y"
+//#line 91 "term.y"
 { yyval = b.argList(val_peek(2), val_peek(0)); }
 break;
 case 12:
-//#line 94 "term.y"
+//#line 96 "term.y"
 { yyval = b.alt(val_peek(2), val_peek(0)); }
 break;
 case 13:
-//#line 101 "term.y"
+//#line 103 "term.y"
 { yyval = b.seq(  val_peek(0), "."); }
 break;
 case 14:
-//#line 102 "term.y"
+//#line 104 "term.y"
 { yyval = b.seq(  val_peek(1), (String)val_peek(0)); }
 break;
 case 15:
-//#line 103 "term.y"
+//#line 105 "term.y"
 { yyval = b.seq(null, (String)val_peek(0)); }
 break;
 case 16:
-//#line 104 "term.y"
+//#line 106 "term.y"
 { yyval = b.seq(null, "."); }
 break;
 case 17:
-//#line 105 "term.y"
+//#line 107 "term.y"
 { yyval = b.argGroup(val_peek(2), (String)val_peek(0)); }
 break;
 case 18:
-//#line 106 "term.y"
-{ %% = b.unpack(val_peek(0)); }
+//#line 108 "term.y"
+{ yyval = b.unpack(val_peek(0)); }
 break;
 case 19:
-//#line 110 "term.y"
+//#line 112 "term.y"
 { yyval = "?"; }
 break;
 case 20:
-//#line 111 "term.y"
+//#line 113 "term.y"
 { yyval = "+"; }
 break;
 case 21:
-//#line 112 "term.y"
+//#line 114 "term.y"
 { yyval = "*"; }
 break;
-case 22:
-//#line 116 "term.y"
-{ yyval = b.tag((AstroToken)val_peek(0)); }
-break;
-case 23:
-//#line 117 "term.y"
-{ yyval = b.litChar((AstroToken)val_peek(0)); }
-break;
-case 24:
-//#line 118 "term.y"
-{ yyval = b.litInteger((AstroToken)val_peek(0)); }
-break;
-case 25:
-//#line 119 "term.y"
-{ yyval = b.litFloat64((AstroToken)val_peek(0)); }
-break;
-case 26:
-//#line 120 "term.y"
-{ yyval = b.litString((AstroToken)val_peek(0)); }
-break;
 case 27:
-//#line 127 "term.y"
-{ yyval = b.dollarHole((AstroToken)val_peek(1)); }
+//#line 129 "term.y"
+{ yyval = b.dollarHole(val_peek(1)); }
 break;
 case 28:
-//#line 128 "term.y"
-{ yyval = b.atHole((AstroToken)val_peek(1)); }
+//#line 130 "term.y"
+{ yyval = b.atHole(val_peek(1)); }
 break;
-//#line 626 "TermParser.java"
+//#line 615 "TermParser.java"
 //########## END OF USER-SUPPLIED ACTIONS ##########
     }//switch
     //#### Now let's reduce... ####



1.9       +37 -28    e/src/jsrc/org/quasiliteral/term/term.y

Index: term.y
===================================================================
RCS file: /cvs/e/src/jsrc/org/quasiliteral/term/term.y,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- term.y	2001/12/02 18:42:02	1.8
+++ term.y	2001/12/03 03:30:56	1.9
@@ -7,12 +7,14 @@
 package org.quasiliteral.term;
 
 
+import org.erights.e.develop.exception.ThrowableSugar;
+import org.erights.e.elib.tables.ConstList;
+import org.erights.e.elib.tables.Twine;
 import org.quasiliteral.astro.AstroSchema;
-import org.quasiliteral.astro.AstroToken;
 import org.quasiliteral.astro.BaseSchema;
+import org.quasiliteral.quasiterm.QuasiBuilder;
+import org.quasiliteral.quasiterm.QuasiBuilderAdaptor;
 import org.quasiliteral.syntax.SyntaxException;
-import org.erights.e.elib.tables.ConstList;
-import org.erights.e.elib.tables.Twine;
 
 import java.io.IOException;
 %}
@@ -32,7 +34,7 @@
 /**
  * The starting production represents a single Term.
  * <p>
- * To understand what these productions mean, see {@link TermSchema}.
+ * To understand what these productions mean, see {@link QuasiBuilder}.
  * <p>
  * It's worth noting that the pure literal (or non-quasi) subset of
  * this grammar is simply:<pre>
@@ -71,12 +73,12 @@
 ;
 
 term:
-        functor                         { $$ = b.term($1, b.argList()); }
- |      functor     '(' argList ')'     { $$ = b.term($1, $3); }
- |      functorHole '(' argList ')'     { $$ = b.term($1, $3); }
+        functor                         { $$ = b.node($1, b.argList()); }
+ |      functor     '(' argList ')'     { $$ = b.node($1, $3); }
+ |      functorHole '(' argList ')'     { $$ = b.node($1, $3); }
 
  |         functorHole                  { $$ = b.termHole(null, $1); }
- |      ID functorHole                  { $$ = b.termHole((AstroToken)$1, $2);}
+ |      ID functorHole                  { $$ = b.termHole($1, $2);}
  ;
 
 argList:
@@ -103,7 +105,7 @@
  |           quant                      { $$ = b.seq(null, (String)$1); }
  |           '.'                        { $$ = b.seq(null, "."); }
  |      '(' args ')' quant              { $$ = b.argGroup($2, (String)$4); }
- |      '^' LiteralString               { %% = b.unpack($2); }
+ |      '^' LiteralString               { $$ = b.unpack($2); }
  ;
 
 quant:
@@ -113,19 +115,19 @@
  ;
 
 functor:
-        ID                              { $$ = b.tag((AstroToken)$1); }
- |      LiteralChar                     { $$ = b.litChar((AstroToken)$1); }
- |      LiteralInteger                  { $$ = b.litInteger((AstroToken)$1); }
- |      LiteralFloat64                  { $$ = b.litFloat64((AstroToken)$1); }
- |      LiteralString                   { $$ = b.litString((AstroToken)$1); }
+        ID
+ |      LiteralChar
+ |      LiteralInteger
+ |      LiteralFloat64
+ |      LiteralString
  ;
 
 /**
  * Starts off as a hole for a Functor, but may get promoted.
  */
 functorHole:
-        '$' '{' LiteralInteger '}'      { $$ = b.dollarHole((AstroToken)$3); }
- |      '@' '{' LiteralInteger '}'      { $$ = b.atHole((AstroToken)$3); }
+        '$' '{' LiteralInteger '}'      { $$ = b.dollarHole($3); }
+ |      '@' '{' LiteralInteger '}'      { $$ = b.atHole($3); }
  ;
 
 
@@ -140,7 +142,7 @@
 /**
  *
  */
-private TermSchema b;
+private QuasiBuilder b;
 
 /**
  *
@@ -150,28 +152,35 @@
 /**
  *
  */
-public TermParser(TermLexer lexer, TermSchema builder) {
+public TermParser(TermLexer lexer, QuasiBuilder builder) {
     myLexer = lexer;
     b = builder;
     myOptResult = null;
 }
 
 /**
- * builder defaults to the SimpleTermSchema instance
+ * builder defaults to the quasi-adapted, non-quasi builder for
+ * building Term trees. 
  */
 static public Term run(Twine source) {
-    return (Term)run(source, SimpleTermSchema.THE_ONE);
+    return (Term)run(source, QuasiBuilderAdaptor.FOR_TERMS);
 }
 
 /**
  *
  */
-static public Object run(Twine source, TermSchema builder) {
-    TermLexer lexer = TermLexer.make(source, builder.doesQuasis());
-    TermParser parser = new TermParser(lexer, builder);
-    return parser.parse();
+static public Object run(Twine source, QuasiBuilder builder) {
+    try {
+        TermLexer lexer = TermLexer.make(source, builder.doesQuasis(), false);
+        TermParser parser = new TermParser(lexer, builder);
+        return parser.parse();
+    } catch (IOException iox) {
+        throw ThrowableSugar.backtrace(iox, "parsing a string?!");
+    }
 }
 
+
+
 /**
  *
  */
@@ -189,21 +198,21 @@
  *
  */
 private int yylex() {
-    AstroToken token = null;
+    Object token = null;
     try {
         token = myLexer.nextToken();
     } catch (IOException ex) {
         yyerror("io: " + ex);
     }
     yylval = token;
-    return token.getType();
+    return myLexer.getCodeOfLeaf(token);
 }
 
 /**
  *
  */
 private void yyerror(String s) throws SyntaxException {
-    int ttype = ((AstroToken)yylval).getType();
+    int ttype = myLexer.getCodeOfLeaf(yylval);
     if (TermParser.EOFTOK == ttype && "syntax error".equals(s)) {
         myLexer.syntaxError("Unexpected EOF");
     } else {
@@ -251,7 +260,7 @@
 }
 
 /**
- *
+ * Builds ASTs according to the term.y grammar
  */
 static public final AstroSchema DEFAULT_SCHEMA =
   new BaseSchema(ConstList.fromArray(TheTokens));