示例#1
0
  /**
   * Parses and returns a valid 'leftside' of an expression. If the left side starts with a prefix,
   * it consumes other expressions with a lower priority than itself. If the left side does not have
   * a prefix it must be an expr0.
   *
   * @param commaIsEndMarker used when the leftside is part of and argument list of expressions
   * @param maxPriority operators with a higher priority than this will effectivly end the
   *     expression
   * @return a wrapper of: 1. term correctly structured and 2. the priority of its root operator
   * @throws InvalidTermException
   */
  private IdentifiedTerm parseLeftSide(boolean commaIsEndMarker, int maxPriority)
      throws InvalidTermException, IOException {
    // 1. prefix expression
    Token f = tokenizer.readToken();
    if (f.isOperator(commaIsEndMarker)) {
      int FX = opManager.opPrio(f.seq, "fx");
      int FY = opManager.opPrio(f.seq, "fy");

      if (f.seq.equals("-")) {
        Token t = tokenizer.readToken();
        if (t.isNumber())
          /*Michele Castagna 06/2011*/
          // return new IdentifiedTerm(0, Parser.createNumber("-" + t.seq));
          return identifyTerm(0, Parser.createNumber("-" + t.seq), tokenStart);
        /**/
        else tokenizer.unreadToken(t);
      }

      // check that no operator has a priority higher than permitted
      if (FY > maxPriority) FY = -1;
      if (FX > maxPriority) FX = -1;

      // FX has priority over FY
      boolean haveAttemptedFX = false;
      if (FX >= FY && FX >= OperatorManager.OP_LOW) {
        IdentifiedTerm found = exprA(FX - 1, commaIsEndMarker); // op(fx, n) exprA(n - 1)
        if (found != null)
          /*Castagna 06/2011*/
          // return new IdentifiedTerm(FX, new Struct(f.seq, found.result));
          return identifyTerm(FX, new Struct(f.seq, found.result), tokenStart);
        /**/
        else haveAttemptedFX = true;
      }
      // FY has priority over FX, or FX has failed
      if (FY >= OperatorManager.OP_LOW) {
        IdentifiedTerm found =
            exprA(FY, commaIsEndMarker); // op(fy,n) exprA(1200)  or   op(fy,n) exprA(n)
        if (found != null)
          /*Castagna 06/2011*/
          // return new IdentifiedTerm(FY, new Struct(f.seq, found.result));
          return identifyTerm(FY, new Struct(f.seq, found.result), tokenStart);
        /**/
      }
      // FY has priority over FX, but FY failed
      if (!haveAttemptedFX && FX >= OperatorManager.OP_LOW) {
        IdentifiedTerm found = exprA(FX - 1, commaIsEndMarker); // op(fx, n) exprA(n - 1)
        if (found != null)
          /*Castagna 06/2011*/
          // return new IdentifiedTerm(FX, new Struct(f.seq, found.result));
          return identifyTerm(FX, new Struct(f.seq, found.result), tokenStart);
        /**/
      }
    }
    tokenizer.unreadToken(f);
    // 2. expr0
    return new IdentifiedTerm(0, expr0());
  }