CIT 594 Notes on Recognizer Assignment
Spring 2004, David Matuszek

Correction to RecognizerTest.testExpression()

In my RecognizerTest, my method testExpression() includes the following:

try {
    assertFalse(r6.expression()); fail();
	assertFalse(r7.expression()); fail();
} catch (ParseException e) {
}

Charlie Chambers points out that if r6.expression() correctly throws an exception, then r7.expression() will never be tested. The correct code is:

try {
    assertFalse(r6.expression()); fail();
} catch (ParseException e) {
}
try {
    assertFalse(r7.expression()); fail();
} catch (ParseException e) {
}

Thanks, Charlie! Extra credit for this.

Name change: ParseException -> LogoParseException

Before you create your own Exception type, you should always look around to see if there's a provided one that you can use instead. I should have done that, but I didn't, and it turns out that there is already a class java.text.ParseException. Unfortunately we can't use that class, because it's a checked exception (it extends Exception), and we need an unchecked exception (one that extends RuntimeException). Also, java.text.ParseException doesn't have the usual set of constructors, and lacks the one that I use.

While it is perfectly legal to write a class with the same name as a Sun-provided class, it isn't a good idea, so I'm changing the name.

To create this class, use File -> New -> Class, and fill in the Name LogoParseException. For the Superclass, type in java.lang.RuntimeException. Make sure Constructors from superclass is checked, and click Finish. Eclipse generates the entire class for you. The only thing left to do is to remove the lines that say // TODO Auto-generated constructor stub, otherwise these will show up in Eclipse's to do list.

Required method names:

Please use these exact method names in your Recognizer.java class:

block()
comparator()
move()
colorName()
condition()
procedure()
command()
eol()
variable()

I have provided the name() and number() methods for you. (In one place in the syntax I inconsistently used <integer> instead of <number>. This won't affect you, because you will only need the higher-level nonterminal <expression>.)

It is essential to name things exactly as specified, otherwise you aren't fulfilling the assignment requirements, and our JUnit tests won't work with your code.

Minor [optional] improvements to test method:

I have a method private void remainder(Tokenizer actual, String rest) to test whether the Tokenizer is in the "correct place" in the test string--that is, whether subsequent calls to Tokenizer actual will return the tokens represented by String rest. You call this method with the Tokenizer and the desired remainder of the String, for example, remainder(r4.tokenizer, "* 5 - 3 * 4 / 6 + 8").

This can be improved in two ways: