/** * Reads a factor from the current line of input and builds an expression tree that represents the * expression. * * @return an ExpNode which is a pointer to the root node of the expression tree * @throws ParseError if a syntax error is found in the input */ private static ExpNode factorTree() throws ParseError { TextIO.skipBlanks(); char ch = TextIO.peek(); if (Character.isDigit(ch)) { // The factor is a number. Return a ConstNode. double num = TextIO.getDouble(); return new ConstNode(num); } else if (ch == 'x' || ch == 'X') { // The factor is the variable x. TextIO.getAnyChar(); // Read the X. return new VariableNode(); } else if (ch == '(') { // The factor is an expression in parentheses. // Return a tree representing that expression. TextIO.getAnyChar(); // Read the "(" ExpNode exp = expressionTree(); TextIO.skipBlanks(); if (TextIO.peek() != ')') throw new ParseError("Missing right parenthesis."); TextIO.getAnyChar(); // Read the ")" return exp; } else if (ch == '\n') throw new ParseError("End-of-line encountered in the middle of an expression."); else if (ch == ')') throw new ParseError("Extra right parenthesis."); else if (ch == '+' || ch == '-' || ch == '*' || ch == '/') throw new ParseError("Misplaced operator."); else throw new ParseError("Unexpected character \"" + ch + "\" encountered."); } // end factorTree()
public static void main(String[] args) { while (true) { System.out.println("\n\nEnter an expression, or press return to end."); System.out.print("\n? "); TextIO.skipBlanks(); if (TextIO.peek() == '\n') break; try { ExpNode exp = expressionTree(); TextIO.skipBlanks(); if (TextIO.peek() != '\n') throw new ParseError("Extra data after end of expression."); TextIO.getln(); ExpNode deriv = exp.derivative(); System.out.println("\nA fully parenthesized expression for the derivative is:"); System.out.print(" "); deriv.printInfix(); System.out.println(); System.out.println("\nValue of derivative at x = 0 is " + deriv.value(0)); System.out.println("Value of derivative at x = 1 is " + deriv.value(1)); System.out.println("Value of derivative at x = 2 is " + deriv.value(2)); System.out.println("Value of derivative at x = 3 is " + deriv.value(3)); System.out.println("\nOrder of postfix evaluation for derivative is:\n"); deriv.printStackCommands(); } catch (ParseError e) { System.out.println("\n*** Error in input: " + e.getMessage()); System.out.println("*** Discarding input: " + TextIO.getln()); } } System.out.println("\n\nDone."); } // end main()
/** * Reads a term from the current line of input and builds an expression tree that represents the * expression. * * @return an ExpNode which is a pointer to the root node of the expression tree * @throws ParseError if a syntax error is found in the input */ private static ExpNode termTree() throws ParseError { TextIO.skipBlanks(); ExpNode term; // The expression tree representing the term. term = factorTree(); TextIO.skipBlanks(); while (TextIO.peek() == '*' || TextIO.peek() == '/') { // Read the next factor, and combine it with the // previous factors into a bigger expression tree. char op = TextIO.getAnyChar(); ExpNode nextFactor = factorTree(); term = new BinOpNode(op, term, nextFactor); TextIO.skipBlanks(); } return term; } // end termValue()
/** * Reads an expression from the current line of input and builds an expression tree that * represents the expression. * * @return an ExpNode which is a pointer to the root node of the expression tree * @throws ParseError if a syntax error is found in the input */ private static ExpNode expressionTree() throws ParseError { TextIO.skipBlanks(); boolean negative; // True if there is a leading minus sign. negative = false; if (TextIO.peek() == '-') { TextIO.getAnyChar(); negative = true; } ExpNode exp; // The expression tree for the expression. exp = termTree(); // Start with the first term. if (negative) exp = new UnaryMinusNode(exp); TextIO.skipBlanks(); while (TextIO.peek() == '+' || TextIO.peek() == '-') { // Read the next term and combine it with the // previous terms into a bigger expression tree. char op = TextIO.getAnyChar(); ExpNode nextTerm = termTree(); exp = new BinOpNode(op, exp, nextTerm); TextIO.skipBlanks(); } return exp; } // end expressionTree()