Unreported Exceptions from Interface Class Calls
I'm working on a beginner's java app that converts infix expressions to postfix, then evaluates them. I've spent many hours trying to fix the following error messages:
Interface.java:21: error: unreported exception SyntaxErrorException; must be caught or declared to be thrown
String conversion = infix.convert(str);
^
Interface.java:22: error: unreported exception SyntaxErrorException; must be caught or declared to be thrown
System.out.println(postfix.eval(conversion));
^
2 errors
Can you please help me with these errors? I've been messing with try/catch statements and moving the SyntaxErrorException class, but I haven't had any luck yet. Here's my program so far:
Interface.java
import java.util.*;
/**
* Interface:
*/
class Interface {
/**
*
*/
public static void main( String [ ] args )
{
String str = "";
Scanner keyboard = new Scanner (System.in);
InfixToPostfix infix = new InfixToPostfix();
PostfixEvaluator postfix = new PostfixEvaluator();
System.out.println( "Enter expressions, one per line:" );
while( ( str = keyboard.next() ) != null )
{
System.out.println( "Read: " + str );
String conversion = infix.convert(str);
System.out.println(postfix.eval(conversion));
System.out.println( "Enter next expression:" );
}
}
}
InfixToPostfix.java
import java.util.*;
/**
* Translates an infix expression to a postfix expression.
*/
public class InfixToPostfix {
// Nested Class
/** Class to report a syntax error. */
public static class SyntaxErrorException
extends Exception {
/** Construct a SyntaxErrorException with the specified
message.
@param message The message
*/
SyntaxErrorException(String message) {
super(message);
}
}
// Data Fields
/** The operator stack */
private Stack < Character > operatorStack;
/** The operators */
private static final String OPERATORS = "+-*/";
/** The precedence of the operators, matches order in OPERATORS. */
private static final int[] PRECEDENCE = {
1, 1, 2, 2};
/** The postfix string */
private StringBuilder postfix;
/** Convert a string from infix to postfix.
@param infix The infix expression
@throws SyntaxErrorException
*/
public String convert(String infix) throws SyntaxErrorException {
operatorStack = new Stack < Character > ();
postfix = new StringBuilder();
StringTokenizer infixTokens = new StringTokenizer(infix);
try {
// Process each token in the infix string.
while (infixTokens.hasMoreTokens()) {
String nextToken = infixTokens.nextToken();
char firstChar = nextToken.charAt(0);
// Is it an operand?
if (Character.isJavaIdentifierStart(firstChar)
|| Character.isDigit(firstChar)) {
postfix.append(nextToken);
postfix.append(' ');
} // Is it an operator?
else if (isOperator(firstChar)) {
processOperator(firstChar);
}
else {
throw new SyntaxErrorException
("Unexpected Character Encountered: "
+ firstChar);
}
} // End while.
// Pop any remaining operators and
// append them to postfix.
while (!operatorStack.empty()) {
char op = operatorStack.pop();
postfix.append(op);
postfix.append(' ');
}
// assert: Stack is empty, return result.
return postfix.toString();
}
catch (EmptyStackException ex) {
throw new SyntaxErrorException
("Syntax Error: The stack is empty");
}
}
/** Method to process operators.
@param op The operator
@throws EmptyStackException
*/
private void processOperator(char op) {
if (operatorStack.empty()) {
operatorStack.push(op);
}
else {
// Peek the operator stack and
// let topOp be top operator.
char topOp = operatorStack.peek();
if (precedence(op) > precedence(topOp)) {
operatorStack.push(op);
}
else {
// Pop all stacked operators with equal
// or higher precedence than op.
while (!operatorStack.empty()
&& precedence(op) <= precedence(topOp)) {
operatorStack.pop();
postfix.append(topOp);
postfix.append(' ');
if (!operatorStack.empty()) {
// Reset topOp.
topOp = operatorStack.peek();
}
}
// assert: Operator stack is empty or
// current operator precedence >
// top of stack operator precedence.
operatorStack.push(op);
}
}
}
/** Determine whether a character is an operator.
@param ch The character to be tested
@return true if ch is an operator
*/
private boolean isOperator(char ch) {
return OPERATORS.indexOf(ch) != -1;
}
/** Determine the precedence of an operator.
@param op The operator
@return the precedence
*/
private int precedence(char op) {
return PRECEDENCE[OPERATORS.indexOf(op)];
}
}
PostfixEvaluator.java
import java.util.*;
/**
* Class that can evaluate a postfix expression.
* */
public class PostfixEvaluator {
// Nested Class
/** Class to report a syntax error. */
public static class SyntaxErrorException
extends Exception {
/** Construct a SyntaxErrorException with the specified
message.
@param message The message
*/
SyntaxErrorException(String message) {
super(message);
}
}
// Constant
/** A list of operators. */
private static final String OPERATORS = "+-*/";
// Data Field
/** The operand stack. */
private Stack < Integer > operandStack;
// Methods
/** Evaluates the current operation.
This function pops the two operands off the operand
stack and applies the operator.
@param op A character representing the operator
@return The result of applying the operator
@throws EmptyStackException if pop is attempted on
an empty stack
*/
private int evalOp(char op) {
// Pop the two operands off the stack.
int rhs = operandStack.pop();
int lhs = operandStack.pop();
int result = 0;
// Evaluate the operator.
switch (op) {
case '+':
result = lhs + rhs;
break;
case '-':
result = lhs - rhs;
break;
case '/':
result = lhs / rhs;
break;
case '*':
result = lhs * rhs;
break;
}
return result;
}
/** Determines whether a character is an operator.
@param op The character to be tested
@return true if the character is an operator
*/
private boolean isOperator(char ch) {
return OPERATORS.indexOf(ch) != -1;
}
/** Evaluates a postfix expression.
@param expression The expression to be evaluated
@return The value of the expression
@throws SyntaxErrorException if a syntax error is detected
*/
public int eval(String expression) throws SyntaxErrorException {
// Create an empty stack.
operandStack = new Stack < Integer > ();
// Process each token.
StringTokenizer tokens = new StringTokenizer(expression);
try {
while (tokens.hasMoreTokens()) {
String nextToken = tokens.nextToken();
// Does it start with a digit?
if (Character.isDigit(nextToken.charAt(0))) {
// Get the integer value.
int value = Integer.parseInt(nextToken);
// Push value onto operand stack.
operandStack.push(value);
} // Is it an operator?
else if (isOperator(nextToken.charAt(0))) {
// Evaluate the operator.
int result = evalOp(nextToken.charAt(0));
// Push result onto the operand stack.
operandStack.push(result);
}
else {
// Invalid character.
throw new SyntaxErrorException(
"Invalid character encountered");
}
} // End while.
// No more tokens - pop result from operand stack.
int answer = operandStack.pop();
// Operand stack should be empty.
if (operandStack.empty()) {
return answer;
}
else {
// Indicate syntax error.
throw new SyntaxErrorException(
"Syntax Error: Stack should be empty");
}
}
catch (EmptyStackException ex) {
// Pop was开发者_高级运维 attempted on an empty stack.
throw new SyntaxErrorException(
"Syntax Error: The stack is empty");
}
}
}
Thanks in advance for any useful hints or solutions.
The errors are telling you there's a checked exception that you haven't handled. "Checked" means that the compiler forces you to do something with it and that you can't just ignore it. You either have to catch it using a try/catch block or declare that the method where the problem occurs throws this exception. In this case, your main method is calling convert() and eval(), both of which throw SyntaxErrorException. That means you need a try/catch in main around the convert() and eval() or else main has to declare throws SyntaxErrorException
.
Edit: Ah, I didn't look closely enough. Your problem is that you have two different SyntaxErrorExceptions, though the error message is giving you only the simple class name, making it hard to distinguish. Do you really need two different exceptions? The fact that they have identical names implies not. Anyway, in your current situation, you just need to make sure to handle both exceptions. Either
public static void main(String[] args) throws InfixToPostfix.SyntaxErrorException, PostfixEvaluator.SyntaxErrorException {
or
try {
String conversion = infix.convert(str);
System.out.println(postfix.eval(conversion));
} catch (InfixToPostfix.SyntaxErrorException e) {
...
} catch (PostfixEvaluator.SyntaxErrorException e) {
...
}
精彩评论