[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<TagName>(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));