Added unit tests for the LispParser and started refactoring
This commit is contained in:
		
							parent
							
								
									be986ea5cf
								
							
						
					
					
						commit
						10fdbf3b75
					
				@ -1,137 +1,61 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 * Name: Mike Cifelli
 | 
					 | 
				
			||||||
 * Course: CIS 443 - Programming Languages
 | 
					 | 
				
			||||||
 * Assignment: Lisp Parser
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package parser;
 | 
					package parser;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.InputStream;
 | 
					import java.io.InputStream;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import error.LispException;
 | 
				
			||||||
 | 
					import parser.MalformedSExpressionException.EofEncounteredException;
 | 
				
			||||||
 | 
					import parser.MalformedSExpressionException.StartsWithRightParenthesisException;
 | 
				
			||||||
 | 
					import parser.MalformedSExpressionException.UnrecognizedTokenException;
 | 
				
			||||||
import scanner.LispScanner;
 | 
					import scanner.LispScanner;
 | 
				
			||||||
 | 
					import token.Eof;
 | 
				
			||||||
import token.Token;
 | 
					import token.Token;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * A <code>LispParser</code> converts a stream of bytes into internal
 | 
					 * Converts a stream of bytes into internal representations of Lisp
 | 
				
			||||||
 * representations of Lisp S-expressions. When the end of stream has been
 | 
					 * S-expressions.
 | 
				
			||||||
 * reached the <code>eof</code> method of this parser will return true.
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public class LispParser {
 | 
					public class LispParser {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private LispScanner scanner;
 | 
					    private LispScanner scanner;
 | 
				
			||||||
    private Token nextToken;
 | 
					    private Token nextToken;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    // A field to store an exception that has been thrown in the 'eof' method
 | 
					 | 
				
			||||||
    // as a result of reading in the next token from 'scanner'.
 | 
					 | 
				
			||||||
    private Exception delayedException;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // A field to notify us if the next token has already been stored in
 | 
					 | 
				
			||||||
    // 'nextToken' by the 'eof' method.
 | 
					 | 
				
			||||||
    private boolean nextTokenStored;
 | 
					    private boolean nextTokenStored;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    public LispParser(InputStream inputStream, String fileName) {
 | 
				
			||||||
     * Create a new <code>LispParser</code> that produces S-expressions from
 | 
					        scanner = new LispScanner(inputStream, fileName);
 | 
				
			||||||
     * the specified input stream.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param in
 | 
					 | 
				
			||||||
     *  the input stream to obtain S-expressions from (must not be
 | 
					 | 
				
			||||||
     *  <code>null</code>)
 | 
					 | 
				
			||||||
     * @param fileName
 | 
					 | 
				
			||||||
     *  the name of the file that <code>in</code> is reading from
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public LispParser(InputStream in, String fileName) {
 | 
					 | 
				
			||||||
        scanner = new LispScanner(in, fileName);
 | 
					 | 
				
			||||||
        nextToken = null;
 | 
					        nextToken = null;
 | 
				
			||||||
        delayedException = null;
 | 
					 | 
				
			||||||
        nextTokenStored = false;
 | 
					        nextTokenStored = false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Determing if this parser has reached the end of its underlying input
 | 
					 | 
				
			||||||
     * stream.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return
 | 
					 | 
				
			||||||
     *  <code>true</code> if this parser has reached the end of its underlying
 | 
					 | 
				
			||||||
     *  input stream; <code>false</code> otherwise
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public boolean eof() {
 | 
					    public boolean eof() {
 | 
				
			||||||
        if (! nextTokenStored) {
 | 
					        if (!nextTokenStored) {
 | 
				
			||||||
            // attempt to read the next token from 'scanner' and store it in
 | 
					 | 
				
			||||||
            // 'nextToken'
 | 
					 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                nextToken = scanner.getNextToken();
 | 
					                nextToken = scanner.getNextToken();
 | 
				
			||||||
                nextTokenStored = true;
 | 
					                nextTokenStored = true;
 | 
				
			||||||
            } catch (Exception e) {
 | 
					            } catch (LispException e) {
 | 
				
			||||||
                // this method should give the illusion of not actually reading
 | 
					                // this method should give the illusion of not actually reading
 | 
				
			||||||
                // a token, so we store any exceptions thrown as a result of
 | 
					                // a token, so we ignore any exceptions (they will be thrown
 | 
				
			||||||
                // reading in the next token from 'scanner' (it will be thrown
 | 
					 | 
				
			||||||
                // the next time the 'getSExpr' method is called)
 | 
					                // the next time the 'getSExpr' method is called)
 | 
				
			||||||
                delayedException = e;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (nextToken == null) {
 | 
					 | 
				
			||||||
                    // we have not successfully read in any tokens yet, so we
 | 
					 | 
				
			||||||
                    // could not have read in an end-of-file token
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (nextToken == null)
 | 
				
			||||||
                    return false;
 | 
					                    return false;
 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return (nextToken.getType() == Token.Type.EOF);
 | 
					        return nextToken instanceof Eof;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Returns the next S-expression from this parser.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @return
 | 
					 | 
				
			||||||
     *  the next S-expression from this parser
 | 
					 | 
				
			||||||
     * @throws RuntimeException
 | 
					 | 
				
			||||||
     *  Indicates that an illegal S-expression was encountered in the
 | 
					 | 
				
			||||||
     *  underlying input stream.
 | 
					 | 
				
			||||||
     * @throws IOException
 | 
					 | 
				
			||||||
     *  Indicates that an I/O error has occurred.
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public SExpression getSExpr() {
 | 
					    public SExpression getSExpr() {
 | 
				
			||||||
        if (delayedException != null) {
 | 
					        if (!nextTokenStored)
 | 
				
			||||||
            // the 'eof' method has stored an exception for us to throw
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // determine the type of the stored exception and throw it!
 | 
					 | 
				
			||||||
            if (delayedException instanceof RuntimeException) {
 | 
					 | 
				
			||||||
                RuntimeException e = (RuntimeException) delayedException;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // remove the exception from 'delayedException'
 | 
					 | 
				
			||||||
                delayedException = null;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                throw e;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (! nextTokenStored) {
 | 
					 | 
				
			||||||
            // the next token has not been stored in 'nextToken' by the 'eof'
 | 
					 | 
				
			||||||
            // method
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            nextToken = scanner.getNextToken();
 | 
					            nextToken = scanner.getNextToken();
 | 
				
			||||||
        } else {
 | 
					        else
 | 
				
			||||||
            // the 'eof' method has been called and has read in the next token
 | 
					 | 
				
			||||||
            // already to determine if we have reached the end-of-file
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            nextTokenStored = false;
 | 
					            nextTokenStored = false;
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return sExpr();
 | 
					        return sExpr();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // sExpr ::= NUMBER | IDENTIFIER | STRING | QUOTE_MARK sExpr |
 | 
					    // sExpr ::= NUMBER | IDENTIFIER | STRING | QUOTE_MARK sExpr |
 | 
				
			||||||
    //           LEFT_PAREN sExprTail
 | 
					    // LEFT_PAREN sExprTail
 | 
				
			||||||
    //
 | 
					 | 
				
			||||||
    // Returns: an S-expression that matches the rules given above
 | 
					 | 
				
			||||||
    // Throws: RuntimeException - Indicates that an illegal S-expression was
 | 
					 | 
				
			||||||
    //                            encountered in the underlying input stream.
 | 
					 | 
				
			||||||
    // Throws: IOException - Indicates that an I/O error has occurred.
 | 
					 | 
				
			||||||
    // Precondition: 'nextToken' is not null.
 | 
					 | 
				
			||||||
    private SExpression sExpr() {
 | 
					    private SExpression sExpr() {
 | 
				
			||||||
        // determine the type of 'nextToken' and create the appropriate
 | 
					 | 
				
			||||||
        // S-expression
 | 
					 | 
				
			||||||
        switch (nextToken.getType()) {
 | 
					        switch (nextToken.getType()) {
 | 
				
			||||||
        case NUMBER:
 | 
					        case NUMBER:
 | 
				
			||||||
            return new LispNumber(nextToken.getText());
 | 
					            return new LispNumber(nextToken.getText());
 | 
				
			||||||
@ -143,35 +67,22 @@ public class LispParser {
 | 
				
			|||||||
            nextToken = scanner.getNextToken();
 | 
					            nextToken = scanner.getNextToken();
 | 
				
			||||||
            SExpression arg = sExpr();
 | 
					            SExpression arg = sExpr();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return new Cons(new Symbol("QUOTE"),
 | 
					            return new Cons(new Symbol("QUOTE"), new Cons(arg, Nil.getUniqueInstance()));
 | 
				
			||||||
                            new Cons(arg, Nil.getUniqueInstance()));
 | 
					 | 
				
			||||||
        case LEFT_PAREN:
 | 
					        case LEFT_PAREN:
 | 
				
			||||||
            return sExprTail();
 | 
					            return sExprTail();
 | 
				
			||||||
        case RIGHT_PAREN:
 | 
					        case RIGHT_PAREN:
 | 
				
			||||||
            throw new RuntimeException("expression begins with \')\'" +
 | 
					            throw new StartsWithRightParenthesisException(nextToken);
 | 
				
			||||||
                                       " - line " + nextToken.getLine() +
 | 
					 | 
				
			||||||
                                       " column " + nextToken.getColumn());
 | 
					 | 
				
			||||||
        case EOF:
 | 
					        case EOF:
 | 
				
			||||||
            throw new RuntimeException("end-of-file encountered" +
 | 
					            throw new EofEncounteredException(nextToken);
 | 
				
			||||||
                                       " - line " + nextToken.getLine() +
 | 
					        default:
 | 
				
			||||||
                                       " column " + nextToken.getColumn());
 | 
					            throw new UnrecognizedTokenException(nextToken);
 | 
				
			||||||
        default:  // unrecognized token type
 | 
					 | 
				
			||||||
            throw new RuntimeException("unrecognizable token" +
 | 
					 | 
				
			||||||
                                       " - line " + nextToken.getLine() +
 | 
					 | 
				
			||||||
                                       " column " + nextToken.getColumn());
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // sExprTail ::= RIGHT_PAREN | sExpr sExprTail
 | 
					    // sExprTail ::= RIGHT_PAREN | sExpr sExprTail
 | 
				
			||||||
    //
 | 
					 | 
				
			||||||
    // Returns: an S-expression that matches the rules given above
 | 
					 | 
				
			||||||
    // Throws: IOException - Indicates that an I/O error has occurred.
 | 
					 | 
				
			||||||
    // Precondition: 'scanner' is not null.
 | 
					 | 
				
			||||||
    private SExpression sExprTail() {
 | 
					    private SExpression sExprTail() {
 | 
				
			||||||
        nextToken = scanner.getNextToken();
 | 
					        nextToken = scanner.getNextToken();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // determine the type of 'nextToken' and create the appropriate
 | 
					 | 
				
			||||||
        // S-expression
 | 
					 | 
				
			||||||
        switch (nextToken.getType()) {
 | 
					        switch (nextToken.getType()) {
 | 
				
			||||||
        case RIGHT_PAREN:
 | 
					        case RIGHT_PAREN:
 | 
				
			||||||
            return Nil.getUniqueInstance();
 | 
					            return Nil.getUniqueInstance();
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										69
									
								
								src/parser/MalformedSExpressionException.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								src/parser/MalformedSExpressionException.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,69 @@
 | 
				
			|||||||
 | 
					package parser;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.text.MessageFormat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import error.LispException;
 | 
				
			||||||
 | 
					import token.Token;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public abstract class MalformedSExpressionException extends LispException {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static final long serialVersionUID = 1L;
 | 
				
			||||||
 | 
					    private Token token;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public MalformedSExpressionException(Token token) {
 | 
				
			||||||
 | 
					        this.token = token;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public int getSeverity() {
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public String getMessage() {
 | 
				
			||||||
 | 
					        return MessageFormat.format("{0} - line {1}, column {2}", getMessagePrefix(), token.getLine(),
 | 
				
			||||||
 | 
					                                    token.getColumn());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public abstract String getMessagePrefix();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static class EofEncounteredException extends MalformedSExpressionException {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static final long serialVersionUID = 1L;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public EofEncounteredException(Token token) {
 | 
				
			||||||
 | 
					            super(token);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public String getMessagePrefix() {
 | 
				
			||||||
 | 
					            return "end-of-file encountered";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static class StartsWithRightParenthesisException extends MalformedSExpressionException {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static final long serialVersionUID = 1L;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public StartsWithRightParenthesisException(Token token) {
 | 
				
			||||||
 | 
					            super(token);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public String getMessagePrefix() {
 | 
				
			||||||
 | 
					            return "Expression begins with ')'";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static class UnrecognizedTokenException extends MalformedSExpressionException {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static final long serialVersionUID = 1L;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public UnrecognizedTokenException(Token token) {
 | 
				
			||||||
 | 
					            super(token);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public String getMessagePrefix() {
 | 
				
			||||||
 | 
					            return "Unrecognized token";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										270
									
								
								test/parser/LispParserTester.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										270
									
								
								test/parser/LispParserTester.java
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,270 @@
 | 
				
			|||||||
 | 
					package parser;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import static org.junit.Assert.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.io.InputStream;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.junit.Test;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import error.LispException;
 | 
				
			||||||
 | 
					import testutils.TestUtilities;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class LispParserTester {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private LispParser createLispParser(String input) {
 | 
				
			||||||
 | 
					        InputStream stringInputStream = TestUtilities.createInputStreamFromString(input);
 | 
				
			||||||
 | 
					        return new LispParser(stringInputStream, "testFile");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private void assertList(SExpression sExpression) {
 | 
				
			||||||
 | 
					        assertFalse(sExpression.atomp());
 | 
				
			||||||
 | 
					        assertTrue(sExpression.consp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.functionp());
 | 
				
			||||||
 | 
					        assertTrue(sExpression.listp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.nullp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.numberp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.stringp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.symbolp());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private void assertNil(SExpression sExpression) {
 | 
				
			||||||
 | 
					        assertEquals(sExpression, Nil.getUniqueInstance());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertTrue(sExpression.atomp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.consp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.functionp());
 | 
				
			||||||
 | 
					        assertTrue(sExpression.listp());
 | 
				
			||||||
 | 
					        assertTrue(sExpression.nullp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.numberp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.stringp());
 | 
				
			||||||
 | 
					        assertTrue(sExpression.symbolp());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private void assertNumber(SExpression sExpression) {
 | 
				
			||||||
 | 
					        assertTrue(sExpression.atomp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.consp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.functionp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.listp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.nullp());
 | 
				
			||||||
 | 
					        assertTrue(sExpression.numberp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.stringp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.symbolp());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private void assertString(SExpression sExpression) {
 | 
				
			||||||
 | 
					        assertTrue(sExpression.atomp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.consp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.functionp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.listp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.nullp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.numberp());
 | 
				
			||||||
 | 
					        assertTrue(sExpression.stringp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.symbolp());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private void assertSymbol(SExpression sExpression) {
 | 
				
			||||||
 | 
					        assertTrue(sExpression.atomp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.consp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.functionp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.listp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.nullp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.numberp());
 | 
				
			||||||
 | 
					        assertFalse(sExpression.stringp());
 | 
				
			||||||
 | 
					        assertTrue(sExpression.symbolp());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void testEofMethod_ReturnsTrueWithNoInput() {
 | 
				
			||||||
 | 
					        String input = "";
 | 
				
			||||||
 | 
					        LispParser parser = createLispParser(input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertTrue(parser.eof());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void testEofMethod_ReturnsFalseWithSomeInput() {
 | 
				
			||||||
 | 
					        String input = "abc";
 | 
				
			||||||
 | 
					        LispParser parser = createLispParser(input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertFalse(parser.eof());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void testEofMethod_ReturnsTrueAfterSomeInput() {
 | 
				
			||||||
 | 
					        String input = "(yyz 9 9 9)";
 | 
				
			||||||
 | 
					        LispParser parser = createLispParser(input);
 | 
				
			||||||
 | 
					        parser.getSExpr();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertTrue(parser.eof());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void testEofMethod_ReturnsFalseAfterMultipleExpressions() {
 | 
				
			||||||
 | 
					        String input = "()()()";
 | 
				
			||||||
 | 
					        LispParser parser = createLispParser(input);
 | 
				
			||||||
 | 
					        assertFalse(parser.eof());
 | 
				
			||||||
 | 
					        parser.getSExpr();
 | 
				
			||||||
 | 
					        assertFalse(parser.eof());
 | 
				
			||||||
 | 
					        parser.getSExpr();
 | 
				
			||||||
 | 
					        assertFalse(parser.eof());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void testEofMethod_ReturnsTrueAfterMultipleExpressions() {
 | 
				
			||||||
 | 
					        String input = "()()()";
 | 
				
			||||||
 | 
					        LispParser parser = createLispParser(input);
 | 
				
			||||||
 | 
					        assertFalse(parser.eof());
 | 
				
			||||||
 | 
					        parser.getSExpr();
 | 
				
			||||||
 | 
					        assertFalse(parser.eof());
 | 
				
			||||||
 | 
					        parser.getSExpr();
 | 
				
			||||||
 | 
					        assertFalse(parser.eof());
 | 
				
			||||||
 | 
					        parser.getSExpr();
 | 
				
			||||||
 | 
					        assertTrue(parser.eof());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void givenNil_CreatesCorrectSExpression() {
 | 
				
			||||||
 | 
					        String input = "()";
 | 
				
			||||||
 | 
					        LispParser parser = createLispParser(input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertNil(parser.getSExpr());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void givenNumber_CreatesCorrectSExpression() {
 | 
				
			||||||
 | 
					        String input = "12";
 | 
				
			||||||
 | 
					        LispParser parser = createLispParser(input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertNumber(parser.getSExpr());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void givenIdentifier_CreatesCorrectSExpression() {
 | 
				
			||||||
 | 
					        String input = "identifier1";
 | 
				
			||||||
 | 
					        LispParser parser = createLispParser(input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertSymbol(parser.getSExpr());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void givenString_CreatesCorrectSExpression() {
 | 
				
			||||||
 | 
					        String input = "\"string\"";
 | 
				
			||||||
 | 
					        LispParser parser = createLispParser(input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertString(parser.getSExpr());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void givenList_CreatesCorrectSExpression() {
 | 
				
			||||||
 | 
					        String input = "(1 2)";
 | 
				
			||||||
 | 
					        LispParser parser = createLispParser(input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertList(parser.getSExpr());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void givenQuotedIdentifier_CreatesCorrectSExpression() {
 | 
				
			||||||
 | 
					        String input = "'quoted";
 | 
				
			||||||
 | 
					        LispParser parser = createLispParser(input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertList(parser.getSExpr());
 | 
				
			||||||
 | 
					        assertTrue(parser.eof());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void givenComplexList_CreatesCorrectSExpression() {
 | 
				
			||||||
 | 
					        String input = "(defun f (x) \n (print \n (list \"x is \" x) \n ) \n )";
 | 
				
			||||||
 | 
					        LispParser parser = createLispParser(input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertList(parser.getSExpr());
 | 
				
			||||||
 | 
					        assertTrue(parser.eof());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void givenMultipleExpressions_CreatesCorrectSExpressions() {
 | 
				
			||||||
 | 
					        String input = "(setf x 2) x \"hi\" () 29";
 | 
				
			||||||
 | 
					        LispParser parser = createLispParser(input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertList(parser.getSExpr());
 | 
				
			||||||
 | 
					        assertSymbol(parser.getSExpr());
 | 
				
			||||||
 | 
					        assertString(parser.getSExpr());
 | 
				
			||||||
 | 
					        assertNil(parser.getSExpr());
 | 
				
			||||||
 | 
					        assertNumber(parser.getSExpr());
 | 
				
			||||||
 | 
					        assertTrue(parser.eof());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void givenNil_CreatesCorrectSExpressionAfterEofCalls() {
 | 
				
			||||||
 | 
					        String input = "()";
 | 
				
			||||||
 | 
					        LispParser parser = createLispParser(input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        parser.eof();
 | 
				
			||||||
 | 
					        parser.eof();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertNil(parser.getSExpr());
 | 
				
			||||||
 | 
					        assertTrue(parser.eof());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test(expected = LispException.class)
 | 
				
			||||||
 | 
					    public void givenBadToken_ThrowsException() {
 | 
				
			||||||
 | 
					        String input = "[";
 | 
				
			||||||
 | 
					        LispParser parser = createLispParser(input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        parser.getSExpr();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test(expected = LispException.class)
 | 
				
			||||||
 | 
					    public void givenUnterminatedString_ThrowsException() {
 | 
				
			||||||
 | 
					        String input = "\"string";
 | 
				
			||||||
 | 
					        LispParser parser = createLispParser(input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        parser.getSExpr();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test(expected = LispException.class)
 | 
				
			||||||
 | 
					    public void givenUnterminatedList_ThrowsException() {
 | 
				
			||||||
 | 
					        String input = "(bad list";
 | 
				
			||||||
 | 
					        LispParser parser = createLispParser(input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        parser.getSExpr();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test(expected = LispException.class)
 | 
				
			||||||
 | 
					    public void givenUnmatchedRightParenthesis_ThrowsException() {
 | 
				
			||||||
 | 
					        String input = ")";
 | 
				
			||||||
 | 
					        LispParser parser = createLispParser(input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        parser.getSExpr();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test(expected = LispException.class)
 | 
				
			||||||
 | 
					    public void givenBadCharacter_ThrowsExceptionAfterEofCalled() {
 | 
				
			||||||
 | 
					        String input = "[";
 | 
				
			||||||
 | 
					        LispParser parser = createLispParser(input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            parser.eof();
 | 
				
			||||||
 | 
					        } catch (LispException e) {
 | 
				
			||||||
 | 
					            fail("Exception thrown too early");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        parser.getSExpr();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test(expected = LispException.class)
 | 
				
			||||||
 | 
					    public void givenBadCharacterAfterValidToken_ThrowsExceptionAtTheCorrectTime() {
 | 
				
			||||||
 | 
					        String input = "id[]";
 | 
				
			||||||
 | 
					        LispParser parser = createLispParser(input);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            parser.getSExpr();
 | 
				
			||||||
 | 
					            parser.eof();
 | 
				
			||||||
 | 
					        } catch (LispException e) {
 | 
				
			||||||
 | 
					            fail("Exception thrown too early");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        parser.getSExpr();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user