Package org.mvel2

Examples of org.mvel2.CompileException


  public Object getReducedValue(Object ctx, Object thisValue, VariableResolverFactory factory) {
    PrototypalFunctionInstance instance = new PrototypalFunctionInstance(this, new MapVariableResolverFactory());
    if (name != null) {
      if (!factory.isIndexedFactory() && factory.isResolveable(name))
        throw new CompileException("duplicate function: " + name, expr, start);
      factory.createVariable(name, instance);
    }
    return instance;
  }
View Full Code Here


    return this.parameters != null && this.parameters.length != 0;
  }

  public void checkArgumentCount(int passing) {
    if (passing != parmNum) {
      throw new CompileException("bad number of arguments in function call: "
          + passing + " (expected: " + (parmNum == 0 ? "none" : parmNum) + ")", expr, start);
    }
  }
View Full Code Here

    }
  }

  public Object getReducedValueAccelerated(Object ctx, Object thisValue, VariableResolverFactory factory) {
    Object ctxObject = compiledBlock.getValue(ctx, thisValue, factory);
    if (ctxObject == null) throw new CompileException("with-block against null pointer", expr, start);

    for (ParmValuePair pvp : withExpressions) {
      pvp.eval(ctxObject, factory);
    }
View Full Code Here

            oper = -1;
            _st = ++i;
          }
          else {
            if (nestParm == null) {
              throw new CompileException("operative assignment not possible here", block, start);
            }

            try {
              parms.add(new ParmValuePair(
                  parm,
                  oper != -1 ?
                      (ExecutableStatement) subCompileExpression(
                          createShortFormOperativeAssignment(nestParm + "." + parm,
                              block, _st, _end - _st, oper), pCtx)
                      //or
                      : (ExecutableStatement) subCompileExpression(block, _st, _end - _st, pCtx)
                  , egressType, pCtx));
            }
            catch (CompileException e) {
              e.setCursor(_st + (e.getCursor() - (e.getExpr().length - offset)));
              e.setExpr(block);
              throw e;
            }

            parm = null;
            oper = -1;
            _st = ++i;
          }

          _end = -1;

          break;
      }
    }

    if (_st != (_end = end)) {
      try {
        if (parm == null || "".equals(parm)) {
          String expr;
          if (nestParm == null) {
            expr = new String(block, _st, _end - _st);
          }
          else {
            expr = new StringBuilder(nestParm).append('.')
                .append(new String(block, _st, _end - _st)).toString();
          }

          parms.add(
              new ParmValuePair(null, (ExecutableStatement)
                  subCompileExpression(expr, pCtx),
                      egressType, pCtx)
          );
        }
        else {
          if (nestParm == null) {
            throw new CompileException("operative assignment not possible here", block, start);
          }

          parms.add(new ParmValuePair(
              parm,
              oper != -1 ?
View Full Code Here

        v = compiledBlock.getValue(ctx, thisValue, itemFactory);
        if (itemFactory.tiltFlag()) return v;
      }
    }
    else {
      throw new CompileException("non-iterable type: "
          + (iterCond != null ? iterCond.getClass().getName() : "null"), expr, start);
    }

    return null;
  }
View Full Code Here

    int cursor = start;
    int end = start + offset;
    while (cursor < end && condition[cursor] != ':') cursor++;

    if (cursor == end || condition[cursor] != ':')
      throw new CompileException("expected : in foreach", condition, cursor);

    int x;
    if ((x = (item = createStringTrimmed(condition, start, cursor - start)).indexOf(' ')) != -1) {
      String tk = new String(condition, start, x).trim();
      try {
        itemType = ParseTools.findClass(null, tk, pCtx);
        item = new String(condition, start + x, (cursor - start) - x).trim();

      }
      catch (ClassNotFoundException e) {
        throw new CompileException("cannot resolve identifier: " + tk, condition, start);
      }
    }

    // this.start = ++cursor;
View Full Code Here

    }
    else if (Integer.class.isAssignableFrom(t)) {
      type = INTEGER;
    }
    else {
      throw new CompileException("non-iterable type: " + t.getName(), expr, start);
    }
  }
View Full Code Here

          items.add(ParseTools.createStringTrimmed(contents, start, i - start));
          start = i + 1;
          break;
        case ',':
          if (expr.size() != (items.size() - 1)) {
            throw new CompileException("unexpected character ',' in foreach tag", contents, cStart + i);
          }
          expr.add(ParseTools.createStringTrimmed(contents, start, i - start));
          start = i + 1;
          break;
      }
    }

    if (start < cEnd) {
      if (expr.size() != (items.size() - 1)) {
        throw new CompileException("expected character ':' in foreach tag", contents, cEnd);
      }
      expr.add(ParseTools.createStringTrimmed(contents, start, cEnd - start));
    }

    item = new String[items.size()];
View Full Code Here

    else if (Float.class.isAssignableFrom(type)) signer = new FloatSigner();
    else if (Short.class.isAssignableFrom(type)) signer = new ShortSigner();
    else if (BigInteger.class.isAssignableFrom(type)) signer = new BigIntSigner();
    else if (BigDecimal.class.isAssignableFrom(type)) signer = new BigDecSigner();
    else {
      throw new CompileException("illegal use of '-': cannot be applied to: " + type.getName(), expr, start);
    }

  }
View Full Code Here

      }

      if (debugSymbols) {
        if (!lastWasLineLabel) {
          if (pCtx.getSourceFile() == null) {
            throw new CompileException("unable to produce debugging symbols: source name must be provided.", expr, st);
          }

          if (!pCtx.isLineMapped(pCtx.getSourceFile())) {
            pCtx.initLineMapping(pCtx.getSourceFile(), expr);
          }

          skipWhitespace();

          if (cursor >= end) {
            return null;
          }

          int line = pCtx.getLineFor(pCtx.getSourceFile(), cursor);

          if (!pCtx.isVisitedLine(pCtx.getSourceFile(), pCtx.setLineCount(line)) && !pCtx.isBlockSymbols()) {
            lastWasLineLabel = true;
            pCtx.visitLine(pCtx.getSourceFile(), line);

            return lastNode = pCtx.setLastLineLabel(new LineLabel(pCtx.getSourceFile(), line, pCtx));
          }
        }
        else {
          lastWasComment = lastWasLineLabel = false;
        }
      }

      /**
       * Skip any whitespace currently under the starting point.
       */
      skipWhitespace();

      /**
       * From here to the end of the method is the core MVEL parsing code.  Fiddling around here is asking for
       * trouble unless you really know what you're doing.
       */

      st = cursor;

      Mainloop:
      while (cursor != end) {
        if (isIdentifierPart(expr[cursor])) {
          capture = true;
          cursor++;

          while (cursor != end && isIdentifierPart(expr[cursor])) cursor++;
        }

        /**
         * If the current character under the cursor is a valid
         * part of an identifier, we keep capturing.
         */

        if (capture) {
          String t;
          if (OPERATORS.containsKey(t = new String(expr, st, cursor - st)) && !Character.isDigit(expr[st])) {
            switch (OPERATORS.get(t)) {
              case NEW:
                if (!isIdentifierPart(expr[st = cursor = trimRight(cursor)])) {
                  throw new CompileException("unexpected character (expected identifier): "
                      + expr[cursor], expr, st);
                }

                /**
                 * Capture the beginning part of the token.
                 */
                do {
                  captureToNextTokenJunction();
                  skipWhitespace();
                }
                while (cursor < end && expr[cursor] == '[');

                /**
                 * If it's not a dimentioned array, continue capturing if necessary.
                 */
                if (cursor < end && !lastNonWhite(']')) captureToEOT();

                TypeDescriptor descr = new TypeDescriptor(expr, st, trimLeft(cursor) - st, fields);

                if (pCtx == null) pCtx = getParserContext();

                if (pCtx.getFunctions().containsKey(descr.getClassName())) {
                  return lastNode = new NewObjectPrototype(pCtx, pCtx.getFunction(descr.getClassName()));
                }

                if (pCtx.hasProtoImport(descr.getClassName())) {
                  return lastNode = new NewPrototypeNode(descr, pCtx);
                }


                lastNode = new NewObjectNode(descr, fields, pCtx);

                skipWhitespace();
                if (cursor != end && expr[cursor] == '{') {
                  if (!((NewObjectNode) lastNode).getTypeDescr().isUndimensionedArray()) {
                    throw new CompileException(
                        "conflicting syntax: dimensioned array with initializer block",
                        expr, st);
                  }

                  st = cursor;
                  Class egressType = lastNode.getEgressType();

                  if (egressType == null) {
                    try {
                      egressType = getClassReference(pCtx, descr);
                    }
                    catch (ClassNotFoundException e) {
                      throw new CompileException("could not instantiate class", expr, st, e);
                    }
                  }


                  cursor = balancedCaptureWithLineAccounting(expr, st, end, expr[cursor], pCtx) + 1;
                  if (tokenContinues()) {
                    lastNode = new InlineCollectionNode(expr, st, cursor - st, fields,
                        egressType, pCtx);
                    st = cursor;
                    captureToEOT();
                    return lastNode = new Union(expr, st + 1, cursor, fields, lastNode, pCtx);
                  }
                  else {
                    return lastNode = new InlineCollectionNode(expr, st, cursor - st, fields,
                        egressType, pCtx);
                  }
                }
                else if (((NewObjectNode) lastNode).getTypeDescr().isUndimensionedArray()) {
                  throw new CompileException("array initializer expected", expr, st);
                }
                st = cursor;

                return lastNode;

              case ASSERT:
                st = cursor = trimRight(cursor);
                captureToEOS();
                return lastNode = new AssertNode(expr, st, cursor-- - st, fields, pCtx);

              case RETURN:
                st = cursor = trimRight(cursor);
                captureToEOS();
                return lastNode = new ReturnNode(expr, st, cursor - st, fields, pCtx);

              case IF:
                return captureCodeBlock(ASTNode.BLOCK_IF);

              case ELSE:
                throw new CompileException("else without if", expr, st);

              case FOREACH:
                return captureCodeBlock(ASTNode.BLOCK_FOREACH);

              case WHILE:
                return captureCodeBlock(ASTNode.BLOCK_WHILE);

              case UNTIL:
                return captureCodeBlock(ASTNode.BLOCK_UNTIL);

              case FOR:
                return captureCodeBlock(ASTNode.BLOCK_FOR);

              case WITH:
                return captureCodeBlock(ASTNode.BLOCK_WITH);

              case DO:
                return captureCodeBlock(ASTNode.BLOCK_DO);

              case STACKLANG:
                return captureCodeBlock(STACKLANG);

              case PROTO:
                return captureCodeBlock(PROTO);

              case ISDEF:
                st = cursor = trimRight(cursor);
                captureToNextTokenJunction();
                return lastNode = new IsDef(expr, st, cursor - st, pCtx);

              case IMPORT:
                st = cursor = trimRight(cursor);
                captureToEOS();
                ImportNode importNode = new ImportNode(expr, st, cursor - st, pCtx);

                if (pCtx == null) pCtx = getParserContext();

                if (importNode.isPackageImport()) {
                  pCtx.addPackageImport(importNode.getPackageImport());
                }
                else {
                  pCtx.addImport(importNode.getImportClass().getSimpleName(), importNode.getImportClass());
                }
                return lastNode = importNode;

              case IMPORT_STATIC:
                st = cursor = trimRight(cursor);
                captureToEOS();
                StaticImportNode staticImportNode = new StaticImportNode(expr, st, trimLeft(cursor) - st, pCtx);
                if (pCtx == null) pCtx = getParserContext();
                pCtx.addImport(staticImportNode.getMethod().getName(), staticImportNode.getMethod());
                return lastNode = staticImportNode;

              case FUNCTION:
                lastNode = captureCodeBlock(FUNCTION);
                st = cursor + 1;
                return lastNode;

              case UNTYPED_VAR:
                int end;
                st = cursor + 1;

                while (true) {
                  captureToEOT();
                  end = cursor;
                  skipWhitespace();

                  if (cursor != end && expr[cursor] == '=') {
                    if (end == (cursor = st))
                      throw new CompileException("illegal use of reserved word: var", expr, st);

                    continue Mainloop;
                  }
                  else {
                    name = new String(expr, st, end - st);
                    if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                      splitAccumulator.add(lastNode = new IndexedDeclTypedVarNode(idx, st, end - st, Object.class, pCtx));
                    }
                    else {
                      splitAccumulator.add(lastNode = new DeclTypedVarNode(name, expr, st, end - st, Object.class,
                          fields, pCtx));
                    }
                  }

                  if (cursor == this.end || expr[cursor] != ',') break;
                  else {
                    cursor++;
                    skipWhitespace();
                    st = cursor;
                  }
                }

                return (ASTNode) splitAccumulator.pop();

              case CONTAINS:
                lastWasIdentifier = false;
                return lastNode = new OperatorNode(Operator.CONTAINS, expr, st, pCtx);

            }
          }

          skipWhitespace();

          /**
           * If we *were* capturing a token, and we just hit a non-identifier
           * character, we stop and figure out what to do.
           */
          if (cursor != end && expr[cursor] == '(') {
            cursor = balancedCaptureWithLineAccounting(expr, cursor, end, '(', pCtx) + 1;
          }

          /**
           * If we encounter any of the following cases, we are still dealing with
           * a contiguous token.
           */
          CaptureLoop:
          while (cursor != end) {
            switch (expr[cursor]) {
              case '.':
                union = true;
                cursor++;
                skipWhitespace();

                continue;

              case '?':
                if (lookToLast() == '.' || cursor == start) {
                  union = true;
                  cursor++;
                  continue;
                }
                else {
                  break CaptureLoop;
                }

              case '+':
                switch (lookAhead()) {
                  case '+':
                    name = new String(subArray(st, trimLeft(cursor)));
                    if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                      lastNode = new IndexedPostFixIncNode(idx, pCtx);
                    }
                    else {
                      lastNode = new PostFixIncNode(name, pCtx);
                    }

                    cursor += 2;

                    expectEOS();

                    return lastNode;

                  case '=':
                    name = createStringTrimmed(expr, st, cursor - st);
                    st = cursor += 2;

                    captureToEOS();

                    if (union) {
                      return lastNode = new DeepAssignmentNode(expr, st = trimRight(st), trimLeft(cursor) - st, fields,
                          ADD, name, pCtx);
                    }
                    else if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                      return lastNode = new IndexedAssignmentNode(expr, st, cursor - st, fields,
                          ADD, name, idx, pCtx);
                    }
                    else {
                      return lastNode = new OperativeAssign(name, expr, st = trimRight(st), trimLeft(cursor) - st,
                          ADD, fields, pCtx);
                    }
                }

                if (isDigit(lookAhead()) &&
                    cursor > 1 && (expr[cursor - 1] == 'E' || expr[cursor - 1] == 'e')
                    && isDigit(expr[cursor - 2])) {
                  cursor++;
                  //     capture = true;
                  continue Mainloop;
                }
                break CaptureLoop;

              case '-':
                switch (lookAhead()) {
                  case '-':
                    name = new String(subArray(st, trimLeft(cursor)));
                    if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                      lastNode = new IndexedPostFixDecNode(idx, pCtx);
                    }
                    else {
                      lastNode = new PostFixDecNode(name, pCtx);
                    }
                    cursor += 2;

                    expectEOS();

                    return lastNode;

                  case '=':
                    name = new String(expr, st, trimLeft(cursor) - st);
                    st = cursor += 2;

                    captureToEOS();

                    if (union) {
                      return lastNode = new DeepAssignmentNode(expr, st, cursor - st, fields,
                          SUB, t, pCtx);
                    }
                    else if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                      return lastNode = new IndexedOperativeAssign(expr, st, cursor - st,
                          SUB, idx, fields, pCtx);
                    }
                    else {
                      return lastNode = new OperativeAssign(name, expr, st, cursor - st,
                          SUB, fields, pCtx);
                    }
                }

                if (isDigit(lookAhead()) &&
                    cursor > 1 && (expr[cursor - 1] == 'E' || expr[cursor - 1] == 'e')
                    && isDigit(expr[cursor - 2])) {
                  cursor++;
                  capture = true;
                  continue Mainloop;
                }
                break CaptureLoop;

              /**
               * Exit immediately for any of these cases.
               */
              case '!':
              case ',':
              case '"':
              case '\'':
              case ';':
              case ':':
                break CaptureLoop;

              case '\u00AB': // special compact code for recursive parses
              case '\u00BB':
              case '\u00AC':
              case '&':
              case '^':
              case '|':
              case '*':
              case '/':
              case '%':
                char op = expr[cursor];
                if (lookAhead() == '=') {
                  name = new String(expr, st, trimLeft(cursor) - st);

                  st = cursor += 2;
                  captureToEOS();

                  if (union) {
                    return lastNode = new DeepAssignmentNode(expr, st, cursor - st, fields,
                        opLookup(op), t, pCtx);
                  }
                  else if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                    return lastNode = new IndexedOperativeAssign(expr, st, cursor - st,
                        opLookup(op), idx, fields, pCtx);
                  }
                  else {
                    return lastNode = new OperativeAssign(name, expr, st, cursor - st,
                        opLookup(op), fields, pCtx);
                  }
                }
                break CaptureLoop;

              case '<':
                if ((lookAhead() == '<' && lookAhead(2) == '=')) {
                  name = new String(expr, st, trimLeft(cursor) - st);

                  st = cursor += 3;
                  captureToEOS();

                  if (union) {
                    return lastNode = new DeepAssignmentNode(expr, st, cursor - st, fields,
                        BW_SHIFT_LEFT, t, pCtx);
                  }
                  else if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                    return lastNode = new IndexedOperativeAssign(expr, st, cursor - st,
                        BW_SHIFT_LEFT, idx, fields, pCtx);
                  }
                  else {
                    return lastNode = new OperativeAssign(name, expr, st, cursor - st,
                        BW_SHIFT_LEFT, fields, pCtx);
                  }
                }
                break CaptureLoop;

              case '>':
                if (lookAhead() == '>') {
                  if (lookAhead(2) == '=') {
                    name = new String(expr, st, trimLeft(cursor) - st);

                    st = cursor += 3;
                    captureToEOS();

                    if (union) {
                      return lastNode = new DeepAssignmentNode(expr, st, cursor - st, fields,
                          BW_SHIFT_RIGHT, t, pCtx);
                    }
                    else if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                      return lastNode = new IndexedOperativeAssign(expr, st, cursor - st,
                          BW_SHIFT_RIGHT, idx, fields, pCtx);
                    }
                    else {
                      return lastNode = new OperativeAssign(name, expr, st, cursor - st,
                          BW_SHIFT_RIGHT, fields, pCtx);
                    }
                  }
                  else if ((lookAhead(2) == '>' && lookAhead(3) == '=')) {
                    name = new String(expr, st, trimLeft(cursor) - st);

                    st = cursor += 4;
                    captureToEOS();

                    if (union) {
                      return lastNode = new DeepAssignmentNode(expr, st, cursor - st, fields,
                          BW_USHIFT_RIGHT, t, pCtx);
                    }
                    else if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                      return lastNode = new IndexedOperativeAssign(expr, st, cursor - st,
                          BW_USHIFT_RIGHT, idx, fields, pCtx);
                    }
                    else {
                      return lastNode = new OperativeAssign(name, expr, st, cursor - st,
                          BW_USHIFT_RIGHT, fields, pCtx);
                    }
                  }
                }
                break CaptureLoop;

              case '(':
                cursor = balancedCaptureWithLineAccounting(expr, cursor, end, '(', pCtx) + 1;
                continue;

              case '[':
                cursor = balancedCaptureWithLineAccounting(expr, cursor, end, '[', pCtx) + 1;
                continue;

              case '{':
                if (!union) break CaptureLoop;
                cursor = balancedCaptureWithLineAccounting(expr, cursor, end, '{', pCtx) + 1;
                continue;

              case '~':
                if (lookAhead() == '=') {
                  // tmp = subArray(start, trimLeft(cursor));
                  tmpStart = st;
                  int tmpOffset = cursor - st;
                  st = cursor += 2;

                  captureToEOT();

                  return lastNode = new RegExMatch(expr, tmpStart, tmpOffset, fields, st, cursor - st, pCtx);
                }
                break CaptureLoop;

              case '=':
                if (lookAhead() == '+') {
                  name = new String(expr, st, trimLeft(cursor) - st);

                  st = cursor += 2;

                  if (!isNextIdentifierOrLiteral()) {
                    throw new CompileException("unexpected symbol '" + expr[cursor] + "'", expr, st);
                  }

                  captureToEOS();

                  if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                    return lastNode = new IndexedOperativeAssign(expr, st, cursor - st,
                        ADD, idx, fields, pCtx);
                  }
                  else {
                    return lastNode = new OperativeAssign(name, expr, st, cursor - st,
                        ADD, fields, pCtx);
                  }
                }
                else if (lookAhead() == '-') {
                  name = new String(expr, st, trimLeft(cursor) - st);

                  st = cursor += 2;

                  if (!isNextIdentifierOrLiteral()) {
                    throw new CompileException("unexpected symbol '" + expr[cursor] + "'", expr, st);
                  }

                  captureToEOS();

                  if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                    return lastNode = new IndexedOperativeAssign(expr, st, cursor - st,
                        SUB, idx, fields, pCtx);
                  }
                  else {
                    return lastNode = new OperativeAssign(name, expr, st, cursor - st,
                        SUB, fields, pCtx);
                  }
                }
                if (greedy && lookAhead() != '=') {
                  cursor++;

                  if (union) {
                    captureToEOS();

                    return lastNode = new DeepAssignmentNode(expr, st, cursor - st,
                        fields | ASTNode.ASSIGN, pCtx);
                  }
                  else if (lastWasIdentifier) {
                    return procTypedNode(false);
                  }
                  else if (pCtx != null && ((idx = pCtx.variableIndexOf(t)) != -1
                      && (pCtx.isIndexAllocation()))) {
                    captureToEOS();

                    IndexedAssignmentNode ian = new IndexedAssignmentNode(expr, st = trimRight(st),
                        trimLeft(cursor) - st,
                        ASTNode.ASSIGN, idx, pCtx);

                    if (idx == -1) {
                      pCtx.addIndexedInput(t = ian.getVarName());
                      ian.setRegister(pCtx.variableIndexOf(t));
                    }
                    return lastNode = ian;
                  }
                  else {
                    captureToEOS();

                    return lastNode = new AssignmentNode(expr, st, cursor - st,
                        fields | ASTNode.ASSIGN, pCtx);
                  }
                }
                break CaptureLoop;

              default:
                if (cursor != end) {
                  if (isIdentifierPart(expr[cursor])) {
                    if (!union) {
                      break CaptureLoop;
                    }
                    cursor++;
                    while (cursor != end && isIdentifierPart(expr[cursor])) cursor++;
                  }
                  else if ((cursor + 1) != end && isIdentifierPart(expr[cursor + 1])) {
                    break CaptureLoop;
                  }
                  else {
                    cursor++;
                  }
                }
                else {
                  break CaptureLoop;
                }
            }
          }

          /**
           * Produce the token.
           */
          trimWhitespace();

          return createPropertyToken(st, cursor);
        }
        else {
          switch (expr[cursor]) {
            case '.': {
              cursor++;
              if (isDigit(expr[cursor])) {
                capture = true;
                continue;
              }
              expectNextChar_IW('{');

              return lastNode = new ThisWithNode(expr, st, cursor - st - 1
                  , cursor + 1,
                  (cursor = balancedCaptureWithLineAccounting(expr,
                      cursor, end, '{', pCtx) + 1) - 3, fields, pCtx);
            }

            case '@': {
              st++;
              captureToEOT();

              if (pCtx == null || (pCtx.getInterceptors() == null || !pCtx.getInterceptors().
                  containsKey(name = new String(expr, st, cursor - st)))) {
                throw new CompileException("reference to undefined interceptor: "
                    + new String(expr, st, cursor - st), expr, st);
              }

              return lastNode = new InterceptorWrapper(pCtx.getInterceptors().get(name), nextToken(), pCtx);
            }

            case '=':
              return createOperator(expr, st, (cursor += 2));

            case '-':
              if (lookAhead() == '-') {
                cursor += 2;
                skipWhitespace();
                st = cursor;
                captureIdentifier();

                name = new String(subArray(st, cursor));
                if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                  return lastNode = new IndexedPreFixDecNode(idx, pCtx);
                }
                else {
                  return lastNode = new PreFixDecNode(name, pCtx);
                }
              }
              else if ((cursor == start || (lastNode != null &&
                  (lastNode instanceof BooleanNode || lastNode.isOperator())))
                  && !isDigit(lookAhead())) {

                cursor += 1;
                captureToEOT();
                return new Sign(expr, st, cursor - st, fields, pCtx);
              }
              else if ((cursor != start &&
                  (lastNode != null && !(lastNode instanceof BooleanNode || lastNode.isOperator())))
                  || !isDigit(lookAhead())) {

                return createOperator(expr, st, cursor++ + 1);
              }
              else if ((cursor - 1) != start || (!isDigit(expr[cursor - 1])) && isDigit(lookAhead())) {
                cursor++;
                break;
              }
              else {
                throw new CompileException("not a statement", expr, st);
              }

            case '+':
              if (lookAhead() == '+') {
                cursor += 2;
                skipWhitespace();
                st = cursor;
                captureIdentifier();

                name = new String(subArray(st, cursor));
                if (pCtx != null && (idx = pCtx.variableIndexOf(name)) != -1) {
                  return lastNode = new IndexedPreFixIncNode(idx, pCtx);
                }
                else {
                  return lastNode = new PreFixIncNode(name, pCtx);
                }
              }
              return createOperator(expr, st, cursor++ + 1);

            case '*':
              if (lookAhead() == '*') {
                cursor++;
              }
              return createOperator(expr, st, cursor++ + 1);

            case ';':
              cursor++;
              lastWasIdentifier = false;
              return lastNode = new EndOfStatement(pCtx);

            case '?':
              if (cursor == start) {
                cursor++;
                continue;
              }


            case '#':
            case '/':
            case ':':
            case '^':
            case '%': {
              return createOperator(expr, st, cursor++ + 1);
            }

            case '(': {
              cursor++;

              boolean singleToken = true;

              skipWhitespace();
              for (brace = 1; cursor != end && brace != 0; cursor++) {
                switch (expr[cursor]) {
                  case '(':
                    brace++;
                    break;
                  case ')':
                    brace--;
                    break;
                  case '\'':
                    cursor = captureStringLiteral('\'', expr, cursor, end);
                    break;
                  case '"':
                    cursor = captureStringLiteral('"', expr, cursor, end);
                    break;
                  case 'i':
                    if (brace == 1 && isWhitespace(lookBehind()) && lookAhead() == 'n' && isWhitespace(lookAhead(2))) {

                      for (int level = brace; cursor != end; cursor++) {
                        switch (expr[cursor]) {
                          case '(':
                            brace++;
                            break;
                          case ')':
                            if (--brace < level) {
                              cursor++;
                              if (tokenContinues()) {
                                lastNode = new Fold(expr, trimRight(st + 1),
                                    cursor - st - 2, fields, pCtx);
                                if (expr[st = cursor] == '.') st++;
                                captureToEOT();
                                return lastNode = new Union(expr, st = trimRight(st),
                                    cursor - st, fields, lastNode, pCtx);
                              }
                              else {
                                return lastNode = new Fold(expr, trimRight(st + 1),
                                    cursor - st - 2, fields, pCtx);
                              }
                            }
                            break;
                          case '\'':
                            cursor = captureStringLiteral('\'', expr, cursor, end);
                            break;
                          case '"':
                            cursor = captureStringLiteral('\"', expr, cursor, end);
                            break;
                        }
                      }

                      throw new CompileException("unterminated projection; closing parathesis required",
                          expr, st);
                    }
                    break;

                  default:
                    /**
                     * Check to see if we should disqualify this current token as a potential
                     * type-cast candidate.
                     */

                    if (expr[cursor] != '.') {
                      switch (expr[cursor]) {
                        case '[':
                        case ']':
                          break;

                        default:
                          if (!(isIdentifierPart(expr[cursor]) || expr[cursor] == '.')) {
                            singleToken = false;
                          }
                      }
                    }
                }
              }

              if (brace != 0) {
                throw new CompileException("unbalanced braces in expression: (" + brace + "):",
                    expr, st);
              }

              tmpStart = -1;
              if (singleToken) {
                int _st;
                TypeDescriptor tDescr = new TypeDescriptor(expr, _st = trimRight(st + 1),
                    trimLeft(cursor - 1) - _st, fields);

                Class cls;
                try {
                  if (tDescr.isClass() && (cls = getClassReference(pCtx, tDescr)) != null) {

                    // lookahead to check if it could be a real cast
                    boolean isCast = false;
                    for (int i = cursor; i < expr.length; i++) {
                      if (expr[i] == ' ' || expr[i] == '\t') continue;
                      isCast = isIdentifierPart(expr[i]) || expr[i] == '\'' || expr[i] == '"' || expr[i] == '(';
                      break;
                    }

                    if (isCast) {
                      st = cursor;

                      captureToEOT();
                      //   captureToEOS();

                      return lastNode = new TypeCast(expr, st, cursor - st,
                          cls, fields, pCtx);
                    }
                  }
                }
                catch (ClassNotFoundException e) {
                  // fallthrough
                }

              }

              if (tmpStart != -1) {
                return handleUnion(handleSubstatement(new Substatement(expr, tmpStart, cursor - tmpStart, fields, pCtx)));
              }
              else {
                return handleUnion(
                    handleSubstatement(
                        new Substatement(expr, st = trimRight(st + 1),
                            trimLeft(cursor - 1) - st, fields, pCtx)));
              }
            }

            case '}':
            case ']':
            case ')': {
              throw new CompileException("unbalanced braces", expr, st);
            }

            case '>': {
              switch (expr[cursor + 1]) {
                case '>':
                  if (expr[cursor += 2] == '>') cursor++;
                  return createOperator(expr, st, cursor);
                case '=':
                  return createOperator(expr, st, cursor += 2);
                default:
                  return createOperator(expr, st, ++cursor);
              }
            }

            case '<': {
              if (expr[++cursor] == '<') {
                if (expr[++cursor] == '<') cursor++;
                return createOperator(expr, st, cursor);
              }
              else if (expr[cursor] == '=') {
                return createOperator(expr, st, ++cursor);
              }
              else {
                return createOperator(expr, st, cursor);
              }
            }

            case '\'':
            case '"':
              lastNode = new LiteralNode(handleStringEscapes(subset(expr, st + 1,
                  (cursor = captureStringLiteral(expr[cursor], expr, cursor, end)) - st - 1))
                  , String.class, pCtx);

              cursor++;

              if (tokenContinues()) {
                return lastNode = handleUnion(lastNode);
              }

              return lastNode;

            case '&': {
              if (expr[cursor++ + 1] == '&') {
                return createOperator(expr, st, ++cursor);
              }
              else {
                return createOperator(expr, st, cursor);
              }
            }

            case '|': {
              if (expr[cursor++ + 1] == '|') {
                return createOperator(expr, st, ++cursor);
              }
              else {
                return createOperator(expr, st, cursor);
              }
            }

            case '~':
              if ((cursor++ - 1 != 0 || !isIdentifierPart(lookBehind()))
                  && isDigit(expr[cursor])) {
                st = cursor;
                captureToEOT();
                return lastNode = new Invert(expr, st, cursor - st, fields, pCtx);
              }
              else if (expr[cursor] == '(') {
                st = cursor--;
                captureToEOT();
                return lastNode = new Invert(expr, st, cursor - st, fields, pCtx);
              }
              else {
                if (expr[cursor] == '=') cursor++;
                return createOperator(expr, st, cursor);
              }

            case '!': {
              ++cursor;
              if (isNextIdentifier()) {
                if (lastNode != null && !lastNode.isOperator()) {
                  throw new CompileException("unexpected operator '!'", expr, st);
                }

                st = cursor;
                captureToEOT();
                if ("new".equals(name = new String(expr, st, cursor - st))
                    || "isdef".equals(name)) {
                  captureToEOT();
                  return lastNode = new Negation(expr, st, cursor - st, fields, pCtx);
                }
                else {
                  return lastNode = new Negation(expr, st, cursor - st, fields, pCtx);
                }
              }
              else if (expr[cursor] == '(') {
                st = cursor--;
                captureToEOT();
                return lastNode = new Negation(expr, st, cursor - st, fields, pCtx);
              }
              else if (expr[cursor] == '!') {
                // just ignore a double negation
                ++cursor;
                return nextToken();
              }
              else if (expr[cursor] != '=')
                throw new CompileException("unexpected operator '!'", expr, st, null);
              else {
                return createOperator(expr, st, ++cursor);
              }
            }

            case '[':
            case '{':
              cursor = balancedCaptureWithLineAccounting(expr, cursor, end, expr[cursor], pCtx) + 1;
              if (tokenContinues()) {
                lastNode = new InlineCollectionNode(expr, st, cursor - st, fields, pCtx);
                st = cursor;
                captureToEOT();
                if (expr[st] == '.') st++;

                return lastNode = new Union(expr, st, cursor - st, fields, lastNode, pCtx);
              }
              else {
                return lastNode = new InlineCollectionNode(expr, st, cursor - st, fields, pCtx);
              }

            default:
              cursor++;
          }
        }
      }

      if (st == cursor)
        return null;
      else
        return createPropertyToken(st, cursor);
    }
    catch (RedundantCodeException e) {
      return nextToken();
    }
    catch (NumberFormatException e) {
      throw new CompileException("badly formatted number: " + e.getMessage(), expr, st, e);
    }
    catch (StringIndexOutOfBoundsException e) {
      throw new CompileException("unexpected end of statement", expr, cursor, e);
    }
    catch (ArrayIndexOutOfBoundsException e) {
      throw new CompileException("unexpected end of statement", expr, cursor, e);
    }
    catch (CompileException e) {
      throw ErrorUtil.rewriteIfNeeded(e, expr, cursor);
    }
  }
View Full Code Here

TOP

Related Classes of org.mvel2.CompileException

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.