Verified Commit 28c731ea authored by Federico Vera's avatar Federico Vera
Browse files

Add disable builtin implementations

useBuiltInFunctions
useBuiltInOperators
useImplicitMultiplication
parent 96876fa1
Loading
Loading
Loading
Loading
+43 −4
Original line number Diff line number Diff line
@@ -43,6 +43,12 @@ public class ExpressionBuilder {

    private final Set<String> variableNames;

    private boolean useBuiltInFunctions = true;

    private boolean useBuiltInOperators = true;

    private boolean useImplicitMultiplication = true;

    /**
     * Create a new ExpressionBuilder instance and initialize it with a given expression
     * string.
@@ -59,6 +65,35 @@ public class ExpressionBuilder {
        this.variableNames = new HashSet<>(4);
    }

    /**
     * Removes all of the built-in functions
     * @return the ExpressionBuilder instance
     */
    public ExpressionBuilder disableBuiltInFunctions() {
        useBuiltInFunctions = false;
        return this;
    }

    /**
     * Removes all of the built-in operators including implicit multiplication
     * @return the ExpressionBuilder instance
     * @see ExpressionBuilder#disableImplicitMultiplication()
     */
    public ExpressionBuilder disableBuiltInOperators() {
        useBuiltInOperators = false;
        useBuiltInFunctions = false;
        return this;
    }

    /**
     * Disables implicit multiplication
     * @return the ExpressionBuilder instance
     */
    public ExpressionBuilder disableImplicitMultiplication() {
        useImplicitMultiplication = false;
        return this;
    }

    /**
     * Add a {@link Function} implementation available for use in the expression.
     * @param function the custom {@link Function} implementation that should be available for
@@ -219,10 +254,14 @@ public class ExpressionBuilder {

        Token[] tokens = ShuntingYard.convertToRPN(
                simplify,
                this.expression,
                this.userFunctions,
                this.userOperators,
                this.variableNames
                expression,
                userFunctions,
                userOperators,
                variableNames,
                useImplicitMultiplication,
                useBuiltInFunctions,
                useBuiltInOperators

        );

        return new Expression(tokens, this.userFunctions.keySet());
+14 −3
Original line number Diff line number Diff line
@@ -47,11 +47,22 @@ public final class ShuntingYard {
                                       final String expression,
                                       final Map<String, Function> userFunctions,
                                       final Map<String, Operator> userOperators,
                                       final Set<String> variableNames){
                                       final Set<String> variableNames,
                                       final boolean useImplicitMultiplication,
                                       final boolean useBuiltInFunctions,
                                       final boolean useBuiltInOperators){
        final TokenStack stack  = new TokenStack();
        final TokenStack output = new TokenStack();

        final Tokenizer tokenizer = new Tokenizer(expression, userFunctions, userOperators, variableNames);
        final Tokenizer tokenizer = new Tokenizer(
                expression,
                userFunctions,
                userOperators,
                variableNames,
                useImplicitMultiplication,
                useBuiltInFunctions,
                useBuiltInOperators
        );
        while (tokenizer.hasNext()) {
            Token token = tokenizer.nextToken();
            switch (token.getType()) {
+28 −13
Original line number Diff line number Diff line
@@ -42,12 +42,26 @@ public class Tokenizer {

    private Token lastToken;

    public Tokenizer(String expression, final Map<String, Function> userFunctions,
            final Map<String, Operator> userOperators, final Set<String> variableNames) {
    private boolean useBuiltInFunctions = true;

    private boolean useBuiltInOperators = true;

    private boolean useImplicitMultiplication = true;

    public Tokenizer(final String expression,
                    final Map<String, Function> userFunctions,
                    final Map<String, Operator> userOperators,
                    final Set<String> variableNames,
                    final boolean useImplicitMultiplication,
                    final boolean useBuiltInFunctions,
                    final boolean useBuiltInOperators) {
        this.expression = expression.trim().toCharArray();
        this.expressionLength = this.expression.length;
        this.userFunctions = userFunctions;
        this.userOperators = userOperators;
        this.useBuiltInFunctions = useBuiltInFunctions;
        this.useBuiltInOperators = useBuiltInOperators;
        this.useImplicitMultiplication = useImplicitMultiplication;

        if (variableNames == null) {
            variableTokens = new HashMap<>(0);
@@ -74,7 +88,8 @@ public class Tokenizer {
                    throw new IllegalArgumentException(String.format(
                        "Unable to parse char '%s' (Code: %d) at [%d]", ch, (int) ch, pos
                    ));
                } else if ((lastToken.getType() != OPERATOR
                } else if (useImplicitMultiplication
                         && (lastToken.getType() != OPERATOR
                         &&  lastToken.getType() != PARENTHESES_OPEN
                         &&  lastToken.getType() != FUNCTION
                         &&  lastToken.getType() != SEPARATOR)) {
@@ -87,7 +102,7 @@ public class Tokenizer {
        } else if (isArgumentSeparator(ch)) {
            return parseArgumentSeparatorToken();
        } else if (isOpenParentheses(ch)) {
            if (lastToken != null &&
            if (lastToken != null && useImplicitMultiplication &&
                    (lastToken.getType() != OPERATOR
                  && lastToken.getType() != PARENTHESES_OPEN
                  && lastToken.getType() != FUNCTION
@@ -103,7 +118,7 @@ public class Tokenizer {
            return parseOperatorToken(ch);
        } else if (isAlphabetic(ch) || ch == '_') {
            // parse the name which can be a setVariable or a function
            if (lastToken != null &&
            if (lastToken != null && useImplicitMultiplication &&
                    (lastToken.getType() != OPERATOR
                  && lastToken.getType() != PARENTHESES_OPEN
                  && lastToken.getType() != FUNCTION
@@ -187,7 +202,7 @@ public class Tokenizer {
        if (this.userFunctions != null) {
            f = this.userFunctions.get(name);
        }
        if (f == null) {
        if (f == null && useBuiltInFunctions) {
            f = Functions.getBuiltinFunction(name);
        }
        return f;
@@ -224,7 +239,7 @@ public class Tokenizer {
        if (this.userOperators != null) {
            op = this.userOperators.get(symbol);
        }
        if (op == null && symbol.length() == 1) {
        if (useBuiltInOperators && op == null && symbol.length() == 1) {
            int argc = 2;
            if (lastToken == null) {
                argc = 1;