Search in sources :

Example 1 with FunctionParser

use of org.mvel2.util.FunctionParser in project mvel by mikebrock.

the class AbstractParser method _captureBlock.

private ASTNode _captureBlock(ASTNode node, final char[] expr, boolean cond, int type) {
    skipWhitespace();
    int startCond = 0;
    int endCond = 0;
    int blockStart;
    int blockEnd;
    String name;
    /**
     * Functions are a special case we handle differently from the rest of block parsing
     */
    switch(type) {
        case FUNCTION:
            {
                int st = cursor;
                captureToNextTokenJunction();
                if (cursor == end) {
                    throw new CompileException("unexpected end of statement", expr, st);
                }
                /**
         * Check to see if the name is legal.
         */
                if (isReservedWord(name = createStringTrimmed(expr, st, cursor - st)) || isNotValidNameorLabel(name))
                    throw new CompileException("illegal function name or use of reserved word", expr, cursor);
                if (pCtx == null)
                    pCtx = getParserContext();
                FunctionParser parser = new FunctionParser(name, cursor, end - cursor, expr, fields, pCtx, splitAccumulator);
                Function function = parser.parse();
                cursor = parser.getCursor();
                return lastNode = function;
            }
        case PROTO:
            if (ProtoParser.isUnresolvedWaiting()) {
                if (pCtx == null)
                    pCtx = getParserContext();
                ProtoParser.checkForPossibleUnresolvedViolations(expr, cursor, pCtx);
            }
            int st = cursor;
            captureToNextTokenJunction();
            if (isReservedWord(name = createStringTrimmed(expr, st, cursor - st)) || isNotValidNameorLabel(name))
                throw new CompileException("illegal prototype name or use of reserved word", expr, cursor);
            if (expr[cursor = nextNonBlank()] != '{') {
                throw new CompileException("expected '{' but found: " + expr[cursor], expr, cursor);
            }
            cursor = balancedCaptureWithLineAccounting(expr, st = cursor + 1, end, '{', pCtx);
            if (pCtx == null)
                pCtx = getParserContext();
            ProtoParser parser = new ProtoParser(expr, st, cursor, name, pCtx, fields, splitAccumulator);
            Proto proto = parser.parse();
            if (pCtx == null)
                pCtx = getParserContext();
            pCtx.addImport(proto);
            proto.setCursorPosition(st, cursor);
            cursor = parser.getCursor();
            ProtoParser.notifyForLateResolution(proto);
            return lastNode = proto;
        default:
            if (cond) {
                if (expr[cursor] != '(') {
                    throw new CompileException("expected '(' but encountered: " + expr[cursor], expr, cursor);
                }
                /**
           * This block is an: IF, FOREACH or WHILE node.
           */
                endCond = cursor = balancedCaptureWithLineAccounting(expr, startCond = cursor, end, '(', pCtx);
                startCond++;
                cursor++;
            }
    }
    skipWhitespace();
    if (cursor >= end) {
        throw new CompileException("unexpected end of statement", expr, end);
    } else if (expr[cursor] == '{') {
        blockEnd = cursor = balancedCaptureWithLineAccounting(expr, blockStart = cursor, end, '{', pCtx);
    } else {
        blockStart = cursor - 1;
        captureToEOSorEOL();
        blockEnd = cursor + 1;
    }
    if (type == ASTNode.BLOCK_IF) {
        IfNode ifNode = (IfNode) node;
        if (node != null) {
            if (!cond) {
                return ifNode.setElseBlock(expr, st = trimRight(blockStart + 1), trimLeft(blockEnd) - st, pCtx);
            } else {
                return ifNode.setElseIf((IfNode) createBlockToken(startCond, endCond, trimRight(blockStart + 1), trimLeft(blockEnd), type));
            }
        } else {
            return createBlockToken(startCond, endCond, blockStart + 1, blockEnd, type);
        }
    } else if (type == ASTNode.BLOCK_DO) {
        cursor++;
        skipWhitespace();
        st = cursor;
        captureToNextTokenJunction();
        if ("while".equals(name = new String(expr, st, cursor - st))) {
            skipWhitespace();
            startCond = cursor + 1;
            endCond = cursor = balancedCaptureWithLineAccounting(expr, cursor, end, '(', pCtx);
            return createBlockToken(startCond, endCond, trimRight(blockStart + 1), trimLeft(blockEnd), type);
        } else if ("until".equals(name)) {
            skipWhitespace();
            startCond = cursor + 1;
            endCond = cursor = balancedCaptureWithLineAccounting(expr, cursor, end, '(', pCtx);
            return createBlockToken(startCond, endCond, trimRight(blockStart + 1), trimLeft(blockEnd), ASTNode.BLOCK_DO_UNTIL);
        } else {
            throw new CompileException("expected 'while' or 'until' but encountered: " + name, expr, cursor);
        }
    } else // DON"T REMOVE THIS COMMENT!
    // else if (isFlag(ASTNode.BLOCK_FOREACH) || isFlag(ASTNode.BLOCK_WITH)) {
    {
        return createBlockToken(startCond, endCond, trimRight(blockStart + 1), trimLeft(blockEnd), type);
    }
}
Also used : FunctionParser(org.mvel2.util.FunctionParser) ProtoParser(org.mvel2.util.ProtoParser) CompileException(org.mvel2.CompileException)

Example 2 with FunctionParser

use of org.mvel2.util.FunctionParser in project mvel by mikebrock.

the class ProtoParser method parse.

public Proto parse() {
    Proto proto = new Proto(protoName);
    Mainloop: while (cursor < endOffset) {
        cursor = ParseTools.skipWhitespace(expr, cursor);
        int start = cursor;
        if (tk2 == null) {
            while (cursor < endOffset && isIdentifierPart(expr[cursor])) cursor++;
            if (cursor > start) {
                tk1 = new String(expr, start, cursor - start);
                if ("def".equals(tk1) || "function".equals(tk1)) {
                    cursor++;
                    cursor = ParseTools.skipWhitespace(expr, cursor);
                    start = cursor;
                    while (cursor < endOffset && isIdentifierPart(expr[cursor])) cursor++;
                    if (start == cursor) {
                        throw new CompileException("attempt to declare an anonymous function as a prototype member", expr, start);
                    }
                    FunctionParser parser = new FunctionParser(new String(expr, start, cursor - start), cursor, endOffset, expr, 0, pCtx, null);
                    proto.declareReceiver(parser.getName(), parser.parse());
                    cursor = parser.getCursor() + 1;
                    tk1 = null;
                    continue;
                }
            }
            cursor = ParseTools.skipWhitespace(expr, cursor);
        }
        if (cursor > endOffset) {
            throw new CompileException("unexpected end of statement in proto declaration: " + protoName, expr, start);
        }
        switch(expr[cursor]) {
            case ';':
                cursor++;
                calculateDecl();
                if (interpreted && type == DeferredTypeResolve.class) {
                    /**
             * If this type could not be immediately resolved, it may be a look-ahead case, so
             * we defer resolution of the type until later and place it in the wait queue.
             */
                    enqueueReceiverForLateResolution(deferredName, proto.declareReceiver(name, Proto.ReceiverType.DEFERRED, null), null);
                } else {
                    proto.declareReceiver(name, type, null);
                }
                break;
            case '=':
                cursor++;
                cursor = ParseTools.skipWhitespace(expr, cursor);
                start = cursor;
                Loop: while (cursor < endOffset) {
                    switch(expr[cursor]) {
                        case '{':
                        case '[':
                        case '(':
                        case '\'':
                        case '"':
                            cursor = balancedCaptureWithLineAccounting(expr, cursor, endOffset, expr[cursor], pCtx);
                            break;
                        case ';':
                            break Loop;
                    }
                    cursor++;
                }
                calculateDecl();
                String initString = new String(expr, start, cursor++ - start);
                if (interpreted && type == DeferredTypeResolve.class) {
                    enqueueReceiverForLateResolution(deferredName, proto.declareReceiver(name, Proto.ReceiverType.DEFERRED, null), initString);
                } else {
                    proto.declareReceiver(name, type, (ExecutableStatement) subCompileExpression(initString, pCtx));
                }
                break;
            default:
                start = cursor;
                while (cursor < endOffset && isIdentifierPart(expr[cursor])) cursor++;
                if (cursor > start) {
                    tk2 = new String(expr, start, cursor - start);
                }
        }
    }
    cursor++;
    /**
     * Check if the function is manually terminated.
     */
    if (splitAccumulator != null && ParseTools.isStatementNotManuallyTerminated(expr, cursor)) {
        /**
       * Add an EndOfStatement to the split accumulator in the parser.
       */
        splitAccumulator.add(new EndOfStatement());
    }
    return proto;
}
Also used : ExecutableStatement(org.mvel2.compiler.ExecutableStatement) Proto(org.mvel2.ast.Proto) EndOfStatement(org.mvel2.ast.EndOfStatement) CompileException(org.mvel2.CompileException)

Aggregations

CompileException (org.mvel2.CompileException)2 EndOfStatement (org.mvel2.ast.EndOfStatement)1 Proto (org.mvel2.ast.Proto)1 ExecutableStatement (org.mvel2.compiler.ExecutableStatement)1 FunctionParser (org.mvel2.util.FunctionParser)1 ProtoParser (org.mvel2.util.ProtoParser)1