Program: 39985
Project: 39985
Buggy source:
/** 
 * Parses single token starting at currentPosition Token is number or bracketed expression, possibly with single preceding minus
 * @param unaryOperationAllowed true if unary plus/minus is allowed as first symbol
 * @return value of token
 * @throws ParsingException invalid expression
 */
private double parseToken(boolean unaryOperationAllowed) throws ParsingException {
  if (currentPosition >= expression.length()) {
    throw new ParsingException("String_Node_Str");
  }
  double result;
  if (expression.charAt(currentPosition) == '(') {
    ++currentPosition;
    result=parseExpression();
    if (currentPosition >= expression.length() || expression.charAt(currentPosition) != ')') {
      throw new ParsingException("String_Node_Str");
    }
    ++currentPosition;
    return result;
  }
  if (!unaryOperationAllowed && (expression.charAt(currentPosition) == '-' || expression.charAt(currentPosition) == '+')) {
    throw new ParsingException("String_Node_Str");
  }
  if (expression.charAt(currentPosition) == '+' || expression.charAt(currentPosition) == '-') {
    if (currentPosition + 1 >= expression.length() || (expression.charAt(currentPosition + 1) != '(' && !Character.isDigit(expression.charAt(currentPosition + 1)))) {
      throw new ParsingException("String_Node_Str");
    }
  }
  if (expression.charAt(currentPosition) == '-') {
    ++currentPosition;
    result=parseToken(false);
    return -result;
  }
  if (expression.charAt(currentPosition) == '+') {
    result=parseToken(false);
    return result;
  }
  result=parseNumber();
  return result;
}

Fixed version (ground truth):
/** 
 * Parses single token starting at currentPosition Token is number or bracketed expression, possibly with single preceding minus
 * @param unaryOperationAllowed true if unary plus/minus is allowed as first symbol
 * @return value of token
 * @throws ParsingException invalid expression
 */
private double parseToken(boolean unaryOperationAllowed) throws ParsingException {
  if (currentPosition >= expression.length()) {
    throw new ParsingException("String_Node_Str");
  }
  double result;
  if (expression.charAt(currentPosition) == '(') {
    ++currentPosition;
    result=parseExpression();
    if (currentPosition >= expression.length() || expression.charAt(currentPosition) != ')') {
      throw new ParsingException("String_Node_Str");
    }
    ++currentPosition;
    return result;
  }
  if (!unaryOperationAllowed && (expression.charAt(currentPosition) == '-' || expression.charAt(currentPosition) == '+')) {
    throw new ParsingException("String_Node_Str");
  }
  if (expression.charAt(currentPosition) == '+' || expression.charAt(currentPosition) == '-') {
    if (currentPosition + 1 >= expression.length() || (expression.charAt(currentPosition + 1) != '(' && !Character.isDigit(expression.charAt(currentPosition + 1)))) {
      throw new ParsingException("String_Node_Str");
    }
  }
  if (expression.charAt(currentPosition) == '-') {
    ++currentPosition;
    result=parseToken(false);
    return -result;
  }
  if (expression.charAt(currentPosition) == '+') {
    ++currentPosition;
    result=parseToken(false);
    return result;
  }
  result=parseNumber();
  return result;
}