org.mvel2.util.FunctionParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mvel2 Show documentation
Show all versions of mvel2 Show documentation
MVEL is a powerful expression language for Java-based applications.
It provides a plethora of features and is suited for everything
from the smallest property binding and extraction, to full blown scripts.
package org.mvel2.util;
import org.mvel2.CompileException;
import org.mvel2.ParserContext;
import org.mvel2.ast.EndOfStatement;
import org.mvel2.ast.Function;
import static org.mvel2.util.ParseTools.balancedCaptureWithLineAccounting;
public class FunctionParser {
private String name;
private int cursor;
private int length;
private int fields;
private char[] expr;
private ParserContext pCtx;
private ExecutionStack splitAccumulator;
public FunctionParser(String functionName,
int cursor,
int endOffset,
char[] expr,
int fields,
ParserContext pCtx,
ExecutionStack splitAccumulator) {
this.name = functionName;
this.cursor = cursor;
this.length = endOffset;
this.expr = expr;
this.fields = fields;
this.pCtx = pCtx;
this.splitAccumulator = splitAccumulator;
}
public Function parse() {
int start = cursor;
int startCond = 0;
int endCond = 0;
int blockStart;
int blockEnd;
int end = cursor + length;
cursor = ParseTools.captureToNextTokenJunction(expr, cursor, end, pCtx);
if (expr[cursor = ParseTools.nextNonBlank(expr, cursor)] == '(') {
/**
* If we discover an opening bracket after the function name, we check to see
* if this function accepts parameters.
*/
endCond = cursor = balancedCaptureWithLineAccounting(expr, startCond = cursor, end, '(', pCtx);
startCond++;
cursor++;
cursor = ParseTools.skipWhitespace(expr, cursor);
if (cursor >= end) {
throw new CompileException("incomplete statement", expr, cursor);
}
else if (expr[cursor] == '{') {
blockEnd = cursor = balancedCaptureWithLineAccounting(expr, blockStart = cursor, end, '{', pCtx);
}
else {
blockStart = cursor - 1;
cursor = ParseTools.captureToEOS(expr, cursor, end, pCtx);
blockEnd = cursor;
}
}
else {
/**
* This function has not parameters.
*/
if (expr[cursor] == '{') {
/**
* This function is bracketed. We capture the entire range in the brackets.
*/
blockEnd = cursor = balancedCaptureWithLineAccounting(expr, blockStart = cursor, end, '{', pCtx);
}
else {
/**
* This is a single statement function declaration. We only capture the statement.
*/
blockStart = cursor - 1;
cursor = ParseTools.captureToEOS(expr, cursor, end, pCtx);
blockEnd = cursor;
}
}
/**
* Trim any whitespace from the captured block range.
*/
blockStart = ParseTools.trimRight(expr, blockStart + 1);
blockEnd = ParseTools.trimLeft(expr, start, blockEnd);
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(pCtx));
}
/**
* Produce the funciton node.
*/
return new Function(name, expr, startCond, endCond - startCond, blockStart, blockEnd - blockStart, fields, pCtx);
}
public String getName() {
return name;
}
public int getCursor() {
return cursor;
}
}