Beispiel #1
0
  /**
   * Evaluates a PostfixMathCommandI with given arguments. Not used in normal use.
   *
   * @param pfmc the command to evaluate.
   * @param children the parameters to the function.
   * @return the value of the function
   * @throws ParseException
   */
  public Object eval(PostfixMathCommandI pfmc, Node children[]) throws ParseException {
    if (pfmc instanceof SpecialEvaluationI) {
      ASTFunNode node = new ASTFunNode(ParserTreeConstants.JJTFUNNODE);
      node.setFunction("TmpFun", pfmc);
      node.jjtOpen();
      for (int i = 0; i < children.length; ++i) {
        node.jjtAddChild(children[i], i);
      }
      node.jjtClose();
      return ((SpecialEvaluationI) pfmc).evaluate(node, null, this, new Stack(), this.symTab);
    }
    if (pfmc instanceof CallbackEvaluationI) {
      ASTFunNode node = new ASTFunNode(ParserTreeConstants.JJTFUNNODE);
      node.setFunction("TmpFun", pfmc);
      node.jjtOpen();
      for (int i = 0; i < children.length; ++i) {
        node.jjtAddChild(children[i], i);
      }
      node.jjtClose();
      Object val = ((CallbackEvaluationI) pfmc).evaluate(node, this);
      return val;
    }

    Stack lstack = new Stack();
    for (int i = 0; i < children.length; ++i) {
      if (!(children[i] instanceof ASTConstant))
        throw new ParseException("buildConstantNode: arguments must all be constant nodes");
      lstack.push(((ASTConstant) children[i]).getValue());
    }
    pfmc.setCurNumberOfParameters(children.length);
    pfmc.run(lstack);
    return lstack.pop();
  }
Beispiel #2
0
  /**
   * Visit a function node. The values of the child nodes are first pushed onto the stack. Then the
   * function class associated with the node is used to evaluate the function.
   *
   * <p>If a function implements SpecialEvaluationI then the evaluate method of PFMC is called.
   */
  public Object visit(ASTFunNode node, Object data) throws ParseException {

    if (node == null) return null;
    PostfixMathCommandI pfmc = node.getPFMC();

    // check if the function class is set
    if (pfmc == null)
      throw new ParseException("No function class associated with " + node.getName());

    // Some operators (=) need a special method for evaluation
    // as the pfmc.run method does not have enough information
    // in such cases we call the evaluate method which passes
    // all available info. Note evaluating the children is
    // the responsibility of the evaluate method.
    if (pfmc instanceof SpecialEvaluationI) {
      return ((SpecialEvaluationI) pfmc).evaluate(node, data, this, stack, this.symTab);
    }
    if (pfmc instanceof CallbackEvaluationI) {
      Object val = ((CallbackEvaluationI) pfmc).evaluate(node, this);
      stack.push(val);
      return val;
    }
    if (debug == true) {
      System.out.println("Stack size before childrenAccept: " + stack.size());
    }

    // evaluate all children (each leaves their result on the stack)

    data = node.childrenAccept(this, data);

    if (debug == true) {
      System.out.println("Stack size after childrenAccept: " + stack.size());
    }

    if (pfmc.getNumberOfParameters() == -1) {
      // need to tell the class how many parameters it can take off
      // the stack because it accepts a variable number of params
      pfmc.setCurNumberOfParameters(node.jjtGetNumChildren());
    }

    // try to run the function

    pfmc.run(stack);

    if (debug == true) {
      System.out.println("Stack size after run: " + stack.size());
    }

    return data;
  }
Beispiel #3
0
  /**
   * Returns the value of the expression as an object. The expression tree is specified with its top
   * node. The algorithm uses a stack for evaluation.
   *
   * <p>The symTab parameter can be null, if no variables are expected in the expression. If a
   * variable is found, an error is added to the error list.
   *
   * <p>An exception is thrown, if an error occurs during evaluation.
   *
   * @return The value of the expression as an object.
   * @throws ParseException if there is a problem with the evaluation.
   */
  public Object getValue(Node topNode, SymbolTable symTab_in) throws ParseException {

    // check if arguments are ok
    if (topNode == null) {
      throw new ParseException("topNode parameter is null");
    }

    // set member vars
    // errorList = errorList_in;
    symTab = symTab_in;
    // System.out.println("Evaluating expression " + topNode.toLongString() + " with symTab: " +
    // symTab);
    // errorFlag = false;
    stack.removeAllElements();
    // rjm addition ensure stack is correct before beginning.
    // njf changed from clear() to removeAllElements for 1.1 compatibility

    // evaluate by letting the top node accept the visitor
    topNode.jjtAccept(this, null);
    /*
    } catch (ParseException e) {
    this.addToErrorList("Error: "+e.getMessage());
    return null;
    }
    if(errorFlag) return null;
     */

    // something is wrong if not exactly one item remains on the stack
    // or if the error flag has been set
    if (stack.size() != 1) {
      throw new ParseException("Stack corrupted");
    }

    // return the value of the expression
    return stack.pop();
  }
Beispiel #4
0
  /**
   * Visit a variable node. The value of the variable is obtained from the symbol table (symTab) and
   * pushed onto the stack.
   */
  public Object visit(ASTVarNode node, Object data) throws ParseException {

    // try to get the variable object
    Variable var = symTab.getVar(node.getVarName());
    if (var == null) {
      String message = "Could not evaluate " + node.getVarName() + ": ";
      throw new ParseException(message + "the variable was not found in the symbol table");
    }

    // get the variable value
    // Object temp = var.getValue();
    Object temp = var.getValue();

    if (trapNullValues && temp == null) {
      String message = "Could not evaluate " + node.getVarName() + ": ";
      throw new ParseException(message + "variable not set");
    }
    // all is fine
    // push the value on the stack
    stack.push(temp);
    return data;
  }
Beispiel #5
0
 /** Visit a constant node. The value of the constant is pushed onto the stack. */
 public Object visit(ASTConstant node, Object data) {
   stack.push(node.getValue());
   return data;
 }
Beispiel #6
0
 /**
  * Evaluates a given node, in the current context.
  *
  * @param node The node to evaluate
  * @return result of the evaluation
  */
 public Object eval(Node node) throws ParseException {
   node.jjtAccept(this, null);
   return stack.pop();
 }