Unreported Exceptions from Interface Class Calls
<p>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:</p>

<pre><code>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
</code></pre>

<p>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:</p>

<p>Interface.java</p>

<pre><code>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:" );
            }
    }
}
</code></pre>

<p>InfixToPostfix.java</p>

<pre><code>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 &lt; Character &gt; 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 &lt; Character &gt; ();
    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) &gt; precedence(topOp)) {
        operatorStack.push(op);
      }
      else {
        // Pop all stacked operators with equal
        // or higher precedence than op.
        while (!operatorStack.empty()
               &amp;&amp; precedence(op) &lt;= 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 &gt;
        //         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)];
  }
}
</code></pre>

<p>PostfixEvaluator.java</p>

<pre><code>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 &lt; Integer &gt; 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 &lt; Integer &gt; ();

    // 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");
    }
  }
}
</code></pre>

<p>Thanks in advance for any useful hints or solutions.</p>
