diff --git a/src/edu/ucsb/cs56/pconrad/parsing/evaluator/EvaluatorNewTest.java b/src/edu/ucsb/cs56/pconrad/parsing/evaluator/EvaluatorNewTest.java
new file mode 100644
index 0000000..db10e03
--- /dev/null
+++ b/src/edu/ucsb/cs56/pconrad/parsing/evaluator/EvaluatorNewTest.java
@@ -0,0 +1,63 @@
+package edu.ucsb.cs56.pconrad.parsing.evaluator;
+
+import edu.ucsb.cs56.pconrad.parsing.syntax.*;
+
+import static edu.ucsb.cs56.pconrad.parsing.evaluator.EvaluatorTest.evaluateNoException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import org.junit.Test;
+
+/**
+ * Like EvaluatorTest, but it adds in
+ * tests for the new grammar. This would normally be put
+ * in EvaluatorTest, but here we use a separate
+ * file to help prevent merge conflicts from occurring.
+ * @see edu.ucsb.cs56.pconrad.parsing.evaluator.EvaluatorTest
+ */
+public class EvaluatorNewTest {
+ // BEGIN INSTANCE VARIABLES
+ private final ASTFactory af;
+ // END INSTANCE VARIABLES
+
+ public EvaluatorNewTest() {
+ af = DefaultASTFactory.DEFAULT;
+ }
+
+ @Test
+ public void testEqualsEquals() {
+ assertEquals(1,
+ evaluateNoException(af.makeEqualsNode(af.makeLiteral(5),
+ af.makeLiteral(5))));
+ }
+
+ @Test
+ public void testEqualsNotEquals() {
+ assertEquals(0,
+ evaluateNoException(af.makeEqualsNode(af.makeLiteral(5),
+ af.makeLiteral(6))));
+ }
+
+ @Test
+ public void testNotEqualsEquals() {
+ assertEquals(0,
+ evaluateNoException(af.makeNotEqualsNode(af.makeLiteral(5),
+ af.makeLiteral(5))));
+ }
+
+ @Test
+ public void testNotEqualsNotEquals() {
+ assertEquals(1,
+ evaluateNoException(af.makeNotEqualsNode(af.makeLiteral(5),
+ af.makeLiteral(6))));
+ }
+
+ @Test
+ public void testTwoToTheThird() {
+ assertEquals(8,
+ evaluateNoException(af.makeExponentNode(af.makeLiteral(2),
+ af.makeLiteral(3))));
+ }
+
+
+} // EvaluatorNewTest
diff --git a/src/edu/ucsb/cs56/pconrad/parsing/parser/ParserNewTest.java b/src/edu/ucsb/cs56/pconrad/parsing/parser/ParserNewTest.java
new file mode 100644
index 0000000..0fedafe
--- /dev/null
+++ b/src/edu/ucsb/cs56/pconrad/parsing/parser/ParserNewTest.java
@@ -0,0 +1,75 @@
+package edu.ucsb.cs56.pconrad.parsing.parser;
+
+import edu.ucsb.cs56.pconrad.parsing.tokenizer.*;
+import edu.ucsb.cs56.pconrad.parsing.syntax.*;
+
+import static edu.ucsb.cs56.pconrad.parsing.parser.ParserTest.parseNoException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import org.junit.Test;
+
+
+/**
+ * Like ParserTest, but it adds in
+ * tests for the new grammar. This would normally be put
+ * in ParserTest, but here we use a separate
+ * file to help prevent merge conflicts from occurring.
+ * @see edu.ucsb.cs56.pconrad.parsing.parser.ParserTest
+ */
+
+public class ParserNewTest {
+ // begin instance variables
+ private final ASTFactory af;
+ // end instance variables
+
+ public ParserNewTest() {
+ af = DefaultASTFactory.DEFAULT;
+ }
+
+ @Test
+ public void testEqualsLiterals() {
+ assertEquals(af.makeEqualsNode(af.makeLiteral(1),
+ af.makeLiteral(2)),
+ parseNoException("1 == 2"));
+ }
+
+ @Test
+ public void testNotEqualsLiterals() {
+ assertEquals(af.makeNotEqualsNode(af.makeLiteral(1),
+ af.makeLiteral(2)),
+ parseNoException("1 != 2"));
+ }
+
+ @Test
+ public void testExponentLiterals() {
+ assertEquals(af.makeExponentNode(af.makeLiteral(2),
+ af.makeLiteral(3)),
+ parseNoException("2**3"));
+ }
+
+ @Test
+ public void testExponentAssociativity() {
+ assertEquals(af.makeExponentNode(af.makeLiteral(2),
+ af.makeExponentNode(af.makeLiteral(3),
+ af.makeLiteral(2))),
+ parseNoException("2**3**2"));
+ }
+
+ @Test
+ public void testExponentAssociativityWithParensRight() {
+ assertEquals(af.makeExponentNode(af.makeLiteral(2),
+ af.makeExponentNode(af.makeLiteral(3),
+ af.makeLiteral(2))),
+ parseNoException("2**(3**2)"));
+ }
+
+ @Test
+ public void testExponentAssociativityWithParensLeft() {
+ assertEquals(af.makeExponentNode(af.makeExponentNode(af.makeLiteral(2),
+ af.makeLiteral(3)),
+ af.makeLiteral(2)),
+ parseNoException("(2**3)**2"));
+ }
+
+} // ParserNewTest
diff --git a/src/edu/ucsb/cs56/pconrad/parsing/syntax/ASTFactory.java b/src/edu/ucsb/cs56/pconrad/parsing/syntax/ASTFactory.java
index e101f5e..19a125c 100644
--- a/src/edu/ucsb/cs56/pconrad/parsing/syntax/ASTFactory.java
+++ b/src/edu/ucsb/cs56/pconrad/parsing/syntax/ASTFactory.java
@@ -12,4 +12,17 @@ public interface ASTFactory {
public AST makeTimesNode(AST left, AST right);
public AST makeDivNode(AST left, AST right);
public AST makeUnaryMinusNode(AST inner);
+
+ // New AST nodes
+
+ public AST makeEqualsNode(AST left, AST right);
+ public AST makeNotEqualsNode(AST left, AST right);
+
+ public AST makeLessThanNode(AST left, AST right);
+ public AST makeLessThanOrEqualsNode(AST left, AST right);
+ public AST makeGreaterThanNode(AST left, AST right);
+ public AST makeGreaterThanOrEqualsNode(AST left, AST right);
+
+ public AST makeExponentNode(AST left, AST right);
+
}
diff --git a/src/edu/ucsb/cs56/pconrad/parsing/tokenizer/TokenFactory.java b/src/edu/ucsb/cs56/pconrad/parsing/tokenizer/TokenFactory.java
index 080959a..e2e4e8e 100644
--- a/src/edu/ucsb/cs56/pconrad/parsing/tokenizer/TokenFactory.java
+++ b/src/edu/ucsb/cs56/pconrad/parsing/tokenizer/TokenFactory.java
@@ -83,4 +83,48 @@ public interface TokenFactory {
*/
public Token makeDivideToken();
+
+ /** make a token that represents an equality operator ==
+ @return an appropriate token
+ */
+
+ public Token makeEqualsToken();
+
+ /** make a token that represents a not equals operator !=
+ @return an appropriate token
+ */
+
+ public Token makeNotEqualsToken();
+
+
+ /** make a token that represents a less than operator <
+ @return an appropriate token
+ */
+
+ public Token makeLessThanToken();
+
+ /** make a token that represents a less than or equals operator <=
+ @return an appropriate token
+ */
+
+ public Token makeLessThanOrEqualsToken();
+
+ /** make a token that represents a greater than operator >
+ @return an appropriate token
+ */
+
+ public Token makeGreaterThanToken();
+
+ /** make a token that represents a greater than or equals operator >=
+ @return an appropriate token
+ */
+
+ public Token makeGreaterThanOrEqualsToken();
+
+ /** make a token that represents an exponent operator **
+ @return an appropriate token
+ */
+
+ public Token makeExponentOperatorToken();
+
}
diff --git a/src/edu/ucsb/cs56/pconrad/parsing/tokenizer/TokenizerAddonsTest.java b/src/edu/ucsb/cs56/pconrad/parsing/tokenizer/TokenizerAddonsTest.java
new file mode 100644
index 0000000..452ee8a
--- /dev/null
+++ b/src/edu/ucsb/cs56/pconrad/parsing/tokenizer/TokenizerAddonsTest.java
@@ -0,0 +1,148 @@
+package edu.ucsb.cs56.pconrad.parsing.tokenizer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.fail;
+import org.junit.Test;
+
+public class TokenizerAddonsTest {
+
+ private TokenFactory tf = new DefaultTokenFactory();
+
+ @Test
+ public void testOneEqualsToken() {
+ assertArrayEquals(new Token[] { tf.makeEqualsToken() },
+ Tokenizer.tokenizeToArray("=="));
+ }
+
+
+ @Test
+ public void testTwoEqualsTokensWithWhiteSpace() {
+ assertArrayEquals(new Token[] {
+ tf.makeEqualsToken(),
+ tf.makeEqualsToken()
+ },
+ Tokenizer.tokenizeToArray("== =="));
+ }
+
+ @Test
+ public void testTwoEqualsTokensNoWhiteSpace() {
+ assertArrayEquals(new Token[] {
+ tf.makeEqualsToken(),
+ tf.makeEqualsToken()
+ },
+ Tokenizer.tokenizeToArray("===="));
+ }
+
+
+ @Test
+ public void testOneEqualsTokensOneErrorEqualToken() {
+ assertArrayEquals(new Token[] {
+ tf.makeEqualsToken(),
+ tf.makeErrorToken("=")
+ },
+ Tokenizer.tokenizeToArray("==="));
+ }
+
+ @Test
+ public void testEqualsExpression() {
+ assertArrayEquals(new Token[] { tf.makeIntToken("12"),
+ tf.makeEqualsToken(),
+ tf.makeIntToken("13") },
+ Tokenizer.tokenizeToArray("12 == 13"));
+ }
+
+ @Test
+ public void testNotEqualsToken() {
+ assertArrayEquals(new Token[] { tf.makeNotEqualsToken() },
+ Tokenizer.tokenizeToArray("!="));
+ }
+
+ @Test
+ public void testNotEqualsExpression() {
+ assertArrayEquals(new Token[] { tf.makeIntToken("12"),
+ tf.makeNotEqualsToken(),
+ tf.makeIntToken("13") },
+ Tokenizer.tokenizeToArray("12 != 13"));
+ }
+
+ @Test
+ public void testLeExpression() {
+ assertArrayEquals(new Token[] { tf.makeIntToken("12"),
+ tf.makeLessThanOrEqualsToken(),
+ tf.makeIntToken("13") },
+ Tokenizer.tokenizeToArray("12 <= 13"));
+ }
+
+ @Test
+ public void testLtExpression() {
+ assertArrayEquals(new Token[] { tf.makeIntToken("1"),
+ tf.makePlusToken(),
+ tf.makeIntToken("2"),
+ tf.makeLessThanToken(),
+ tf.makeIntToken("3"),
+ tf.makeTimesToken(),
+ tf.makeIntToken("4")
+ },
+ Tokenizer.tokenizeToArray("1+2<3*4"));
+ }
+
+
+ @Test
+ public void testGtExpression() {
+ assertArrayEquals(new Token[] { tf.makeIntToken("12"),
+ tf.makeGreaterThanToken(),
+ tf.makeIntToken("13") },
+ Tokenizer.tokenizeToArray("12 > 13"));
+ }
+
+ @Test
+ public void testGeExpression() {
+ assertArrayEquals(new Token[] { tf.makeLParenToken(),
+ tf.makeIntToken("78"),
+ tf.makeMinusToken(),
+ tf.makeIntToken("90"),
+ tf.makeRParenToken(),
+ tf.makeGreaterThanOrEqualsToken(),
+ tf.makeIntToken("13"),
+ tf.makeDivideToken(),
+ tf.makeIntToken("4")
+ },
+ Tokenizer.tokenizeToArray("(78-90)>=13/4"));
+ }
+
+
+ public void testExponentOperator() {
+ assertArrayEquals(new Token[] {
+ tf.makeIntToken("2"),
+ tf.makeExponentOperatorToken(),
+ tf.makeIntToken("16"),
+ },
+ Tokenizer.tokenizeToArray("2**16"));
+ }
+
+ public void testInequalityOperators() {
+ assertArrayEquals(new Token[] {
+ tf.makeLessThanToken(),
+ tf.makeLessThanOrEqualsToken(),
+ tf.makeLessThanToken(),
+ tf.makeGreaterThanToken(),
+ tf.makeLessThanOrEqualsToken(),
+ },
+ Tokenizer.tokenizeToArray("<<=<>>="));
+ }
+
+ public void brokenInequalityOperators() {
+ assertArrayEquals(new Token[] {
+ tf.makeLessThanToken(),
+ tf.makeErrorToken("="),
+ tf.makeGreaterThanToken(),
+ tf.makeErrorToken("="),
+ tf.makeEqualsToken(),
+ tf.makeErrorToken("="),
+ tf.makeErrorToken("="),
+ },
+ Tokenizer.tokenizeToArray("< = > = == = = "));
+ }
+
+}