Created a package for s-expressions and continued refactoring the parser

This commit is contained in:
Mike Cifelli 2016-12-14 13:09:41 -05:00
parent 10fdbf3b75
commit 930c8137df
44 changed files with 215 additions and 78 deletions

View File

@ -7,6 +7,9 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
/** /**
* <code>APPLY</code> represents the APPLY function in Lisp. * <code>APPLY</code> represents the APPLY function in Lisp.

View File

@ -7,6 +7,10 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
/** /**
* <code>ATOM</code> represents the ATOM function in Lisp. * <code>ATOM</code> represents the ATOM function in Lisp.

View File

@ -7,6 +7,9 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
/** /**
* <code>CAR</code> represents the CAR function in Lisp. * <code>CAR</code> represents the CAR function in Lisp.

View File

@ -7,6 +7,9 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
/** /**
* <code>CDR</code> represents the CDR function in Lisp. * <code>CDR</code> represents the CDR function in Lisp.

View File

@ -7,6 +7,9 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.Nil;
import sexpression.SExpression;
/** /**
* <code>COND</code> represents the COND form in Lisp. * <code>COND</code> represents the COND form in Lisp.

View File

@ -7,6 +7,9 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
/** /**
* <code>CONS</code> represents the CONS function in Lisp. * <code>CONS</code> represents the CONS function in Lisp.

View File

@ -7,6 +7,10 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
import java.util.HashMap; import java.util.HashMap;
/** /**

View File

@ -7,6 +7,10 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.LispNumber;
import sexpression.SExpression;
import sexpression.Symbol;
/** /**
* <code>DIVIDE</code> represents the '/' function in Lisp. * <code>DIVIDE</code> represents the '/' function in Lisp.

View File

@ -7,6 +7,10 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
/** /**
* <code>EQ</code> represents the EQ function in Lisp. * <code>EQ</code> represents the EQ function in Lisp.

View File

@ -7,6 +7,10 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
/** /**
* <code>EQUAL</code> represents the EQUAL function in Lisp. * <code>EQUAL</code> represents the EQUAL function in Lisp.

View File

@ -7,6 +7,11 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.LispNumber;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
/** /**
* <code>EQUALSP</code> represents the '=' function in Lisp. * <code>EQUALSP</code> represents the '=' function in Lisp.

View File

@ -7,6 +7,11 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
import java.util.HashMap; import java.util.HashMap;
/** /**

View File

@ -1,6 +1,9 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
public class EXIT extends LispFunction { public class EXIT extends LispFunction {

View File

@ -7,6 +7,9 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
/** /**
* <code>FUNCALL</code> represents the FUNCALL function in Lisp. * <code>FUNCALL</code> represents the FUNCALL function in Lisp.

View File

@ -7,6 +7,11 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.LispNumber;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
/** /**
* <code>GREATERP</code> represents the '&gt;' function in Lisp. * <code>GREATERP</code> represents the '&gt;' function in Lisp.

View File

@ -7,6 +7,9 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
/** /**
* <code>LAMBDA</code> represents the LAMBDA form in Lisp. * <code>LAMBDA</code> represents the LAMBDA form in Lisp.

View File

@ -7,6 +7,10 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.LispNumber;
import sexpression.SExpression;
import sexpression.Symbol;
/** /**
* <code>LENGTH</code> represents the LENGTH function in Lisp. * <code>LENGTH</code> represents the LENGTH function in Lisp.

View File

@ -7,6 +7,11 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.LispNumber;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
/** /**
* <code>LESSP</code> represents the '&lt;' function in Lisp. * <code>LESSP</code> represents the '&lt;' function in Lisp.

View File

@ -7,6 +7,9 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.Nil;
import sexpression.SExpression;
/** /**
* <code>LET</code> represents the LET form in Lisp. * <code>LET</code> represents the LET form in Lisp.

View File

@ -7,6 +7,9 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.Nil;
import sexpression.SExpression;
/** /**
* <code>LIST</code> represents the LIST function in Lisp. * <code>LIST</code> represents the LIST function in Lisp.

View File

@ -7,6 +7,10 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
/** /**
* <code>LISTP</code> represents the LISTP function in Lisp. * <code>LISTP</code> represents the LISTP function in Lisp.

View File

@ -7,6 +7,12 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.LispString;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
import java.io.*; import java.io.*;
/** /**
@ -64,9 +70,9 @@ public class LOAD extends LispFunction {
} }
// attempt to evaluate all the S-expressions contained in the file // attempt to evaluate all the S-expressions contained in the file
while (! parser.eof()) { while (! parser.isEof()) {
try { try {
SExpression sexpr = parser.getSExpr(); SExpression sexpr = parser.getNextSExpression();
EVAL.eval(sexpr); EVAL.eval(sexpr);
} catch (RuntimeException e) { } catch (RuntimeException e) {

View File

@ -7,6 +7,8 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
/** /**
* This class represents a Lisp FUNCTION in the PL-Lisp implementation. * This class represents a Lisp FUNCTION in the PL-Lisp implementation.

View File

@ -7,6 +7,8 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
/** /**
* A <code>LispFunction</code> is an internal representation of a built-in * A <code>LispFunction</code> is an internal representation of a built-in

View File

@ -7,6 +7,10 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.LispNumber;
import sexpression.SExpression;
import sexpression.Symbol;
/** /**
* <code>MINUS</code> represents the '-' function in Lisp. * <code>MINUS</code> represents the '-' function in Lisp.

View File

@ -7,6 +7,9 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.LispNumber;
import sexpression.SExpression;
/** /**
* <code>MULTIPLY</code> represents the '*' function in Lisp. * <code>MULTIPLY</code> represents the '*' function in Lisp.

View File

@ -7,6 +7,10 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.Nil;
import sexpression.SExpression;
import sexpression.Symbol;
/** /**
* <code>NULL</code> represents the NULL function in Lisp. * <code>NULL</code> represents the NULL function in Lisp.

View File

@ -7,6 +7,9 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.LispNumber;
import sexpression.SExpression;
/** /**
* <code>PLUS</code> represents the '+' function in Lisp. * <code>PLUS</code> represents the '+' function in Lisp.

View File

@ -7,6 +7,9 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
/** /**
* <code>PRINT</code> represents the PRINT function in Lisp. * <code>PRINT</code> represents the PRINT function in Lisp.

View File

@ -7,6 +7,9 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
/** /**
* <code>QUOTE</code> represents the QUOTE form in Lisp. * <code>QUOTE</code> represents the QUOTE form in Lisp.

View File

@ -7,6 +7,9 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
/** /**
* <code>SETF</code> represents the SETF form in Lisp. * <code>SETF</code> represents the SETF form in Lisp.

View File

@ -7,6 +7,9 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
/** /**
* <code>SYMBOL_FUNCTION</code> represents the SYMBOL-FUNCTION function in * <code>SYMBOL_FUNCTION</code> represents the SYMBOL-FUNCTION function in

View File

@ -7,6 +7,8 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.SExpression;
import java.util.HashMap; import java.util.HashMap;
/** /**

View File

@ -7,6 +7,10 @@
package eval; package eval;
import parser.*; import parser.*;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
import java.util.ArrayList; import java.util.ArrayList;
/** /**

View File

@ -7,6 +7,7 @@
package main; package main;
import parser.*; import parser.*;
import sexpression.SExpression;
import eval.*; import eval.*;
import error.ErrorManager; import error.ErrorManager;
import error.LispException; import error.LispException;
@ -62,9 +63,9 @@ public class LispInterpreter {
System.out.print(PROMPT); System.out.print(PROMPT);
} }
while (! parser.eof()) { while (! parser.isEof()) {
try { try {
SExpression sexpr = parser.getSExpr(); SExpression sexpr = parser.getNextSExpression();
String result = MessageFormat.format("{0}{1}{2}", ANSI_GREEN, EVAL.eval(sexpr), ANSI_RESET); String result = MessageFormat.format("{0}{1}{2}", ANSI_GREEN, EVAL.eval(sexpr), ANSI_RESET);
LispInterpreter.erasePrompt(interactive); LispInterpreter.erasePrompt(interactive);

View File

@ -3,10 +3,9 @@ package parser;
import java.io.InputStream; import java.io.InputStream;
import error.LispException; import error.LispException;
import parser.MalformedSExpressionException.EofEncounteredException; import parser.MalformedSExpressionException.*;
import parser.MalformedSExpressionException.StartsWithRightParenthesisException;
import parser.MalformedSExpressionException.UnrecognizedTokenException;
import scanner.LispScanner; import scanner.LispScanner;
import sexpression.*;
import token.Eof; import token.Eof;
import token.Token; import token.Token;
@ -18,37 +17,37 @@ public class LispParser {
private LispScanner scanner; private LispScanner scanner;
private Token nextToken; private Token nextToken;
private boolean nextTokenStored; private boolean isNextTokenStored;
public LispParser(InputStream inputStream, String fileName) { public LispParser(InputStream inputStream, String fileName) {
scanner = new LispScanner(inputStream, fileName); scanner = new LispScanner(inputStream, fileName);
nextToken = null; nextToken = null;
nextTokenStored = false; isNextTokenStored = false;
} }
public boolean eof() { public boolean isEof() {
if (!nextTokenStored) { if (!isNextTokenStored)
try { storeNextToken();
nextToken = scanner.getNextToken();
nextTokenStored = true;
} catch (LispException e) {
// this method should give the illusion of not actually reading
// a token, so we ignore any exceptions (they will be thrown
// the next time the 'getSExpr' method is called)
if (nextToken == null)
return false;
}
}
return nextToken instanceof Eof; return nextToken instanceof Eof;
} }
public SExpression getSExpr() { private void storeNextToken() {
if (!nextTokenStored) try {
nextToken = scanner.getNextToken();
isNextTokenStored = true;
} catch (LispException e) {
// This method should give the illusion of not actually reading
// a token, so we ignore any exception. It will be thrown when we
// return the next sExpression.
}
}
public SExpression getNextSExpression() {
if (!isNextTokenStored)
nextToken = scanner.getNextToken(); nextToken = scanner.getNextToken();
else else
nextTokenStored = false; isNextTokenStored = false;
return sExpr(); return sExpr();
} }

View File

@ -4,7 +4,7 @@
* Assignment: Lisp Parser * Assignment: Lisp Parser
*/ */
package parser; package sexpression;
/** /**
* This class represents an ATOM in the PL-Lisp implementation. * This class represents an ATOM in the PL-Lisp implementation.

View File

@ -4,7 +4,7 @@
* Assignment: Lisp Parser * Assignment: Lisp Parser
*/ */
package parser; package sexpression;
/** /**
* This class represents a Lisp CONS cell in the PL-Lisp implementation. * This class represents a Lisp CONS cell in the PL-Lisp implementation.

View File

@ -4,7 +4,7 @@
* Assignment: Lisp Parser * Assignment: Lisp Parser
*/ */
package parser; package sexpression;
/** /**
* This class represents a NUMBER in the PL-Lisp implementation. * This class represents a NUMBER in the PL-Lisp implementation.

View File

@ -4,7 +4,7 @@
* Assignment: Lisp Parser * Assignment: Lisp Parser
*/ */
package parser; package sexpression;
/** /**
* This class represents a STRING in the PL-Lisp implementation. * This class represents a STRING in the PL-Lisp implementation.

View File

@ -4,7 +4,7 @@
* Assignment: Lisp Parser * Assignment: Lisp Parser
*/ */
package parser; package sexpression;
/** /**
* This class represents NIL in the PL-Lisp implementation. * This class represents NIL in the PL-Lisp implementation.

View File

@ -4,7 +4,7 @@
* Assignment: Lisp Parser * Assignment: Lisp Parser
*/ */
package parser; package sexpression;
/** /**
* This is the base class for memory in the PL-Lisp implementation. * This is the base class for memory in the PL-Lisp implementation.

View File

@ -4,7 +4,7 @@
* Assignment: Lisp Parser * Assignment: Lisp Parser
*/ */
package parser; package sexpression;
/** /**
* This class represents a SYMBOL in the PL-Lisp implementation. * This class represents a SYMBOL in the PL-Lisp implementation.

View File

@ -7,6 +7,8 @@ import java.io.InputStream;
import org.junit.Test; import org.junit.Test;
import error.LispException; import error.LispException;
import sexpression.Nil;
import sexpression.SExpression;
import testutils.TestUtilities; import testutils.TestUtilities;
public class LispParserTester { public class LispParserTester {
@ -79,7 +81,7 @@ public class LispParserTester {
String input = ""; String input = "";
LispParser parser = createLispParser(input); LispParser parser = createLispParser(input);
assertTrue(parser.eof()); assertTrue(parser.isEof());
} }
@Test @Test
@ -87,40 +89,40 @@ public class LispParserTester {
String input = "abc"; String input = "abc";
LispParser parser = createLispParser(input); LispParser parser = createLispParser(input);
assertFalse(parser.eof()); assertFalse(parser.isEof());
} }
@Test @Test
public void testEofMethod_ReturnsTrueAfterSomeInput() { public void testEofMethod_ReturnsTrueAfterSomeInput() {
String input = "(yyz 9 9 9)"; String input = "(yyz 9 9 9)";
LispParser parser = createLispParser(input); LispParser parser = createLispParser(input);
parser.getSExpr(); parser.getNextSExpression();
assertTrue(parser.eof()); assertTrue(parser.isEof());
} }
@Test @Test
public void testEofMethod_ReturnsFalseAfterMultipleExpressions() { public void testEofMethod_ReturnsFalseAfterMultipleExpressions() {
String input = "()()()"; String input = "()()()";
LispParser parser = createLispParser(input); LispParser parser = createLispParser(input);
assertFalse(parser.eof()); assertFalse(parser.isEof());
parser.getSExpr(); parser.getNextSExpression();
assertFalse(parser.eof()); assertFalse(parser.isEof());
parser.getSExpr(); parser.getNextSExpression();
assertFalse(parser.eof()); assertFalse(parser.isEof());
} }
@Test @Test
public void testEofMethod_ReturnsTrueAfterMultipleExpressions() { public void testEofMethod_ReturnsTrueAfterMultipleExpressions() {
String input = "()()()"; String input = "()()()";
LispParser parser = createLispParser(input); LispParser parser = createLispParser(input);
assertFalse(parser.eof()); assertFalse(parser.isEof());
parser.getSExpr(); parser.getNextSExpression();
assertFalse(parser.eof()); assertFalse(parser.isEof());
parser.getSExpr(); parser.getNextSExpression();
assertFalse(parser.eof()); assertFalse(parser.isEof());
parser.getSExpr(); parser.getNextSExpression();
assertTrue(parser.eof()); assertTrue(parser.isEof());
} }
@Test @Test
@ -128,7 +130,7 @@ public class LispParserTester {
String input = "()"; String input = "()";
LispParser parser = createLispParser(input); LispParser parser = createLispParser(input);
assertNil(parser.getSExpr()); assertNil(parser.getNextSExpression());
} }
@Test @Test
@ -136,7 +138,7 @@ public class LispParserTester {
String input = "12"; String input = "12";
LispParser parser = createLispParser(input); LispParser parser = createLispParser(input);
assertNumber(parser.getSExpr()); assertNumber(parser.getNextSExpression());
} }
@Test @Test
@ -144,7 +146,7 @@ public class LispParserTester {
String input = "identifier1"; String input = "identifier1";
LispParser parser = createLispParser(input); LispParser parser = createLispParser(input);
assertSymbol(parser.getSExpr()); assertSymbol(parser.getNextSExpression());
} }
@Test @Test
@ -152,7 +154,7 @@ public class LispParserTester {
String input = "\"string\""; String input = "\"string\"";
LispParser parser = createLispParser(input); LispParser parser = createLispParser(input);
assertString(parser.getSExpr()); assertString(parser.getNextSExpression());
} }
@Test @Test
@ -160,7 +162,7 @@ public class LispParserTester {
String input = "(1 2)"; String input = "(1 2)";
LispParser parser = createLispParser(input); LispParser parser = createLispParser(input);
assertList(parser.getSExpr()); assertList(parser.getNextSExpression());
} }
@Test @Test
@ -168,8 +170,8 @@ public class LispParserTester {
String input = "'quoted"; String input = "'quoted";
LispParser parser = createLispParser(input); LispParser parser = createLispParser(input);
assertList(parser.getSExpr()); assertList(parser.getNextSExpression());
assertTrue(parser.eof()); assertTrue(parser.isEof());
} }
@Test @Test
@ -177,8 +179,8 @@ public class LispParserTester {
String input = "(defun f (x) \n (print \n (list \"x is \" x) \n ) \n )"; String input = "(defun f (x) \n (print \n (list \"x is \" x) \n ) \n )";
LispParser parser = createLispParser(input); LispParser parser = createLispParser(input);
assertList(parser.getSExpr()); assertList(parser.getNextSExpression());
assertTrue(parser.eof()); assertTrue(parser.isEof());
} }
@Test @Test
@ -186,12 +188,12 @@ public class LispParserTester {
String input = "(setf x 2) x \"hi\" () 29"; String input = "(setf x 2) x \"hi\" () 29";
LispParser parser = createLispParser(input); LispParser parser = createLispParser(input);
assertList(parser.getSExpr()); assertList(parser.getNextSExpression());
assertSymbol(parser.getSExpr()); assertSymbol(parser.getNextSExpression());
assertString(parser.getSExpr()); assertString(parser.getNextSExpression());
assertNil(parser.getSExpr()); assertNil(parser.getNextSExpression());
assertNumber(parser.getSExpr()); assertNumber(parser.getNextSExpression());
assertTrue(parser.eof()); assertTrue(parser.isEof());
} }
@Test @Test
@ -199,11 +201,11 @@ public class LispParserTester {
String input = "()"; String input = "()";
LispParser parser = createLispParser(input); LispParser parser = createLispParser(input);
parser.eof(); parser.isEof();
parser.eof(); parser.isEof();
assertNil(parser.getSExpr()); assertNil(parser.getNextSExpression());
assertTrue(parser.eof()); assertTrue(parser.isEof());
} }
@Test(expected = LispException.class) @Test(expected = LispException.class)
@ -211,7 +213,7 @@ public class LispParserTester {
String input = "["; String input = "[";
LispParser parser = createLispParser(input); LispParser parser = createLispParser(input);
parser.getSExpr(); parser.getNextSExpression();
} }
@Test(expected = LispException.class) @Test(expected = LispException.class)
@ -219,7 +221,7 @@ public class LispParserTester {
String input = "\"string"; String input = "\"string";
LispParser parser = createLispParser(input); LispParser parser = createLispParser(input);
parser.getSExpr(); parser.getNextSExpression();
} }
@Test(expected = LispException.class) @Test(expected = LispException.class)
@ -227,7 +229,7 @@ public class LispParserTester {
String input = "(bad list"; String input = "(bad list";
LispParser parser = createLispParser(input); LispParser parser = createLispParser(input);
parser.getSExpr(); parser.getNextSExpression();
} }
@Test(expected = LispException.class) @Test(expected = LispException.class)
@ -235,7 +237,7 @@ public class LispParserTester {
String input = ")"; String input = ")";
LispParser parser = createLispParser(input); LispParser parser = createLispParser(input);
parser.getSExpr(); parser.getNextSExpression();
} }
@Test(expected = LispException.class) @Test(expected = LispException.class)
@ -244,27 +246,42 @@ public class LispParserTester {
LispParser parser = createLispParser(input); LispParser parser = createLispParser(input);
try { try {
parser.eof(); parser.isEof();
} catch (LispException e) { } catch (LispException e) {
fail("Exception thrown too early"); fail("Exception thrown too early");
} }
parser.getSExpr(); parser.getNextSExpression();
} }
@Test(expected = LispException.class) @Test(expected = LispException.class)
public void givenBadCharacterAfterValidToken_ThrowsExceptionAtTheCorrectTime() { public void givenBadCharacterAfterValidToken_ThrowsExceptionAtTheCorrectTime() {
String input = "id[]"; String input = "id[";
LispParser parser = createLispParser(input); LispParser parser = createLispParser(input);
try { try {
parser.getSExpr(); parser.getNextSExpression();
parser.eof(); parser.isEof();
} catch (LispException e) { } catch (LispException e) {
fail("Exception thrown too early"); fail("Exception thrown too early");
} }
parser.getSExpr(); parser.getNextSExpression();
} }
@Test
public void afterException_ReturnsEofCorrectly() {
String input = "id[";
LispParser parser = createLispParser(input);
parser.getNextSExpression();
parser.isEof();
try {
parser.getNextSExpression();
fail("Expected LispException");
} catch (LispException e) {
}
assertTrue(parser.isEof());
}
} }