CIT 594 “Logo2006” Recognizer
Spring 2006, David Matuszek

Purposes:

General Idea:

In this assignment I define a BNF grammar for a small programming language, which I am calling "Logo 2006". This language is a simplified and modified version of the language Logo.

Your assignment is to write a recognizer for productions in that grammar. A recognizer is a program that, given a stream of tokens and a nonterminal, decides whether or not that stream of tokens is an instance of that nonterminal. The meaning of the production, if any, is outside the scope of this assignment.

For example, one of the nonterminals is <factor>, defined by

<factor> ::= <NAME> | <NUMBER> | "(" <expression> ")"

The stream of tokens SYMBOL:(  NUMBER:2  SYMBOL:+  NUMBER:3  SYMBOL:) (the tokenization of the String "(2+3)") is recognized by this production.

Supplied files:

Recognizer.java, RecognizerTest.java

Details:

The complete grammar is on a separate page for easy reference.

For each nonterminal nt in the grammar (excluding <NAME>, <NUMBER>, <SYMBOL>, and <EOL>), you should have one public boolean nt() method. Name your methods the same as the nonterminals they recognize. See Recognizer.java for examples, which has the required methods for <expression>, <term>, <factor>, <addOperator>, and <multiplyOperator>, plus some very useful (private) utility methods.

Provide complete JUnit tests for all public methods. Write Javadoc comments for all methods, public and private. Follow all specified style rules.

Caution: Some definitions contains brackets [ and ] as metasymbols, and <block> also uses "[" and "]" as terminals. Don't get these confused!

Recommended approach:

To get started, do the following:

  1. Download my files and Import... Recognizer.java into a new project in Eclipse (but don't import RecognizerTest.java). Also Import... the files you wrote for the Tokenizer assignment.
  2. To my Recognizer class, add stubs for each method you will need. This will be one method stub for every nonterminal (<command>, <move>, etc.). Note that you do not need method stubs for <NAME>, <NUMBER>, <SYMBOL>, or <EOL>, because your tokenizer provides these. You also don't need stubs for my provided methods.
  3. Use Eclipse to generate a TestCase for the Recognizer class. Have it generate all the test method stubs for you.
  4. Copy my methods from my RecognizerTest.java file into yours. This may involve replacing some constructors or method stubs.
  5. Create an AllTests.java test suite.
  6. Run JUnit to ensure everything is set up correctly.

Here's why I suggest the above. If you start by importing my RecognizerTest.java class, Eclipse won't add test method stubs to it (or if it will, I haven't yet discovered how). This would mean you would have to write all the test method stubs by hand, which is boring and error prone. If instead you let Eclipse generate the RecognizerTest.java class, it will be correct and complete, and you can add code from the provided RecognizerTest.java class simply by cutting and pasting.

I believe you will find that the easiest way to do this assignment is as follows:

  1. Pick some unwritten method that doesn't depend on other unwritten methods, and turn the test method stub in RecognizerTest.java into an actual test. For example, <comparator> doesn't depend on anything else, but <condition> depends on <comparator>, so write the test code for <comparator> first.
  2. Run the test. It should fail. Make certain that it does. (If it doesn't, there may be a problem with your test.)
  3. Write the code for the method you are testing (that is, fill in the method stub in the Recognizer class).
  4. Test and debug, test and debug, until your test passes. If you wrote adequate tests, you should be done with this method. If your tests pass and you know the method isn't finished, add a test that fails.
  5. Repeat until all methods have been coded.

Due date:

Tuesday, February 7, before midnight. Turn in your program via blackboard, and follow these conventions: