我正在开发一个初学者的java应用程序,它将中缀表达式转换为postfix,然后对它们进行评估。我花了很多时间来修复以下错误消息:
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
你能帮我解决这些错误吗?我一直在搞乱try / catch语句并移动SyntaxErrorException类,但我还没有运气。到目前为止,这是我的计划:
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");
}
}
}
提前感谢任何有用的提示或解决方案。
答案 0 :(得分:1)
错误告诉你有checked exception that you haven't handled。 “已检查”表示编译器强制您对其执行某些操作,并且您不能忽略它。您要么必须使用try / catch块捕获它,要么声明出现问题的方法会引发此异常。在这种情况下,您的main方法是调用convert()和eval(),两者都抛出SyntaxErrorException。这意味着你需要在convert()和eval()周围使用try / catch,否则main必须声明throws SyntaxErrorException
。
编辑:啊,我看得不够仔细。你的问题是你有两个不同的SyntaxErrorExceptions,虽然错误信息只给你简单的类名,这使得很难区分。你真的需要两个不同的例外吗?它们具有相同名称的事实意味着没有。无论如何,在您目前的情况下,您只需要确保处理两个例外。任
public static void main(String[] args) throws InfixToPostfix.SyntaxErrorException, PostfixEvaluator.SyntaxErrorException {
或
try {
String conversion = infix.convert(str);
System.out.println(postfix.eval(conversion));
} catch (InfixToPostfix.SyntaxErrorException e) {
...
} catch (PostfixEvaluator.SyntaxErrorException e) {
...
}