Troubleshooting Bracket Matching in Java StackADT Class

  • Thread starter Thread starter STEMucator
  • Start date Start date
Click For Summary

Discussion Overview

The discussion revolves around troubleshooting a bracket matching algorithm implemented in a Java StackADT class. Participants are examining issues related to exception handling and the correctness of the bracket matching logic within the context of evaluating boolean expressions.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Homework-related

Main Points Raised

  • One participant describes their implementation of a bracket matching algorithm and expresses confusion about exceptions not being thrown as expected.
  • Another participant suggests that the algorithm may fail with certain strings like "{)}", indicating a potential flaw in handling mismatched brackets.
  • A participant asserts that their code correctly handles the string "{)}" and shares an updated version of their bracket matching method that includes exception handling for various scenarios.
  • Concerns are raised about an error related to unreported exceptions in the context of exception handling in the evaluateExpression method.
  • One participant questions the logic of the bracket matching algorithm, suggesting that the stack's state should prevent errors when encountering mismatched brackets.
  • Another participant provides a code snippet to illustrate their approach to handling exceptions during the bracket validation process.

Areas of Agreement / Disagreement

Participants express differing views on the correctness of the bracket matching algorithm and its handling of exceptions. There is no consensus on whether the implementation is correct, as some participants believe it functions as intended while others raise concerns about specific cases.

Contextual Notes

Participants discuss various assumptions about the behavior of the stack and the handling of exceptions. The discussion highlights potential limitations in the implementation, such as the handling of nested brackets and the conditions under which exceptions are thrown.

STEMucator
Homework Helper
Messages
2,076
Reaction score
140

Homework Statement



I'm trying to create a program which evaluates boolean expressions consisting of ()[]{}XYZ'!| 01TF. Right now I'm working on a bracket matching algorithm that will determine if the brackets match in a given expression.

The problem I'm getting is it's telling me I'm not throwing the proper exceptions for some reason even though I'm pretty sure I am inside my matching brackets code.

Here's my code which concerns this from my StackADT<T> class which I manually wrote. I used an ArrayList as my store. Just the bracket code, constructors, top, pop and push methods are below :

Constructors :

Code:
	//Used to create a BOUNDED capacity stack
	public StackADT(int capacity){
		isBoundedCapacity = true;
	    boundedCapacity = Math.abs(capacity);
	    Operators = new ArrayList<T>(boundedCapacity);
	}
	
	//Used to create an UNBOUNDED capacity stack
	public StackADT(){
		isBoundedCapacity = false;
		boundedCapacity = StackProtocol.INITIAL_CAPACITY;
		Operators = new ArrayList<T>(boundedCapacity);
	}

Top, pop and push :

Code:
	@Override
	public T top() throws StackUnderflowException{
		if(isEmpty())
			throw new StackUnderflowException();
		return Operators.get(topOfStack);
	}

    @Override
    public T pop() throws StackUnderflowException {
    	if(isEmpty())
    		throw new StackUnderflowException();
    	return Operators.remove(topOfStack--);
    }
   
    @Override
    public void push(T item) throws BoundedCapacityOverFlowException {
    	if(size() == boundedCapacity) {
    		if(isBoundedCapacity())
    			throw new BoundedCapacityOverFlowException();
    		else {
    			boundedCapacity *= 2;
    			Operators.ensureCapacity(boundedCapacity); //Automatically increases the stack bound
    		}
    	}
    	topOfStack++;
    	Operators.add(item);
    }

Matching brackets code ( Located in another class ):

Code:
	public void validateMatchingBrackets() throws MissmatchedBracketsException  {
		StackADT<Character> operationStack = new StackADT<Character>();  //Empty unbounded stack

		for(int i=0; i<booleanExpression.length(); i++) { //Loop over the expression
			Character c = booleanExpression.charAt(i);
			
		    if((c == '(' || c == '{' || c == '[')) //If c is an open bracket
		    	operationStack.push(c); //Push it onto the stack
		    
			else if(c == ')' || c == '}' || c == ']') { //Else if c is a close bracket
				if(operationStack.isEmpty()) //First check if the stack is empty which means we have no match
					throw new MissmatchedBracketsException(); //Throw the exception
								
				if( (c == ')' && operationStack.top() == '(') //If the stack wasn't empty, find the match and pop
				|| (c == ']' && operationStack.top() == '[')
				|| (c == '}' && operationStack.top() == '{') )
			    	operationStack.pop();
			} 
		}
		
		if(!operationStack.isEmpty())  //After the loop, if the stack is not empty, then throw an exception
			throw new MissmatchedBracketsException();
	}

If anyone could help me pinpoint what's wrong with my bracket code it would be very helpful :).
 
Physics news on Phys.org
The problem I'm getting is it's telling me I'm not throwing the proper exceptions
Who/what is telling you that in which way?

I think your bracket matching algorithm gets problems with strings like "{)}" - it just ignores the ")".
 
mfb said:
Who/what is telling you that in which way?

I think your bracket matching algorithm gets problems with strings like "{)}" - it just ignores the ")".

No my code will not have problems with "{)}" I just tested it in my GUI.

Also, I switched my code up a bit :

Code:
	public void validateMatchingBrackets() throws MissmatchedBracketsException, 
												BoundedCapacityOverFlowException, 
												StackUnderflowException {
		
		StackADT<Character> operationStack = new StackADT<Character>();  //Empty unbounded stack

		for(int i=0; i<booleanExpression.length(); i++) { //Loop over the expression
			Character c = booleanExpression.charAt(i);
			
		    if((c == '(' || c == '{' || c == '['))
		    	operationStack.push(c);

		    else if(c == ')' || c == '}' || c == ']') { //Else if c is a close bracket
				if(operationStack.isEmpty()) //First check if the stack is empty which means we have no match
					throw new MissmatchedBracketsException(); //Throw the exception

				if((c == ')' && operationStack.top() == '(') //If the stack wasn't empty, find the match and pop
				|| (c == ']' && operationStack.top() == '[')
				|| (c == '}' && operationStack.top() == '{'))
					operationStack.pop();
			}
		}
		
		if(!operationStack.isEmpty())  //After the loop, if the stack is not empty, then throw an exception
			throw new MissmatchedBracketsException();
	}

Now my method will throw any over and underflows back to the method caller. My method caller is a method called evaluateExpression() :

Code:
	public void evaluateExpression() {
		//Perform necessary validation
		try{
			validateVariablesAndOperators();
			validateMatchingBrackets();
		}
		catch (BoundedCapacityOverFlowException e) {
			e.getMessage();
		} 
		catch (StackUnderflowException e) {
			e.getMessage();
		}
		catch(InvalidVariableOrOperatorException e){
		    booleanExpression = e.toString();
			results = new boolean[] {
					false, false, false, false,
					false, false, false, false
			};
			if(gui != null) 
				gui.updateGUI();
			return;
		}
		catch(MissmatchedBracketsException e){
			booleanExpression = e.toString();
			results = new boolean[] {
					false, false, false, false,
					false, false, false, false
			};
			
			if(gui != null) 
				gui.updateGUI();
			return;
		}

Now for some reason, I get an error :

unreported exception assignment2_2402.BoundedCapacityOverFlowException; must be caught or declared to be thrown
t.validateMatchingBrackets();

Which makes no sense since I'm throwing these exceptions and dealing with them?
 
Zondrina said:
No my code will not have problems with "{)}" I just tested it in my GUI.
I don't see how this gives an error (as it should).
The first "{" is recognized and put on the stack. For ")", the program enters the else if case, but does not do anything there, as the stack is not empty and stack.top gives "{" and c is ")".You should not get those error messages at all, unless you use a stack of fixed size and nest brackets too deep. Do you get them for all expressions? Did you check the state of the program just before it runs into errors? If you do not have a method to add breakpoints in your code to debug it, a lot of debug outputs should work as well.
 
mfb said:
I don't see how this gives an error (as it should).
The first "{" is recognized and put on the stack. For ")", the program enters the else if case, but does not do anything there, as the stack is not empty and stack.top gives "{" and c is ")".

Here's a snip :

Code:
		for(int i=0; i<booleanExpression.length(); i++) { //Loop over the expression
			Character c = booleanExpression.charAt(i);
		    if((c == '(' || c == '{' || c == '[')) {
		    	try{operationStack.push(c);}
		    	catch(BoundedCapacityOverFlowException e) {
					booleanExpression = e.toString();
					results = new boolean[] {
							false, false, false, false,
							false, false, false, false
					};
					
					if(gui != null) 
						gui.updateGUI();
					return;
		    	}
		    }
		    else if(c == ')' || c == '}' || c == ']') { //Else if c is a close bracket
		    	try {
				if(operationStack.isEmpty()) //First check if the stack is empty which means we have no match
					throw new MissmatchedBracketsException(); //Throw the exception
				
				if( ((c == ')') && (operationStack.top() == '(' )) //If the stack wasn't empty, find the match and pop
				||  ((c == ']') && (operationStack.top() == '['))
				||  ((c == '}') && (operationStack.top() == '{')) )
					operationStack.pop();
		    	}

I thought that for "{)}" :

i = 0 implies '{' is put into stack entry 0 by the if statement.

i = 1 implies we skip the if and go to the else if.

So in the else if, first we check if the stack is empty because if we found a close bracket before we found an open bracket ( aka the stack is empty ) then we just want to throw the exception right away.

The stack isn't empty, so it skips over to the next if which result in :

if( ((c == ')') && (operationStack.top() == '(' )) getting executed, but top returns '{' in this case. So nothing happens. Nothing will continue to happen as all the other ifs don''t happen.

So now... i = 2 implies ... oooh so the stack is going to wind up being cleared as we did nothing with the ')'. So to fix this ... I need to change my logic around. I see why I was wrong now. Instead of '==' I should really be saying '!=' and throw the exception if that does happen to occur.

Here's the completed code that wound up working according to the test server :

Code:
	public void validateVariablesAndOperators() throws InvalidVariableOrOperatorException {
		String validTokens = "XYZ&|'()[]{} 01TF";
        for(int i=0; i<booleanExpression.length(); i++){
			char c = booleanExpression.charAt(i);
			
		    if(!validTokens.contains(""+c)) 
		    	throw new InvalidVariableOrOperatorException();
		}
	}
	public void validateMatchingBrackets() throws MissmatchedBracketsException {
		
		StackADT<Character> operationStack = new StackADT<Character>();  //Empty unbounded stack

		for(int i=0; i<booleanExpression.length(); i++) { //Loop over the expression
			Character c = booleanExpression.charAt(i);
		    if((c == '(' || c == '{' || c == '[')) {
		    	try{operationStack.push(c);}
		    	catch(BoundedCapacityOverFlowException e) {
					booleanExpression = e.toString();
					results = new boolean[] {
							false, false, false, false,
							false, false, false, false
					};
					
					if(gui != null) 
						gui.updateGUI();
					return;
		    	}
		    }
		    else if(c == ')' || c == '}' || c == ']') { //Else if c is a close bracket
		    	try {
				if(operationStack.isEmpty()) //First check if the stack is empty which means we have no match
					throw new MissmatchedBracketsException(); //Throw the exception
				Character tempPop = operationStack.pop();
				if( ((c == ')') && (tempPop != '(' )) //If the stack wasn't empty, find the match and pop
				||  ((c == ']') && (tempPop != '['))
				||  ((c == '}') && (tempPop != '{')) )
					throw new MissmatchedBracketsException();
		    	}
		    	catch(StackUnderflowException e){
					booleanExpression = e.toString();
					results = new boolean[] {
							false, false, false, false,
							false, false, false, false
					};
					
					if(gui != null) 
						gui.updateGUI();
					return;
		    	}
		   }
	}	
		if(!operationStack.isEmpty())  //After the loop, if the stack is not empty, then throw an exception
			throw new MissmatchedBracketsException();
	}

Thanks a lot for your help :)
 

Similar threads

  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 16 ·
Replies
16
Views
5K
  • · Replies 3 ·
Replies
3
Views
3K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 1 ·
Replies
1
Views
4K
Replies
5
Views
3K
  • · Replies 4 ·
Replies
4
Views
2K