[e-cvs] cvs commit: e/src/jsrc/org/quasiliteral/quasiterm Makefile TermBuilder.java TermLexer.java TermParser.java
markm@eros.cs.jhu.edu
markm@eros.cs.jhu.edu
Sat, 3 Nov 2001 19:39:43 -0500
markm 01/11/03 19:39:43
Added: src/jsrc/org/quasiliteral/quasiterm Makefile
TermBuilder.java TermLexer.java TermParser.java
Log:
Oops, forgot these
Revision Changes Path
1.1 e/src/jsrc/org/quasiliteral/quasiterm/Makefile
Index: Makefile
===================================================================
default: all
TOP=../../../../..
include $(TOP)/src/build/makerules.mk
BYACCJ = $(TOP)/dist/bin/$(PLATDIR)/byaccj$(EXE)
# The BYACCJ is assumed to be BYACC/Java, and could originally be
# obtained from "http://www.lincom-asg.com/~rjamison/byacc/". This is
# standard Berkeley yacc enhanced by Bob Jamison so that it can also
# output Java code. Both Berkeley yacc and BYACC/Java are covered by
# the standard Berkeley open source license. This website has since
# disappeared, so the byaccj sources are now included in the E
# sources.
all:
# The chmod is a horrible kludge to deal with the loss of the
# execute bit when tar-ing on Windows.
chmod a+x $(BYACCJ)
$(BYACCJ) -jv -f TermParser -s Object term.y
1.1 e/src/jsrc/org/quasiliteral/quasiterm/TermBuilder.java
Index: TermBuilder.java
===================================================================
package org.quasiliteral.quasiterm;
/**
* Used by the actions of term.y / TermParser.
* <p>
* XXX TermBuilder, TermParser, term.y, and TermLexer are all to be replaced
* with Antlr-based equivalents.
*
* @author <a href="mailto:markm@caplet.com">Mark S Miller</a>
*/
public interface TermBuilder {
/**
*
*/
Object list();
/**
*
*/
Object list(Object elem0);
/**
*
*/
Object with(Object sofar, Object next);
/**
*
*/
Object term(Object fnctr, Object args);
/**
*
*/
Object functor(Object ttype, Object src, Object optValue);
/**
*
*/
Object dollarHole(Object index);
/**
*
*/
Object atHole(Object index);
/**
*
*/
Object repr(Object hole, Object howMany);
}
1.1 e/src/jsrc/org/quasiliteral/quasiterm/TermLexer.java
Index: TermLexer.java
===================================================================
package org.quasiliteral.quasiterm;
import org.erights.e.develop.exception.PrintStreamWriter;
import org.erights.e.elib.eio.TextWriter;
import org.erights.e.elib.tables.Twine;
import org.erights.e.elang.syntax.LineFeeder;
import org.erights.e.elang.syntax.Indenter;
import org.erights.e.elang.syntax.TwineFeeder;
import org.erights.e.elang.syntax.SyntaxException;
import org.erights.e.elang.syntax.FileFeeder;
import org.quasiliteral.astro.AstroToken;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.math.BigInteger;
/**
* Breaks textually input into a stream of tokens according to the Term
* language's defined grammar.
* <p>
* XXX To be replaced with a lexer generated by Antlr
*
* @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
*/
public class TermLexer {
/**
*
*/
static public final int EOFCHAR = -1;
/** contains all lines after the current line */
private LineFeeder myInput;
/** the current line, or null at end-of-file */
public Twine myLTwine = null;
/** the string part, but as an array for speed */
public char[] myLData = null;
/** position in current line of candidate character */
private int myPos;
/** the candidate character, or EOFCHAR for end-of-file. */
private int myChar;
/**
* Where on the current line does the current token start? If the token
* starts before the current line, or if there is no current token, this
* is -1.
*/
private int myOptStartPos = -1;
/**
* Accumulates all text of the current token from lines before the
* current line, or null if no current token or if the current
* token starts on the current line. The EOL token itself is not
* considered to be a line spanning token.
*/
private Twine myOptStartText = null;
/**
* Keeps track of indentation level
*/
private Indenter myIndenter;
/**
* Should the next line get extra indentation as a continuation line?
*/
private boolean myContinueFlag;
/**
*
*/
public TermLexer(LineFeeder input)
throws IOException {
myInput = input;
myPos = -1;
myLTwine = myInput.optNextLine(false, 0, 'x', 0);
if (null == myLTwine) {
myLData = null;
} else {
myLData = myLTwine.bare().toCharArray();
}
nextChar();
myIndenter = new Indenter();
myContinueFlag = false;
}
/**
* @param sourceCode The source code itself
*/
static public TermLexer make(Twine sourceCode)
throws IOException {
LineFeeder lineFeeder = new TwineFeeder(sourceCode);
return new TermLexer(lineFeeder);
}
/**
* Skip to the end of this line, so that the next character read will be
* from the next line, forget any token we may have been in the midst
* of, and reset our indentation tracker.
*/
private void reset() throws IOException {
if (null != myLTwine) {
myPos = myLData.length-1;
myChar = myLData[myPos];
if ('\n' != myChar) {
throw new RuntimeException
("internal: must end with newline");
}
}
myOptStartPos = -1;
myOptStartText = null;
myIndenter = new Indenter();
myContinueFlag = false;
}
/**
*
*/
private void nextLine() throws IOException {
if (myLTwine == null) {
myChar = EOFCHAR;
return;
}
if (-1 == myOptStartPos) {
if (null == myOptStartText) {
//no current token, do nothing
} else {
//current token already started
myOptStartText = (Twine)myOptStartText.add(myLTwine);
}
} else {
//current token started on this line at myOptStartPos
myOptStartText = (Twine)myLTwine.run(myOptStartPos,
myLTwine.size());
myOptStartPos = -1;
}
myPos = -1;
char closer = myIndenter.getCloser();
int indent = myIndenter.getIndent();
if (myContinueFlag) {
indent += 2;
}
myLTwine =
myInput.optNextLine(('"' == closer || '`' == closer),
indent,
closer,
myIndenter.getCloseIndent());
if (null == myLTwine) {
//don't clear myContinueFlag on end-of-file
myLData = null;
} else {
myContinueFlag = false;
myLData = myLTwine.bare().toCharArray();
}
myChar = '\n';
}
/**
*
*/
private void nextChar() throws IOException {
while (true) {
if (null == myLTwine) {
myChar = EOFCHAR;
return;
}
myPos++;
int len = myLData.length;
if (myPos < len) {
myChar = myLData[myPos];
return;
} else {
nextLine();
}
}
}
/**
*
*/
public AstroToken nextToken() throws IOException, SyntaxException {
AstroToken result;
try {
result = getNextToken();
} finally {
myOptStartPos = -1;
myOptStartText = null;
}
if (TermParser.isContinuer(result.getType())) {
return continuer(result);
} else {
return result;
}
}
/**
* Separated out for use by '>'
*/
private AstroToken continuer(AstroToken result) throws IOException {
if (isWhite(myPos, myLData.length)) {
myContinueFlag = true;
skipLine();
}
return result;
}
/**
*
*/
/*package*/ void syntaxError(String msg)
throws SyntaxException, IOException {
int start = myOptStartPos;
if (-1 == start) {
start = myPos -1;
}
start = Math.max(Math.min(start, myPos -1), 0);
int bound = Math.max(myPos, start +1);
SyntaxException sex = new SyntaxException(msg,
myLTwine,
start,
bound);
reset();
throw sex;
}
/**
*
*/
private boolean eatDigit(int radix) throws IOException {
if (Character.digit((char)myChar, radix) != -1 || myChar == '_') {
nextChar();
return true;
} else {
return false;
}
}
/**
*
*/
private void skipWhiteSpace() throws IOException {
while (true) {
if (myChar == EOFCHAR) {
return;
}
if (Character.isWhitespace((char)myChar)) {
nextChar();
} else {
return;
}
}
}
/**
* Are all the characters on the current line from start inclusive to
* bound exclusive whitespace characters?
*/
private boolean isWhite(int start, int bound) {
for (int i = start; i < bound; i++) {
if (! Character.isWhitespace(myLData[i])) {
return false;
}
}
return true;
}
/**
*
*/
private AstroToken getNextToken() throws IOException, SyntaxException {
skipWhiteSpace();
startToken();
switch(myChar) {
case ',':
case ':':
case '=':
case '$':
case '@':
case '?':
case '+':
case '*': {
char c = (char)myChar;
nextChar();
return new AstroToken(c, endToken());
} case EOFCHAR: {
return new AstroToken(TermParser.EOFTOK, Twine.fromString(""));
} case '(': {
return openBracket(')');
} case ')': {
return closeBracket();
} case '{': {
return openBracket('}');
} case '}': {
return closeBracket();
} case '[': {
return openBracket(']');
} case ']': {
return closeBracket();
} case '#': {
// Skip comment to end of line (as in "//" case above).
skipLine();
stopToken();
return getNextToken();
} case '\\': {
nextChar();
if (myChar == 'u' || myChar == 'U') {
syntaxError("\\u... not yet implemented");
return null; //keep compiler happy
}
syntaxError("unrecognized escape");
return null; //keep compiler happy
} case '\'': {
return charLiteral();
} case '"': {
return stringLiteral();
} case '`': {
return twineLiteral();
}
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': {
return numberLiteral();
} default: {
if (isIdentifierStart((char)myChar)) {
return identifier();
} else {
syntaxError("unrecognized character: '" + (char)myChar +
"' code: " + (int)myChar);
return null; //keep compiler happy
}
}
}
}
/**
*
*/
private AstroToken openBracket(char closer) throws IOException {
int tokenType = myChar;
nextChar();
Twine openner = endToken();
return openBracket(tokenType, openner, closer);
}
/**
*
*/
private AstroToken openBracket(int tokenType, Twine openner, char closer)
throws IOException {
if (isWhite(myPos, myLData.length)) {
myIndenter.nest(openner, closer);
} else {
//Indent the next line to right after the open.
myIndenter.push(openner, closer, myPos);
}
return new AstroToken(tokenType, openner);
}
/**
*
*/
private AstroToken closeBracket() throws IOException {
char closerChar = (char)myChar;
nextChar();
Twine closer = endToken();
//on mismatched close, throws SyntaxError at openner
//on unmatched close, throws Syntax error at closer
myIndenter.pop(closerChar, closer);
return new AstroToken(closerChar, closer);
}
/**
*
*/
private char mustEat(char c) throws IOException, SyntaxException {
nextChar();
if (myChar != c) {
syntaxError("" + c + " expected");
}
return c;
}
/**
*
*/
private char charConstant() throws IOException, SyntaxException {
if (myChar == '\\') {
nextChar();
switch(myChar) {
case 'b': return '\b';
case 't': return '\t';
case 'n': return '\n';
case 'f': return '\f';
case 'r': return '\r';
case '"': return '"';
case '\'': return '\'';
case '\\': return '\\';
case '$': return mustEat('$');
case '@': return mustEat('@');
case '\n': {
//XXX need to move into stringLiteral only
//XXX bug: must be accepted at end of string
nextChar();
return charConstant();
}
case EOFCHAR: {
syntaxError("End of file in middle of literal");
}
case 'u': {
syntaxError
("XXX escaped uchar codes not yet implemented");
}
default: {
if (Character.isDigit((char)myChar)) {
syntaxError
("XXX escaped char codes not yet implemented");
} else {
syntaxError("Unrecognized escaped character");
}
}
}
} else if (myChar == '$') {
return mustEat('$');
} else if (myChar == '@') {
return mustEat('@');
} else if (myChar == '`') {
return mustEat('`');
} else if (myChar == EOFCHAR) {
syntaxError("End of file in middle of literal");
} else {
return (char)myChar;
}
return 'x'; //keep compiler happy
}
/**
*
*/
private AstroToken charLiteral() throws IOException, SyntaxException {
nextChar();
char value = charConstant();
nextChar();
if (myChar != '\'') {
syntaxError("char constant must end in \"'\"");
}
nextChar();
return new AstroToken(TermParser.LiteralChar,
endToken(),
new Character(value));
}
/**
* Called with myChar as the first character of the identifier.
*/
private AstroToken identifier() throws IOException, SyntaxException {
do {
nextChar();
} while (myChar != EOFCHAR && isIdentifierPart((char)myChar));
return new AstroToken(TermParser.Identifier, endToken());
}
/** pretty self explanatory */
public boolean isEndOfFile() {
return null == myLTwine;
}
/**
* The first character of an E identifier may be anything accepted
* as the first character of a Java identifier except '$'. I.e.,
* a letter or '_'.
*
* @see java.lang.Character#isJavaIdentifierStart
*/
static public boolean isIdentifierStart(char ch) {
return Character.isJavaIdentifierStart(ch) && ch != '$';
}
/**
* A non-first character of an E identifier may be anything
* accepted as a non-first character of a Java identifier except
* '$'. The ascii subset consists of letters, digits, and '_'.
* See Character.isJavaIdentifierPart() for the full spec.
*
* @see java.lang.Character#isJavaIdentifierPart
*/
static public boolean isIdentifierPart(char ch) {
return Character.isJavaIdentifierPart(ch) && ch != '$';
}
/**
*
*/
private AstroToken numberLiteral()
throws IOException, SyntaxException {
// Now handles floating point numbers as well as integers
boolean floating = false;
int radix = 10;
if (myChar == '0') {
radix = 8;
nextChar();
if (myChar == 'x' || myChar == 'X') {
radix = 16;
nextChar();
}
}
if (radix == 16) {
while (eatDigit(16)) {}
} else {
//even if radix == 8, we may instead have a floating point literal
while (eatDigit(10)) {}
// If we have a decimal point go for the fractional part
if (myChar == '.' && ! peekChar('.')) {
nextChar();
floating = true;
while (eatDigit(10)) {}
}
if ((myChar == 'E') || (myChar == 'e')) {
nextChar();
floating = true;
if (myChar == '-') {
nextChar();
}
while (eatDigit(10)) {}
}
}
Twine tok = endToken();
String str = tok.replaceAll("_", "").bare();
if (floating) {
return new AstroToken(TermParser.LiteralFloat64,
tok,
Double.valueOf(str));
} else {
if (radix == 16) {
//remove the leading "0x" to make BigInteger happy
str = str.substring(2);
}
return new AstroToken(TermParser.LiteralInteger,
tok,
new BigInteger(str, radix));
}
}
/**
* XXX Get rid of peekChar/0 or make it work
*/
private char peekChar() {
if (myChar == EOFCHAR || myChar == '\n') {
throw new Error("internal: can't peek here");
}
int last = myLData.length -1;
if (myPos < last) {
return myLData[myPos +1];
} else {
throw new Error("internal: (XXX bug) peek past end");
}
}
/**
*
*/
private boolean peekChar(char c) {
if (myChar == EOFCHAR || myChar == '\n') {
throw new Error("internal: can't peek here");
}
int last = myLData.length -1;
if (myPos < last) {
return c == myLData[myPos +1];
} else {
return false;
}
}
/**
*
*/
private AstroToken twineLiteral() throws IOException, SyntaxException {
nextChar(); //eat initial '`'
Twine openner = (Twine)myLTwine.run(myOptStartPos, myPos);
myIndenter.push(openner, '`', 0);
Twine value = Twine.fromString("");
while (true) {
int startSeg = myPos;
while ("$@`\n".indexOf(myChar) == -1) {
if (myChar == EOFCHAR) {
syntaxError("File end inside quasi-string literal");
}
nextChar();
}
value = (Twine)value.add(myLTwine.run(startSeg, myPos));
//myChar is a '$', '@', '`', or '\n'
if ('\n' == myChar) {
value = (Twine)value.add(myLTwine.run(myPos, myPos+1));
} else if (peekChar((char)myChar)) {
//A doubled $, @, or ` is uninterpreted, and turns into a
//single one.
Twine dbl = (Twine)myLTwine.run(myPos, myPos+2);
value = (Twine)value.add(dbl.infect(""+(char)myChar,
false));
nextChar();
nextChar();
} else if (myChar == '`') {
//terminal backquote is eaten but not added to the
//value of the resulting QuasiClose token.
nextChar();
Twine source = endToken();
myIndenter.pop('`', source);
return new AstroToken(TermParser.LiteralTwine,
source,
value);
} else {
syntaxError("unexpected: " + (char)myChar);
}
}
}
/**
* Skip to the rest of this line.
*/
private void skipLine() throws IOException {
if (null != myLTwine) {
myPos = myLData.length -1;
myChar = myLData[myPos];
}
nextChar();
}
/**
*
*/
private void startToken() {
if (-1 != myOptStartPos || null != myOptStartText) {
throw new Error("internal: token already started");
}
myOptStartPos = myPos;
}
/**
* Cancels a started token
*/
private void stopToken() {
myOptStartPos = -1;
myOptStartText = null;
}
/**
*
*/
private Twine endToken() {
Twine result;
int pos = myPos;
if (-1 == myOptStartPos) {
if (null == myOptStartText) {
throw new Error("internal: no current token");
} else {
//started on previous line
result = myOptStartText;
if (null != myLTwine) {
result = (Twine)result.add(myLTwine.run(0, pos));
}
}
} else {
//starts on this line
result = (Twine)myLTwine.run(myOptStartPos, pos);
}
stopToken();
return result;
}
/**
*
*/
private AstroToken stringLiteral() throws IOException, SyntaxException {
nextChar();
Twine openner = (Twine)myLTwine.run(myOptStartPos, myPos);
myIndenter.push(openner, '"', 0);
StringBuffer value = new StringBuffer();
while (myChar != '"') {
if (myChar == EOFCHAR) {
syntaxError("File ends inside string literal");
}
value.append(charConstant());
nextChar();
}
nextChar();
Twine closer = endToken();
myIndenter.pop('"', closer);
return new AstroToken(TermParser.LiteralString,
closer,
value.toString());
}
/**
* Just for testing. Reads an input file and prints one token per line
* to stdout.
*/
static public void main(String[] args)
throws IOException, SyntaxException {
TextWriter stdout = new TextWriter(PrintStreamWriter.out(), true);
String url;
BufferedReader ins;
if (0 == args.length) {
url = "stdin";
ins = PrintStreamWriter.in();
} else if (1 == args.length) {
url = args[0];
ins = new BufferedReader(new FileReader(args[0]));
} else {
throw new RuntimeException
("usage: java org.quasiliteral.quasiterm.TermLexer file");
}
LineFeeder lr = new FileFeeder(url, ins, stdout);
TermLexer lex = new TermLexer(lr);
while (true) {
try {
AstroToken t;
do {
t = lex.nextToken();
stdout.println(t.asFunctor(TermParser.getTokenNames()));
} while (t.getType() != TermParser.EOFTOK);
return;
} catch (SyntaxException sex) {
TextWriter err = new TextWriter(PrintStreamWriter.err(),
true);
err.indent("# ").print("# ", sex);
err.println();
}
}
}
}
1.1 e/src/jsrc/org/quasiliteral/quasiterm/TermParser.java
Index: TermParser.java
===================================================================
//### This file created by BYACC 1.8(/Java extension 0.92)
//### Java capabilities added 7 Jan 97, Bob Jamison
//### Updated : 27 Nov 97 -- Bob Jamison, Joe Nieten
//### 01 Jan 98 -- Bob Jamison -- fixed generic semantic constructor
//### 01 Jun 99 -- Bob Jamison -- added Runnable support
//### Please send bug reports to rjamison@lincom-asg.com
//### static char yysccsid[] = "@(#)yaccpar 1.8 (Berkeley) 01/20/90";
//#line 7 "term.y"
package org.quasiliteral.quasiterm;
import org.erights.e.elang.syntax.SyntaxException;
import org.erights.e.elib.tables.ConstList;
//#line 15 "TermParser.java"
//#####################################################################
// class: TermParser
// does : encapsulates yacc() parser functionality in a Java
// class for quick code development
//#####################################################################
public class TermParser
{
boolean yydebug; //do I want debug output?
int yynerrs; //number of errors so far
int yyerrflag; //was there an error?
int yychar; //the current working character
//########## MESSAGES ##########
//###############################################################
// method: debug
//###############################################################
void debug(String msg)
{
if (yydebug)
System.out.println(msg);
}
//########## STATE STACK ##########
final static int YYSTACKSIZE = 500; //maximum stack size
int statestk[],stateptr; //state stack
//###############################################################
// methods: state stack push,pop,drop,peek
//###############################################################
void state_push(int state)
{
if (stateptr>=YYSTACKSIZE) //overflowed?
return;
statestk[++stateptr]=state;
}
int state_pop()
{
if (stateptr<0) //underflowed?
return -1;
return statestk[stateptr--];
}
void state_drop(int cnt)
{
int ptr;
ptr=stateptr-cnt;
if (ptr<0)
return;
stateptr = ptr;
}
int state_peek(int relative)
{
int ptr;
ptr=stateptr-relative;
if (ptr<0)
return -1;
return statestk[ptr];
}
//###############################################################
// method: init_stacks : allocate and prepare stacks
//###############################################################
boolean init_stacks()
{
statestk = new int[YYSTACKSIZE];
stateptr = -1;
val_init();
return true;
}
//###############################################################
// method: dump_stacks : show n levels of the stacks
//###############################################################
void dump_stacks(int count)
{
int i;
System.out.println("=index==state====value= s:"+stateptr+" v:"+valptr);
for (i=0;i<count;i++)
System.out.println(" "+i+" "+statestk[i]+" "+valstk[i]);
System.out.println("======================");
}
//########## SEMANTIC VALUES ##########
//## **user defined:Object
String yytext;//user variable to return contextual strings
Object yyval; //used to return semantic vals from action routines
Object yylval;//the 'lval' (result) I got from yylex()
Object valstk[];
int valptr;
//###############################################################
// methods: value stack push,pop,drop,peek.
//###############################################################
void val_init()
{
valstk=new Object[YYSTACKSIZE];
yyval=new Object();
yylval=new Object();
valptr=-1;
}
void val_push(Object val)
{
if (valptr>=YYSTACKSIZE)
return;
valstk[++valptr]=val;
}
Object val_pop()
{
if (valptr<0)
return null;
return valstk[valptr--];
}
void val_drop(int cnt)
{
int ptr;
ptr=valptr-cnt;
if (ptr<0)
return;
valptr = ptr;
}
Object val_peek(int relative)
{
int ptr;
ptr=valptr-relative;
if (ptr<0)
return null;
return valstk[ptr];
}
//#### end semantic value section ####
public final static short Identifier=257;
public final static short LiteralChar=258;
public final static short LiteralInteger=259;
public final static short LiteralFloat64=260;
public final static short LiteralString=261;
public final static short LiteralTwine=262;
public final static short YYERRCODE=256;
final static short yylhs[] = { -1,
0, 0, 0, 2, 2, 3, 3, 3, 1, 1,
1, 1, 1, 1, 4, 4, 5, 5, 5, 6,
6, 6, 6, 6,
};
final static short yylen[] = { 2,
1, 4, 3, 0, 1, 1, 2, 3, 1, 3,
3, 5, 1, 1, 4, 4, 1, 1, 1, 1,
1, 1, 1, 1,
};
final static short yydefred[] = { 0,
0, 20, 21, 22, 23, 24, 0, 0, 0, 0,
0, 14, 13, 0, 0, 6, 0, 0, 0, 0,
0, 0, 0, 11, 3, 0, 17, 18, 19, 7,
0, 0, 0, 0, 8, 15, 16, 2, 12,
};
final static short yydgoto[] = { 16,
11, 17, 18, 12, 30, 13,
};
final static short yysindex[] = { -36,
-40, 0, 0, 0, 0, 0, -36, -104, -103, 0,
-18, 0, 0, -238, -245, 0, -68, -15, -31, -233,
-228, -36, -28, 0, 0, -36, 0, 0, 0, 0,
-91, -90, -5, -245, 0, 0, 0, 0, 0,
};
final static short yyrindex[] = { 0,
1, 0, 0, 0, 0, 0, -56, 0, 0, 0,
5, 0, 0, 0, 0, 0, 0, -39, -34, 0,
0, -3, 3, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
};
final static short yygindex[] = { 4,
0, 17, 0, 2, 0, -7,
};
final static int YYTABLESIZE=226;
final static short yytable[] = { 8,
9, 5, 10, 10, 1, 14, 14, 24, 19, 14,
29, 28, 2, 3, 4, 5, 6, 14, 20, 21,
15, 22, 23, 19, 25, 31, 39, 9, 26, 35,
32, 27, 34, 36, 37, 38, 4, 4, 33, 0,
9, 9, 10, 10, 9, 1, 10, 0, 1, 0,
0, 0, 0, 5, 7, 0, 0, 0, 14, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 9, 0, 10, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 2, 3, 4, 5, 6,
};
final static short yycheck[] = { 36,
0, 41, 0, 0, 0, 40, 41, 15, 7, 44,
42, 43, 258, 259, 260, 261, 262, 58, 123, 123,
61, 40, 261, 22, 93, 259, 34, 64, 44, 26,
259, 63, 61, 125, 125, 41, 93, 41, 22, -1,
40, 41, 40, 41, 44, 41, 44, -1, 44, -1,
-1, -1, -1, 93, 91, -1, -1, -1, 93, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 93, -1, 93, -1, 93, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
257, 258, 259, 260, 261, 262,
};
final static short YYFINAL=10;
final static short YYMAXTOKEN=262;
final static String yyname[] = {
"end-of-file",null,null,null,null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,"'$'",null,null,null,"'('","')'","'*'","'+'",
"','",null,null,null,null,null,null,null,null,null,null,null,null,null,"':'",
null,null,"'='",null,"'?'","'@'",null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
null,"'['",null,"']'",null,null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
null,null,"'{'",null,"'}'",null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
null,null,null,null,null,null,null,null,null,"Identifier","LiteralChar",
"LiteralInteger","LiteralFloat64","LiteralString","LiteralTwine",
};
final static String yyrule[] = {
"$accept : term",
"term : functor",
"term : functor '(' argList ')'",
"term : '[' argList ']'",
"argList :",
"argList : args",
"args : term",
"args : hole repr",
"args : args ',' term",
"functor : Identifier",
"functor : Identifier ':' LiteralString",
"functor : Identifier '=' literal",
"functor : Identifier ':' LiteralString '=' literal",
"functor : literal",
"functor : hole",
"hole : '$' '{' LiteralInteger '}'",
"hole : '@' '{' LiteralInteger '}'",
"repr : '?'",
"repr : '+'",
"repr : '*'",
"literal : LiteralChar",
"literal : LiteralInteger",
"literal : LiteralFloat64",
"literal : LiteralString",
"literal : LiteralTwine",
};
//#line 70 "term.y"
/**
*
*/
private TermBuilder b;
/**
*
*/
private int yylex() {
throw new RuntimeException("XXX not yet implemented");
}
/**
*
*/
private void yyerror(String s) throws SyntaxException {
throw new RuntimeException("XXX not yet implemented");
}
/**
*
*/
static /*package*/ boolean isContinuer(int ttype) {
return false; //for now
}
/*********************************/
/**
*
*/
static private String[] TheTokens = new String[yyname.length];
/** Not provided for us */
static /*package*/ final short EOFTOK = 0;
static {
System.arraycopy(yyname, 0, TheTokens, 0, yyname.length);
/* Since this language has no keywords, it's not a conflict
* for the names to be identifiers
*/
TheTokens[EOFTOK] = "EndOfFile";
}
/**
*
*/
static /*package*/ ConstList getTokenNames() {
return ConstList.fromArray(TheTokens);
}
//#line 294 "TermParser.java"
//###############################################################
// method: yylexdebug : check lexer state
//###############################################################
void yylexdebug(int state,int ch)
{
String s=null;
if (ch < 0) ch=0;
if (ch <= YYMAXTOKEN) //check index bounds
s = yyname[ch]; //now get it
if (s==null)
s = "illegal-symbol";
debug("state "+state+", reading "+ch+" ("+s+")");
}
//###############################################################
// method: yyparse : parse input and execute indicated items
//###############################################################
int yyparse()
{
int yyn; //next next thing to do
int yym; //
int yystate; //current parsing state from state table
String yys; //current token string
boolean doaction;
init_stacks();
yynerrs = 0;
yyerrflag = 0;
yychar = -1; //impossible char forces a read
yystate=0; //initial state
state_push(yystate); //save it
while (true) //until parsing is done, either correctly, or w/error
{
doaction=true;
if (yydebug) debug("loop");
//#### NEXT ACTION (from reduction table)
for (yyn=yydefred[yystate];yyn==0;yyn=yydefred[yystate])
{
if (yydebug) debug("yyn:"+yyn+" state:"+yystate+" char:"+yychar);
if (yychar < 0) //we want a char?
{
yychar = yylex(); //get next token
//#### ERROR CHECK ####
if (yychar < 0) //it it didn't work/error
{
yychar = 0; //change it to default string (no -1!)
if (yydebug)
yylexdebug(yystate,yychar);
}
}//yychar<0
yyn = yysindex[yystate]; //get amount to shift by (shift index)
if ((yyn != 0) && (yyn += yychar) >= 0 &&
yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
{
if (yydebug)
debug("state "+yystate+", shifting to state "+yytable[yyn]+"");
//#### NEXT STATE ####
yystate = yytable[yyn];//we are in a new state
state_push(yystate); //save it
val_push(yylval); //push our lval as the input for next rule
yychar = -1; //since we have 'eaten' a token, say we need another
if (yyerrflag > 0) //have we recovered an error?
--yyerrflag; //give ourselves credit
doaction=false; //but don't process yet
break; //quit the yyn=0 loop
}
yyn = yyrindex[yystate]; //reduce
if ((yyn !=0 ) && (yyn += yychar) >= 0 &&
yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
{ //we reduced!
if (yydebug) debug("reduce");
yyn = yytable[yyn];
doaction=true; //get ready to execute
break; //drop down to actions
}
else //ERROR RECOVERY
{
if (yyerrflag==0)
{
yyerror("syntax error");
yynerrs++;
}
if (yyerrflag < 3) //low error count?
{
yyerrflag = 3;
while (true) //do until break
{
if (stateptr<0) //check for under & overflow here
{
yyerror("stack underflow. aborting..."); //note lower case 's'
return 1;
}
yyn = yysindex[state_peek(0)];
if ((yyn != 0) && (yyn += YYERRCODE) >= 0 &&
yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
{
if (yydebug)
debug("state "+state_peek(0)+", error recovery shifting to state "+yytable[yyn]+" ");
yystate = yytable[yyn];
state_push(yystate);
val_push(yylval);
doaction=false;
break;
}
else
{
if (yydebug)
debug("error recovery discarding state "+state_peek(0)+" ");
if (stateptr<0) //check for under & overflow here
{
yyerror("Stack underflow. aborting..."); //capital 'S'
return 1;
}
state_pop();
val_pop();
}
}
}
else //discard this token
{
if (yychar == 0)
return 1; //yyabort
if (yydebug)
{
yys = null;
if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
if (yys == null) yys = "illegal-symbol";
debug("state "+yystate+", error recovery discards token "+yychar+" ("+yys+")");
}
yychar = -1; //read another
}
}//end error recovery
}//yyn=0 loop
if (!doaction) //any reason not to proceed?
continue; //skip action
yym = yylen[yyn]; //get count of terminals on rhs
if (yydebug)
debug("state "+yystate+", reducing "+yym+" by rule "+yyn+" ("+yyrule[yyn]+")");
if (yym>0) //if count of rhs not 'nil'
yyval = val_peek(yym-1); //get current semantic value
switch(yyn)
{
//########## USER-SUPPLIED ACTIONS ##########
case 1:
//#line 24 "term.y"
{ yyval = b.term(val_peek(0), b.list()); }
break;
case 2:
//#line 25 "term.y"
{ yyval = b.term(val_peek(3), val_peek(1)); }
break;
case 3:
//#line 26 "term.y"
{ yyval = b.term("list", val_peek(1)); }
break;
case 4:
//#line 30 "term.y"
{ yyval = b.list(); }
break;
case 6:
//#line 35 "term.y"
{ yyval = b.list(val_peek(0)); }
break;
case 7:
//#line 36 "term.y"
{ yyval = b.repr(val_peek(1), val_peek(0)); }
break;
case 8:
//#line 37 "term.y"
{ yyval = b.with(val_peek(2), val_peek(0)); }
break;
case 9:
//#line 41 "term.y"
{ yyval = b.functor(val_peek(0), val_peek(0), null); }
break;
case 10:
//#line 42 "term.y"
{ yyval = b.functor(val_peek(2), val_peek(0), null); }
break;
case 11:
//#line 43 "term.y"
{ yyval = b.functor(val_peek(2), val_peek(2), val_peek(0)); }
break;
case 12:
//#line 45 "term.y"
{ yyval = b.functor(val_peek(4), val_peek(3), val_peek(2)); }
break;
case 15:
//#line 51 "term.y"
{ yyval = b.dollarHole(val_peek(1)); }
break;
case 16:
//#line 52 "term.y"
{ yyval = b.atHole(val_peek(1)); }
break;
//#line 489 "TermParser.java"
//########## END OF USER-SUPPLIED ACTIONS ##########
}//switch
//#### Now let's reduce... ####
if (yydebug) debug("reduce");
state_drop(yym); //we just reduced yylen states
yystate = state_peek(0); //get new state
val_drop(yym); //corresponding value drop
yym = yylhs[yyn]; //select next TERMINAL(on lhs)
if (yystate == 0 && yym == 0)//done? 'rest' state and at first TERMINAL
{
debug("After reduction, shifting from state 0 to state "+YYFINAL+"");
yystate = YYFINAL; //explicitly say we're done
state_push(YYFINAL); //and save it
val_push(yyval); //also save the semantic value of parsing
if (yychar < 0) //we want another character?
{
yychar = yylex(); //get next character
if (yychar<0) yychar=0; //clean, if necessary
if (yydebug)
yylexdebug(yystate,yychar);
}
if (yychar == 0) //Good exit (if lex returns 0 ;-)
break; //quit the loop--all DONE
}//if yystate
else //else not done yet
{ //get next state and push, for next yydefred[]
yyn = yygindex[yym]; //find out where to go
if ((yyn != 0) && (yyn += yystate) >= 0 &&
yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
yystate = yytable[yyn]; //get new state
else
yystate = yydgoto[yym]; //else go to new defred
debug("after reduction, shifting from state "+state_peek(0)+" to state "+yystate+"");
state_push(yystate); //going again, so push state & val...
val_push(yyval); //for next action
}
}//main loop
return 0;//yyaccept!!
}
//## end of method parse() ######################################
}
//################### END OF CLASS yaccpar ######################