CS351 - Design of Large Programs - Professor Ackley

Tuesday and Thursday: 11:00am - 12:15pm (Centennial B146) Labs: Monday (001) 1:00pm - 1:50pm and Thursday (005) 12:30pm - 1:20pm (Centennial B146)

Lab #3: Recognizer

Use a Recognizer to check to see if an input is valid given a grammar.

Goals

  • Implement the labs.lab3.Recognizer interface
  • Use the provided grammar to determine if an input is valid or not

Needs


Background

Since you now know how to read an input in using a java.io.Reader character-by-character, this lab is based around using that knowledge to write a Recognizer. As described in class, a Recognizer "checks the syntax but doesn't do anything else". More specifically, it checks the syntax of an input against a given grammar but doesn't do anything else. The grammar that we will use for this assignment is as follows:

Bal < Single | Double | Triple | '.'
Single < '(' + Bal + ')'
Double < '[' + Bal + Bal + ']'
Triple < '{' + Bal + Bal + Bal + '}'


where "Bal" is the start symbol. The '|' character means "either or" and the '+' character means in "sequence". Note that this grammar uses a different syntax than that of the SiteRiter. That's okay; just the power of grammars.

To implement this in code, you might notice that we will have to have a parse method for each NON-TERMINAL rule. The labs.lab3.Recognizer has exactly 4 methods you will implement (one for each rule).

boolean parseBal(Reader reader) throws IOException;
boolean parseSingle(Reader reader) throws IOException;
boolean parseDouble(Reader reader) throws IOException;
boolean parseTriple(Reader reader) throws IOException;


//TODO

Your job is to implement a labs.lab3.Recognizer that will tell if a given input is a valid String against the given grammar. The following main() method should be copy and pasted into your RecognizerImpl.java which you will turn in:

/**
* This method should be the one to print to the console using
* {@code System.out.println()} that the input is either recognized or
* un-recognizable.
*
* @param args
*/
public static void main(String[] args) {
String validInput1 = ".";
String invalidInput1 = "([.])";
String validInput2 = "((((((.))))))";
String invalidInput2 = "[.[.].]";
String validInput3 = "{[.(.)].(.)}";
String invalidInput3 = "[.)";
String[] potentialInputs = { validInput1, invalidInput1, validInput2,
invalidInput2, validInput3, invalidInput3 };

Recognizer recognizer = new RecognizerImpl();

try {
for (int i = 0; i < 6; i++) {
if (recognizer.parseBal(new StringReader(potentialInputs[i]))) {
// must have recognized it!
System.out.println("Recognizer recognized "
+ potentialInputs[i] + " as valid.");
} else {
// invalid, boo.
System.out.println("Recognizer did NOT recognize "
+ potentialInputs[i] + " as valid.");
}
}
} catch (IOException e) {
System.out.println("IO Exception. Recognizer = Dead.");
e.printStackTrace();
}
}


A correct implementation will produce the following output to the console:

Recognizer recognized . as valid.
Recognizer did NOT recognize ([.]) as valid.
Recognizer recognized ((((((.)))))) as valid.
Recognizer did NOT recognize [.[.].] as valid.
Recognizer recognized {[.(.)].(.)} as valid.
Recognizer did NOT recognize [.) as valid.


Turn in a single "RecognizerImpl.java" file using the online interface by 11:59:59 PM of your lab day.