Ah. Then you only need to deal with one line at a time.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
int main( int argc, char* argv[] )
{
if (argc != 2)
{
cout << "Brace Balance Checker\nKomal Rani\n\n"
"to use:\n " << argv[ 0 ] << " FILE\n";
return 0;
}
ifstream file( argv[ 1 ] );
string line;
// Read and validate each line in the file
while (getline( file, line ))
validate( line );
file.close();
return 0;
}
|
The purpose of the stack is to match
( with
), or
[ with
], or
{ with
}.
As an example, given the line (a simple
scheme-language-style program):
(if (eq? tomatoes rotten) (list [spill milk] [toss cookies}) {eat tomatoes}) )
Let us verify that
1. Only
( matches
), and
[ matches
], etc.
2. Braces are balanced.
We also need to define the tokens we will use on the stack:
CURVY
SQUARE
CURLY
Initially the stack is empty
1(bottom) *
Starting at the beginning of the line, we immediately find a
'('. Push a CURVY. Now the stack looks like this:
Continuing along, we soon find another
'('. Push another CURVY.
1 2 3
|
CURVY *
CURVY
(bottom)
|
The next brace we find is a
')', indicating that it is time to pop. The
')' is a CURVY, so we expect the top of the stack to have a CURVY. For our example that is the case.
1 2 3
|
CURVY *
CURVY
(bottom)
|
Pop it off the stack.
Immediately we encounter another
'(' CURVY. Push it.
1 2 3
|
CURVY *
CURVY
(bottom)
|
And shortly after we find a
'[' SQUARE. Push it also.
1 2 3 4
|
SQUARE *
CURVY
CURVY
(bottom)
|
When we finish spilling our milk in astonishment, there is a
']' telling us to pop a SQUARE. Since the top of the stack has a SQUARE, all is well. Popping it leaves our stack as:
1 2 3
|
CURVY *
CURVY
(bottom)
|
Another open SQUARE:
1 2 3 4
|
SQUARE *
CURVY
CURVY
(bottom)
|
When we are finished with our comic interlude, we encounter a
'}', which tells us that the top of the stack should have a CURLY on it.
1 2 3 4
|
SQUARE *
CURVY
CURVY
(bottom)
|
The problem is, it doesn't. Hence, we have found an error. A ha! Print an error message and
return.
There is one more error in the example for you to think about.
If you get to the end of the line and the stack is empty, then everything matched nicely.
The code to implement it should be pretty simple:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
void validate( const string& line )
{
Stack stack;
for (unsigned n = 0; n < line.length(); n++)
switch (line[ n ])
{
// ( [ { --> push
case '(': stack.push( CURVY ); break;
case '[': ...
...
// ) ] } --> pop
case ')': ...
break;
case ']': ...
break;
...
// default = do nothing
}
// You need to put some code here to handle the
// second error in my example. Remember, at this
// point, the stack should be in a specific state. What
// is it?
}
|
You will have to fill-in the missing code. You will also have to decide what
CURVY,
SQUARE, and
CURLY are. You can make them anything you want, like an enumeration, or whatever (just so long as you can use them on your
Stack). If you want to get tricky, you can make them
')',
']', and
'}', and you can just check to see that the top of the stack equals
line[ n ]
.
BTW. Don't hardcode ASCII codes. Use the keyboard.
Hence:
41
== bad
But:
')'
== good
Hope this helps.