CSC402 Assignment #4
100 points
Overview
This assignment is an application using a stack. The Java API has a generic Stack class that you may use in the java.util package (or you can use your own generic Stack class.)
The four short sample input files are here.
Write a class BalancedApp with a static main method that will parse an input file to check that it has properly balanced curly braces, square brackets, and parentheses - '{', '}', '[', ']', '(', and ')'. These will be referred to as delimiters.
What does properly balanced mean? It means when examining the characters of the file when the closing delimiter ']', is encountered, the most recently seen unmatched opening delimiter should be the matching one, '[' and similarly for the other delimiters. (See examples below.)
Your program should prompt the user for input file name (or read it from the command line). For example, if you read the file name from the command line, for an input file named test1.txt, the user would type
java BalancedApp test1.txtIf the file test1.txt contains:
This file has balanced curly braces, square brackets and parentheses: {}, [] and (). [Note that these characters are not required to balance on the same line, as long as there is a matching closing character.]
you must add line numbers as you print each line of the input file to standard output. E.g,
java BalancedApp test1.txt 1. This file has balanced curly braces, square brackets 2. and parentheses: {}, [] and (). [Note that these 3. characters are not required to balance on the 4. same line, as long as there is a matching closing character.] Input is balanced.
In addition to reporting a valid input file like the one above, your program should check for and report the following errors:
- A closing character - '}', ']', or ')' - with the preceding text
already balanced.
File test2.txt: [This ({line} is balanced) ], but this character ] is not. -------------------------------- java BalancedApp test2.txt 1. [This ({line} is balanced) ], 2. but this character ] Error: Line 2. Closing character ']', with no matching opening character.
The line numbers for the output and the reference to the Line number in the Error message are also required. See Implementation Hints below.
- A closing character which does not match the most recent
unmatched opening character.
File test3.txt: (This left parenthesis is not "closed"! [Balanced square brackets], then a } at the end. ----------------------------- java BalancedApp test3.txt 1. (This left parenthesis 2. is not "closed"! [Balanced 3. square brackets], then a } Error: Line 3. Symbol '}' is the wrong closing symbol for char = '(', line 1
- End of file reached but with an opening character still not
matched.
File test4.txt: Opening square bracket, [, is not matched when end of file reached. -------------------------- java BalancedApp test4.txt 1. Opening square 2. bracket, [, is not matched 3. when end of file reached. Error: At end of file, no closing symbol found for char = '[', line 2
Implementation Hints
It will probably be better to read the input one character at a time. As each character is read, it can be printed and so the output will appear formatted exactly like the input file. So this is similar to what you did for the previous assignment.
That is, you can use a Scanner instance to do this provided you change the Scanner's notion of what next() should return.
By default, next() returns next string of non whitespace characters. That is, a Scanner will use strings of 1 or more whitespace characters as delimiters to skip over until it finds a string of non-whitespace characters. To change this so that next() returns the next single character (whitespace or not) set the delimiter to the empty string:
Scanner sc = ...; sc.useDelimiter("");
Alternatively, you could use a BufferedReader. However, instead of using the BufferedReader's readline() method, a single character can be read using the read() method. This method returns the int -1 at end of file. Otherwise, the return value can be cast to a char.
Either way, when a character is read, it should also be printed to the output.
Use a stack to keep track of the opening symbols - '{', '[', '('. You will need to also keep track of line number where these symbols appeared. So it will be a good idea to create a class to represent the information you will need to push onto the stack when an opening symbol is read. For now I'll call this class DelimPos.
Stack<DelimPos> s = new Stack<DelimPos>(); s.push(new DelimPos(...));
To print line numbers and also have the error message reference a previous line number where an opening symbol occurred, the DelimPos instances will minimally need to contain both the opening delimiter character and the line number where it occurred. It might also be useful for the DelimPos class to have a method to provide the matching closing character for DelimPos instances.
Then the stack would be:
Stack<DelimPos> s = new Stack<DelimPos>(); int linecnt; char ch;
What to turn in
Submit your Java source file(s) to COL. If you use multiple files, submit one compressed file containing the source files.
You do not need to submit input text files.
Remember to include a header comment in each file minimally giving this information:
/** Description: Brief description of the class(es) in the file. * Author: your name * Class: CSC402 */
Each method should have a comment with a short description of what the method does, its parameter(s) and return values (if any) and what exception(s) it may throw.
For example, something like this:
/** * Determines if ... * @param input the item to be checked * @return The value of ... * @throws IllegalArgumentException if input is not ... */