[ 
https://issues.apache.org/jira/browse/JEXL-438?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17941233#comment-17941233
 ] 

Henri Biestro commented on JEXL-438:
------------------------------------

The easiest part is configuring to avoid syntactic constructs that dont look 
like expressions:

{code:java}
// Some comments here

        // no local, no lambda, no loops, no-side effects
        final JexlFeatures f = new JexlFeatures()
                .localVar(false)
                .lambda(false)
                .loops(false)
                .sideEffect(false)
                .sideEffectGlobal(false);
        JexlBuilder builder = new JexlBuilder();
        builder.features(f);
        // more settings...
        JexlEngine jexl = builder.create();
{code}

The easiest way without modifications to JEXL code is to transcode those 
SQL-like expressions to JEXL, something like:


{code:java}

    /** The set of characters that may be followed by a '='.*/
    static final char[] EQ_FRIEND;
    static {
        char[] eq = {'!', ':', '<', '>', '^', '|', '&', '+', '-', '/', '*', 
'~', '='};
        Arrays.sort(eq);
        EQ_FRIEND = eq;
    }

    /**
     * Transcodes a SQL-inspired expression to a JEXL expression.
     * @param expr the expression to transcode
     * @return the resulting expression
     */
    private static String transcodeSQLExpr(final CharSequence expr) {
        final StringBuilder strb = new StringBuilder(expr.length());
        final int end = expr.length();
        char previous = 0;
        for (int i = 0; i < end; ++i) {
            char c = expr.charAt(i);
            if (previous == '<') {
                // previous char a '<' now followed by '>'
                if (c == '>') {
                    // replace '<>' with '!='
                    strb.append("!=");
                    previous = c;
                    continue;
                } else {
                    strb.append('<');
                }
            }
            if (c != '<') {
                if (c == '=') {
                    // replace '=' with '==' when it does not follow a 'friend'
                    if (Arrays.binarySearch(EQ_FRIEND, previous) >= 0) {
                        strb.append(c);
                    } else {
                        strb.append("==");
                    }
                } else {
                    strb.append(c);
                    if (c == '"' || c == '\'') {
                        // read string, escape '\'
                        boolean escape = false;
                        for (i += 1; i < end; ++i) {
                            final char ec = expr.charAt(i);
                            strb.append(ec);
                            if (ec == '\\') {
                                escape = !escape;
                            } else if (escape) {
                                escape = false;
                            } else if (ec == c) {
                                break;
                            }
                        }
                    }
                }
            }
            previous = c;
        }
        return strb.toString();
    }


    @Test
    void testSQLTranspose() {
        String[] e = { "a<>b", "a = 2", "a.b.c <> '1<>0'" };
        String[] j = { "a!=b", "a == 2", "a.b.c != '1<>0'" };
        for(int i = 0; i < e.length; ++i) {
            String je = transcodeSQLExpr(e[i]);
            Assertions.assertEquals(j[i], je);
        }
    }

    @Test
    void testSQLNoChange() {
        String[] e = { "a <= 2", "a >= 2", "a := 2", "a + 3 << 4 > 5",  };
        for(int i = 0; i < e.length; ++i) {
            String je = transcodeSQLExpr(e[i]);
            Assertions.assertEquals(e[i], je);
        }
    }
{code}




> Allow alternative syntax: sql/excel-like
> ----------------------------------------
>
>                 Key: JEXL-438
>                 URL: https://issues.apache.org/jira/browse/JEXL-438
>             Project: Commons JEXL
>          Issue Type: New Feature
>            Reporter: Yair Lenga
>            Priority: Major
>
> Im using jexl3 to allow customization by end users of workflow. The users 
> love the flexibility, but are having repeated issues with the grammar. 
> Specifically, the == operator, not having ‘<>’. I understand the parser 
> cannot be configured at run time flag, as it is generated code by JavaScript, 
> and changing = to mean equals will change parsing logic, operator precedence, 
> etc.
> My ask: possible to allow for an alternate parser (parser-sql.jjt), which 
> will be modified/extended version of the existing parser.jjt, and will 
> provide more sql/excel operators. in particular, no assignment inside 
> expressions, etc.
> Implementation can allow for a Boolean mode, 'Sqlish', same as 'antish' 
> property. I'm not sure if possible to build a parser outside the jexl3 tree. 
> If yes, will be nice to be able to pass a class that implement the same 
> interface as the current parser.
> For my use case, I do not mind having all the jexl3 extension features, even 
> the one not in the sql/excel grammar. I do not need the ability to have 
> statements, scripts, etc.
> there are some other minor twists (concatenation, etc), but I believe those 
> can be handled via jex3 operator customization. Some constructs (sql case) 
> will require some additional work, but are not high priority for my use case.
>  



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to