commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hen...@apache.org
Subject svn commit: r809160 - in /commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl: Debugger.java Interpreter.java JexlEngine.java parser/Parser.jjt
Date Sat, 29 Aug 2009 16:59:55 GMT
Author: henrib
Date: Sat Aug 29 16:59:55 2009
New Revision: 809160

URL: http://svn.apache.org/viewvc?rev=809160&view=rev
Log:
*Parser.jjt*: modified grammar to make last statement terminator (aka ';') optional.
This implied a change in AdditiveOperation and the introduction of AdditiveOperator to break
conflicts.
*Interpreter.java*: modified according to grammar ({Add,Subtract}Node replaced by AdditiveNode.
Debugger.java: made debugger expression-AST roundtrip enabled; the Debugger can regenerate
an expression from AST that when parsed, will give back an equivalent AST (fixes JEXL-86).
JexlEngine.java: modified because StatementExpression are no longer creating nodes (#void)

Modified:
    commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/Debugger.java
    commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/Interpreter.java
    commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/JexlEngine.java
    commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/parser/Parser.jjt

Modified: commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/Debugger.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/Debugger.java?rev=809160&r1=809159&r2=809160&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/Debugger.java (original)
+++ commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/Debugger.java Sat
Aug 29 16:59:55 2009
@@ -16,7 +16,8 @@
  */
 package org.apache.commons.jexl;
 
-import org.apache.commons.jexl.parser.ASTAddNode;
+import org.apache.commons.jexl.parser.ASTAdditiveNode;
+import org.apache.commons.jexl.parser.ASTAdditiveOperator;
 import org.apache.commons.jexl.parser.ASTAndNode;
 import org.apache.commons.jexl.parser.ASTArrayAccess;
 import org.apache.commons.jexl.parser.ASTArrayLiteral;
@@ -30,8 +31,6 @@
 import org.apache.commons.jexl.parser.ASTDivNode;
 import org.apache.commons.jexl.parser.ASTEQNode;
 import org.apache.commons.jexl.parser.ASTEmptyFunction;
-import org.apache.commons.jexl.parser.ASTExpression;
-import org.apache.commons.jexl.parser.ASTExpressionExpression;
 import org.apache.commons.jexl.parser.ASTFalseNode;
 import org.apache.commons.jexl.parser.ASTFloatLiteral;
 import org.apache.commons.jexl.parser.ASTForeachStatement;
@@ -54,12 +53,9 @@
 import org.apache.commons.jexl.parser.ASTNullLiteral;
 import org.apache.commons.jexl.parser.ASTOrNode;
 import org.apache.commons.jexl.parser.ASTReference;
-import org.apache.commons.jexl.parser.ASTReferenceExpression;
 import org.apache.commons.jexl.parser.ASTSizeFunction;
 import org.apache.commons.jexl.parser.ASTSizeMethod;
-import org.apache.commons.jexl.parser.ASTStatementExpression;
 import org.apache.commons.jexl.parser.ASTStringLiteral;
-import org.apache.commons.jexl.parser.ASTSubtractNode;
 import org.apache.commons.jexl.parser.ASTTernaryNode;
 import org.apache.commons.jexl.parser.ASTTrueNode;
 import org.apache.commons.jexl.parser.ASTUnaryMinusNode;
@@ -157,6 +153,25 @@
     }
 
     /**
+     * Adds a statement node to the rebuilt expression.
+     * @param child the child node
+     * @param data visitor pattern argument
+     * @return visitor pattern value
+     */
+    private Object acceptStatement(JexlNode child, Object data) {
+        Object value = accept(child, data);
+        // blocks, if, for & while dont need a ';' at end
+        if (child instanceof ASTBlock
+            || child instanceof ASTIfStatement
+            || child instanceof ASTForeachStatement
+            || child instanceof ASTWhileStatement) {
+            return value;
+        }
+        builder.append(";");
+        return value;
+    }
+
+    /**
      * Checks if a terminal node is the the cause to debug & adds its
      * representation to the rebuilt expression.
      * @param node the child node
@@ -184,28 +199,79 @@
      * adds their representation to the rebuilt expression.
      * @param node the child node
      * @param infix the child node token
+     * @param paren whether the child should be parenthesized
      * @param data visitor pattern argument
      * @return visitor pattern value
      */
-    private Object infixChildren(JexlNode node, String infix, Object data) {
-        int num = node.jjtGetNumChildren();
+    private Object infixChildren(JexlNode node, String infix, boolean paren, Object data)
{
+        int num = node.jjtGetNumChildren(); //child.jjtGetNumChildren() > 1;
+        if (paren) {
+            builder.append("(");
+        }
         for (int i = 0; i < num; ++i) {
             if (i > 0) {
                 builder.append(infix);
             }
             accept(node.jjtGetChild(i), data);
         }
+        if (paren) {
+            builder.append(")");
+        }
+        return data;
+    }
+
+    /**
+     * Checks if the child of a node using prefix notation is the cause to debug,
+     * adds their representation to the rebuilt expression.
+     * @param node the node
+     * @param prefix the node token
+     * @param data visitor pattern argument
+     * @return visitor pattern value
+     */
+    private Object prefixChild(JexlNode node, String prefix, Object data) {
+        boolean paren = node.jjtGetChild(0).jjtGetNumChildren() > 1;
+        builder.append(prefix);
+        if (paren) {
+            builder.append("(");
+        }
+        accept(node.jjtGetChild(0), data);
+        if (paren) {
+            builder.append(")");
+        }
+        return data;
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTAdditiveNode node, Object data) {
+        // need parenthesis if not in operator precedence order
+        boolean paren = node.jjtGetParent() instanceof ASTMulNode
+                        || node.jjtGetParent() instanceof ASTDivNode
+                        || node.jjtGetParent() instanceof ASTModNode;
+        int num = node.jjtGetNumChildren(); //child.jjtGetNumChildren() > 1;
+        if (paren) {
+            builder.append("(");
+        }
+        accept(node.jjtGetChild(0), data);
+        for (int i = 1; i < num; ++i) {
+            accept(node.jjtGetChild(i), data);
+        }
+        if (paren) {
+            builder.append(")");
+        }
         return data;
     }
 
     /** {@inheritDoc} */
-    public Object visit(ASTAddNode node, Object data) {
-        return infixChildren(node, " + ", data);
+    public Object visit(ASTAdditiveOperator node, Object data) {
+        builder.append(' ');
+        builder.append(node.image);
+        builder.append(' ');
+        return data;
     }
 
     /** {@inheritDoc} */
     public Object visit(ASTAndNode node, Object data) {
-        return infixChildren(node, " && ", data);
+        return infixChildren(node, " && ", false, data);
     }
 
     /** {@inheritDoc} */
@@ -235,28 +301,29 @@
     
     /** {@inheritDoc} */
     public Object visit(ASTAssignment node, Object data) {
-        return infixChildren(node, " = ", data);
+        return infixChildren(node, " = ", false, data);
     }
 
     /** {@inheritDoc} */
     public Object visit(ASTBitwiseAndNode node, Object data) {
-        return infixChildren(node, " & ", data);
+        return infixChildren(node, " & ", false, data);
     }
 
     /** {@inheritDoc} */
     public Object visit(ASTBitwiseComplNode node, Object data) {
-        builder.append("~");
-        return accept(node.jjtGetChild(0), data);
+        return prefixChild(node, "~", data);
     }
 
     /** {@inheritDoc} */
     public Object visit(ASTBitwiseOrNode node, Object data) {
-        return infixChildren(node, " | ", data);
+        boolean paren = node.jjtGetParent() instanceof ASTBitwiseAndNode;
+        return infixChildren(node, " | ", paren, data);
     }
 
     /** {@inheritDoc} */
     public Object visit(ASTBitwiseXorNode node, Object data) {
-        return infixChildren(node, " ^ ", data);
+        boolean paren = node.jjtGetParent() instanceof ASTBitwiseAndNode;
+        return infixChildren(node, " ^ ", paren, data);
     }
 
     /** {@inheritDoc} */
@@ -264,7 +331,8 @@
         builder.append("{ ");
         int num = node.jjtGetNumChildren();
         for (int i = 0; i < num; ++i) {
-            accept(node.jjtGetChild(0), data);
+            JexlNode child = node.jjtGetChild(i);
+            acceptStatement(child, data);
         }
         builder.append(" }");
         return data;
@@ -272,7 +340,7 @@
 
     /** {@inheritDoc} */
     public Object visit(ASTDivNode node, Object data) {
-        return infixChildren(node, " / ", data);
+        return infixChildren(node, " / ", false, data);
     }
 
     /** {@inheritDoc} */
@@ -285,26 +353,7 @@
 
     /** {@inheritDoc} */
     public Object visit(ASTEQNode node, Object data) {
-        return infixChildren(node, " == ", data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTExpression node, Object data) {
-        int num = node.jjtGetNumChildren();
-        for (int i = 0; i < num; ++i) {
-            accept(node.jjtGetChild(i), data);
-        }
-        return data;
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTExpressionExpression node, Object data) {
-        int num = node.jjtGetNumChildren();
-        for (int i = 0; i < num; ++i) {
-            accept(node.jjtGetChild(i), data);
-        }
-        builder.append(";");
-        return data;
+        return infixChildren(node, " == ", false, data);
     }
 
     /** {@inheritDoc} */
@@ -319,25 +368,27 @@
 
     /** {@inheritDoc} */
     public Object visit(ASTForeachStatement node, Object data) {
-        builder.append("foreach(");
+        builder.append("for(");
         accept(node.jjtGetChild(0), data);
-        builder.append(" in ");
+        builder.append(" : ");
         accept(node.jjtGetChild(1), data);
         builder.append(") ");
         if (node.jjtGetNumChildren() > 2) {
-            accept(node.jjtGetChild(2), data);
+            acceptStatement(node.jjtGetChild(2), data);
+        } else {
+            builder.append(';');
         }
         return data;
     }
 
     /** {@inheritDoc} */
     public Object visit(ASTGENode node, Object data) {
-        return infixChildren(node, " >= ", data);
+        return infixChildren(node, " >= ", false, data);
     }
 
     /** {@inheritDoc} */
     public Object visit(ASTGTNode node, Object data) {
-        return infixChildren(node, " > ", data);
+        return infixChildren(node, " > ", false, data);
     }
 
     /** {@inheritDoc} */
@@ -347,13 +398,19 @@
 
     /** {@inheritDoc} */
     public Object visit(ASTIfStatement node, Object data) {
-        builder.append("if(");
+        builder.append("if (");
         accept(node.jjtGetChild(0), data);
         builder.append(") ");
-        accept(node.jjtGetChild(1), data);
-        if (node.jjtGetNumChildren() > 2) {
-            builder.append(" else ");
-            accept(node.jjtGetChild(2), data);
+        if (node.jjtGetNumChildren() > 1) {
+            acceptStatement(node.jjtGetChild(1), data);
+            if (node.jjtGetNumChildren() > 2) {
+                builder.append(" else ");
+                acceptStatement(node.jjtGetChild(2), data);
+            } else {
+                builder.append(';');
+            }
+        } else {
+            builder.append(';');
         }
         return data;
     }
@@ -367,25 +424,26 @@
     public Object visit(ASTJexlScript node, Object data) {
         int num = node.jjtGetNumChildren();
         for (int i = 0; i < num; ++i) {
-            accept(node.jjtGetChild(i), data);
+            JexlNode child = node.jjtGetChild(i);
+            acceptStatement(child, data);
         }
         return data;
     }
 
     /** {@inheritDoc} */
     public Object visit(ASTLENode node, Object data) {
-        return infixChildren(node, " <= ", data);
+        return infixChildren(node, " <= ", false, data);
     }
 
     /** {@inheritDoc} */
     public Object visit(ASTLTNode node, Object data) {
-        return infixChildren(node, " < ", data);
+        return infixChildren(node, " < ", false, data);
     }
 
     /** {@inheritDoc} */
     public Object visit(ASTMapEntry node, Object data) {
         accept(node.jjtGetChild(0), data);
-        builder.append(" => ");
+        builder.append(" : ");
         accept(node.jjtGetChild(1), data);
         return data;
     }
@@ -404,15 +462,13 @@
     }
 
     /** {@inheritDoc} */
-    public Object visit(ASTConstructorNode node, Object data) {
+     public Object visit(ASTConstructorNode node, Object data) {
         int num = node.jjtGetNumChildren();
         builder.append("new ");
-        accept(node.jjtGetChild(0), data);
         builder.append("(");
+        accept(node.jjtGetChild(0), data);
         for (int i = 1; i < num; ++i) {
-            if (i > 1) {
-                builder.append(", ");
-            }
+            builder.append(", ");
             accept(node.jjtGetChild(i), data);
         }
         builder.append(")");
@@ -453,17 +509,17 @@
 
     /** {@inheritDoc} */
     public Object visit(ASTModNode node, Object data) {
-        return infixChildren(node, " % ", data);
+        return infixChildren(node, " % ", false, data);
     }
 
     /** {@inheritDoc} */
     public Object visit(ASTMulNode node, Object data) {
-        return infixChildren(node, " * ", data);
+        return infixChildren(node, " * ", false, data);
     }
 
     /** {@inheritDoc} */
     public Object visit(ASTNENode node, Object data) {
-        return infixChildren(node, " != ", data);
+        return infixChildren(node, " != ", false, data);
     }
 
     /** {@inheritDoc} */
@@ -480,8 +536,10 @@
     }
 
     /** {@inheritDoc} */
-    public Object visit(ASTOrNode node, Object data) {
-        return infixChildren(node, " ||", data);
+   public Object visit(ASTOrNode node, Object data) {
+        // need parenthesis if not in operator precedence order
+        boolean paren = node.jjtGetParent() instanceof ASTAndNode;
+        return infixChildren(node, " || ", paren, data);
     }
 
     /** {@inheritDoc} */
@@ -496,18 +554,6 @@
     }
 
     /** {@inheritDoc} */
-    public Object visit(ASTReferenceExpression node, Object data) {
-        int num = node.jjtGetNumChildren();
-        accept(node.jjtGetChild(0), data);
-        for (int i = 1; i < num; ++i) {
-            builder.append(".");
-            accept(node.jjtGetChild(i), data);
-        }
-        builder.append(";");
-        return data;
-    }
-
-    /** {@inheritDoc} */
     public Object visit(ASTSizeFunction node, Object data) {
         builder.append("size(");
         accept(node.jjtGetChild(0), data);
@@ -520,19 +566,7 @@
         check(node, "size()", data);
         return data;
     }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTStatementExpression node, Object data) {
-        int num = node.jjtGetNumChildren();
-        for (int i = 0; i < num; ++i) {
-            accept(node.jjtGetChild(i), data);
-            if (i > 0) {
-                builder.append(";");
-            }
-        }
-        return data;
-    }
-
+    
     /** {@inheritDoc} */
     public Object visit(ASTStringLiteral node, Object data) {
         String img = node.image.replace("'", "\\'");
@@ -540,11 +574,6 @@
     }
 
     /** {@inheritDoc} */
-    public Object visit(ASTSubtractNode node, Object data) {
-        return infixChildren(node, " - ", data);
-    }
-
-    /** {@inheritDoc} */
     public Object visit(ASTTernaryNode node, Object data) {
         accept(node.jjtGetChild(0), data);
         if (node.jjtGetNumChildren() > 2) {
@@ -568,17 +597,19 @@
 
     /** {@inheritDoc} */
     public Object visit(ASTUnaryMinusNode node, Object data) {
-        builder.append("-");
-        accept(node.jjtGetChild(0), data);
-        return data;
+        return prefixChild(node, "-", data);
     }
 
     /** {@inheritDoc} */
     public Object visit(ASTWhileStatement node, Object data) {
-        builder.append("while(");
+        builder.append("while (");
         accept(node.jjtGetChild(0), data);
         builder.append(") ");
-        accept(node.jjtGetChild(1), data);
+        if (node.jjtGetNumChildren() > 1) {
+            acceptStatement(node.jjtGetChild(1), data);
+        } else {
+            builder.append(';');
+        }
         return data;
     }
 

Modified: commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/Interpreter.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/Interpreter.java?rev=809160&r1=809159&r2=809160&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/Interpreter.java
(original)
+++ commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/Interpreter.java
Sat Aug 29 16:59:55 2009
@@ -30,7 +30,8 @@
 import org.apache.commons.logging.Log;
 
 import org.apache.commons.jexl.parser.JexlNode;
-import org.apache.commons.jexl.parser.ASTAddNode;
+import org.apache.commons.jexl.parser.ASTAdditiveNode;
+import org.apache.commons.jexl.parser.ASTAdditiveOperator;
 import org.apache.commons.jexl.parser.ASTAndNode;
 import org.apache.commons.jexl.parser.ASTArrayAccess;
 import org.apache.commons.jexl.parser.ASTArrayLiteral;
@@ -44,8 +45,6 @@
 import org.apache.commons.jexl.parser.ASTDivNode;
 import org.apache.commons.jexl.parser.ASTEQNode;
 import org.apache.commons.jexl.parser.ASTEmptyFunction;
-import org.apache.commons.jexl.parser.ASTExpression;
-import org.apache.commons.jexl.parser.ASTExpressionExpression;
 import org.apache.commons.jexl.parser.ASTFalseNode;
 import org.apache.commons.jexl.parser.ASTFunctionNode;
 import org.apache.commons.jexl.parser.ASTFloatLiteral;
@@ -68,12 +67,9 @@
 import org.apache.commons.jexl.parser.ASTNullLiteral;
 import org.apache.commons.jexl.parser.ASTOrNode;
 import org.apache.commons.jexl.parser.ASTReference;
-import org.apache.commons.jexl.parser.ASTReferenceExpression;
 import org.apache.commons.jexl.parser.ASTSizeFunction;
 import org.apache.commons.jexl.parser.ASTSizeMethod;
-import org.apache.commons.jexl.parser.ASTStatementExpression;
 import org.apache.commons.jexl.parser.ASTStringLiteral;
-import org.apache.commons.jexl.parser.ASTSubtractNode;
 import org.apache.commons.jexl.parser.ASTTernaryNode;
 import org.apache.commons.jexl.parser.ASTTrueNode;
 import org.apache.commons.jexl.parser.ASTUnaryMinusNode;
@@ -205,8 +201,8 @@
         return node;
     }
 
-    /** {@inheritDoc} */
-    public Object visit(ASTAddNode node, Object data) {
+/** {@inheritDoc} */
+    public Object visit(ASTAdditiveNode node, Object data) {
         /**
          * The pattern for exception mgmt is to let the child*.jjtAccept
          * out of the try/catch loop so that if one fails, the ex will
@@ -215,13 +211,34 @@
          * be caught explicitly and rethrown.
          */
         Object left = node.jjtGetChild(0).jjtAccept(this, data);
-        Object right = node.jjtGetChild(1).jjtAccept(this, data);
-        try {
-            return arithmetic.add(left, right);
-        } catch (RuntimeException xrt) {
-            JexlNode xnode = findNullOperand(xrt, node, left, right);
-            throw new JexlException(xnode, "add error", xrt);
+        for(int c = 2, size = node.jjtGetNumChildren(); c < size; c += 2) {
+            Object right = node.jjtGetChild(c).jjtAccept(this, data);
+            try {
+                JexlNode op = node.jjtGetChild(c - 1);
+                if (op instanceof ASTAdditiveOperator) {
+                    String which = ((ASTAdditiveOperator) op).image;
+                    if ("+".equals(which)) {
+                        left = arithmetic.add(left, right);
+                        continue;
+                    }
+                    if ("-".equals(which)) {
+                        left = arithmetic.subtract(left, right);
+                        continue;
+                    }
+                    throw new UnsupportedOperationException("unknown operator " + which);
+                }
+                throw new IllegalArgumentException("unknown operator " + op);
+            } catch (RuntimeException xrt) {
+                JexlNode xnode = findNullOperand(xrt, node, left, right);
+                throw new JexlException(xnode, "+/- error", xrt);
+            }
         }
+        return left;
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTAdditiveOperator node, Object data) {
+        throw new UnsupportedOperationException("Shoud not be called.");
     }
 
     /** {@inheritDoc} */
@@ -504,16 +521,6 @@
     }
 
     /** {@inheritDoc} */
-    public Object visit(ASTExpression node, Object data) {
-        return node.jjtGetChild(0).jjtAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTExpressionExpression node, Object data) {
-        return node.jjtGetChild(0).jjtAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
     public Object visit(ASTFalseNode node, Object data) {
         return Boolean.FALSE;
     }
@@ -1015,11 +1022,6 @@
     }
 
     /** {@inheritDoc} */
-    public Object visit(ASTReferenceExpression node, Object data) {
-        return node.jjtGetChild(0).jjtAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
     public Object visit(ASTSizeFunction node, Object data) {
         Object val = node.jjtGetChild(0).jjtAccept(this, data);
 
@@ -1036,28 +1038,11 @@
     }
 
     /** {@inheritDoc} */
-    public Object visit(ASTStatementExpression node, Object data) {
-        return node.jjtGetChild(0).jjtAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
     public Object visit(ASTStringLiteral node, Object data) {
         return node.image;
     }
 
     /** {@inheritDoc} */
-    public Object visit(ASTSubtractNode node, Object data) {
-        Object left = node.jjtGetChild(0).jjtAccept(this, data);
-        Object right = node.jjtGetChild(1).jjtAccept(this, data);
-        try {
-            return arithmetic.subtract(left, right);
-        } catch (RuntimeException xrt) {
-            JexlNode xnode = findNullOperand(xrt, node, left, right);
-            throw new JexlException(xnode, "- error", xrt);
-        }
-    }
-
-    /** {@inheritDoc} */
     public Object visit(ASTTernaryNode node, Object data) {
         Object condition = node.jjtGetChild(0).jjtAccept(this, data);
         if (node.jjtGetNumChildren() == 3) {

Modified: commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/JexlEngine.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/JexlEngine.java?rev=809160&r1=809159&r2=809160&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/JexlEngine.java
(original)
+++ commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/JexlEngine.java
Sat Aug 29 16:59:55 2009
@@ -435,7 +435,7 @@
         expr = r0 + (expr.charAt(0) == '[' ? "" : ".") + expr + ";";
         try {
             JexlNode tree = parse(expr, null);
-            JexlNode node = tree.jjtGetChild(0).jjtGetChild(0);
+            JexlNode node = tree.jjtGetChild(0);
             Interpreter interpreter = createInterpreter(context);
             // ensure 4 objects in register array
             Object[] r = {r0, bean, r0, bean};
@@ -502,7 +502,7 @@
         expr = r0 + (expr.charAt(0) == '[' ? "" : ".") + expr + "=" + r1 + ";";
         try {
             JexlNode tree = parse(expr, null);
-            JexlNode node = tree.jjtGetChild(0).jjtGetChild(0);
+            JexlNode node = tree.jjtGetChild(0);
             Interpreter interpreter = createInterpreter(context);
             // set the registers
             Object[] r = {r0, bean, r1, value};
@@ -570,7 +570,7 @@
                 }
             }
             try {
-                Reader reader = expr.endsWith(";") ? new StringReader(expr) : new StringReader(expr
+ ";");
+                Reader reader = new StringReader(expr);
                 // use first calling method of JexlEngine as debug info
                 if (info == null && debug) {
                     Throwable xinfo = new Throwable();

Modified: commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/parser/Parser.jjt
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/parser/Parser.jjt?rev=809160&r1=809159&r2=809160&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/parser/Parser.jjt
(original)
+++ commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/parser/Parser.jjt
Sat Aug 29 16:59:55 2009
@@ -43,10 +43,7 @@
 
 public class Parser extends StringParser
 {
-    /** Base debug information. */
-    protected Info debug = null;
-
-    public JexlNode parse(Reader reader, Info info)
+    public ASTJexlScript parse(Reader reader, Info info)
         throws ParseException
     {
         ReInit(reader);
@@ -55,7 +52,7 @@
          *  safe - it's a pain to remember
          */
 
-        JexlNode tree = JexlScript();
+        ASTJexlScript tree = JexlScript();
         tree.value = info;
         return tree;
     }
@@ -64,6 +61,10 @@
 PARSER_END(Parser)
 
 
+/***************************************
+ *     Skip & Number literal tokens
+ ***************************************/
+
 SKIP : /* WHITE SPACE */
 {
   <COMMENT: ( "##" ( ~["\"","\n","\r"] )* ("\n" | "\r") ) >
@@ -83,27 +84,21 @@
   < FLOAT_LITERAL: (<DIGIT>)+ "."(<DIGIT>)+ >
 }
 
-/*
- * Program structuring syntax follows.
- */
 
-JexlNode JexlScript() :
-{
-   String name;
-}
+/***************************************
+ *      Program
+ ***************************************/
+
+ASTJexlScript JexlScript() : {}
 {
-    (
-       Statement()
-    )*
-    <EOF>
+   ( Statement() )* <EOF>
    { return jjtThis;}
 }
 
 
-void Block() :
-{}
+void Block() #Block : {}
 {
-  "{" ( Statement() )* "}"
+    "{" ( Statement() )* "}"
 }
 
 void EmptyFunction() : {}
@@ -127,16 +122,11 @@
 }
 
 
-/*
- * Expression syntax follows.
- */
-
-void Expression() : {}
+void Expression() #void : {}
 {
-        LOOKAHEAD( Reference() "=" )
-  Assignment()
+    LOOKAHEAD( Reference() "=" )  Assignment()
 |
-  ConditionalOrExpression()
+    ConditionalExpression()
 }
 
 
@@ -145,6 +135,20 @@
   Reference() "=" Expression()
 }
 
+/***************************************
+ *      Conditional & relational
+ ***************************************/
+
+void ConditionalExpression() #void : {}
+{
+  ConditionalOrExpression()
+  (
+    "?" Expression() ":" Expression() #TernaryNode(3)
+  |
+    "?:" Expression() #TernaryNode(2)
+  )?
+}
+
 void ConditionalOrExpression() #void :
 {}
 {
@@ -153,11 +157,6 @@
     "||" ConditionalAndExpression() #OrNode(2)
   |
     "or" ConditionalAndExpression() #OrNode(2)
-  )*
-  (
-    "?" Expression() ":" Expression() #TernaryNode(3)
-  |
-    "?:" Expression() #TernaryNode(2)
   )?
 }
 
@@ -169,28 +168,28 @@
     "&&" InclusiveOrExpression() #AndNode(2)
   |
     "and" InclusiveOrExpression() #AndNode(2)
-  )*
+  )?
 }
 
 void InclusiveOrExpression() #void :
 {}
 {
   ExclusiveOrExpression()
-  ( "|" ExclusiveOrExpression() #BitwiseOrNode(2) )*
+  ( "|" ExclusiveOrExpression() #BitwiseOrNode(2) )?
 }
 
 void ExclusiveOrExpression() #void :
 {}
 {
   AndExpression()
-  ( "^" AndExpression() #BitwiseXorNode(2) )*
+  ( "^" AndExpression() #BitwiseXorNode(2) )?
 }
 
 void AndExpression() #void :
 {}
 {
   EqualityExpression()
-  ( "&" EqualityExpression() #BitwiseAndNode(2) )*
+  ( "&" EqualityExpression() #BitwiseAndNode(2) )?
 }
 
 void EqualityExpression() #void :
@@ -205,7 +204,7 @@
      "!=" RelationalExpression() #NENode(2)
    |
      "ne" RelationalExpression() #NENode(2)
-  )*
+  )?
 }
 
 void RelationalExpression() #void :
@@ -228,18 +227,23 @@
     ">=" AdditiveExpression() #GENode(2)
    |
     "ge" AdditiveExpression() #GENode(2)
-  )*
+  )?
 }
 
-void AdditiveExpression() #void :
-{}
+/***************************************
+ *      Arithmetic
+ ***************************************/
+
+void AdditiveExpression() #AdditiveNode(>1) : {}
 {
-  MultiplicativeExpression()
-  (
-    "+" MultiplicativeExpression() #AddNode(2)
-   |
-    "-" MultiplicativeExpression() #SubtractNode(2)
-  )*
+    MultiplicativeExpression() ( LOOKAHEAD(1) AdditiveOperator() MultiplicativeExpression())*
+}
+
+void AdditiveOperator() : {}
+{
+    "+" { jjtThis.image = "+"; }
+|
+    "-" { jjtThis.image = "-"; }
 }
 
 void MultiplicativeExpression() #void :
@@ -256,7 +260,7 @@
     "%" UnaryExpression() #ModNode(2)
    |
     "mod" UnaryExpression() #ModNode(2)
-  )*
+  )?
 }
 
 void UnaryExpression() #void :
@@ -273,13 +277,11 @@
   PrimaryExpression()
 }
 
-void PrimaryExpression() #void :
-{}
+void PrimaryExpression() #void : {}
 {
   Literal()
 |
-  LOOKAHEAD(3)
-  Reference()
+  LOOKAHEAD(3)  Reference()
 |
   LOOKAHEAD("(") "(" Expression() ")"
 |
@@ -289,14 +291,16 @@
 |
   LOOKAHEAD("new" "(") Constructor()
 |
-  LOOKAHEAD( "{" MapEntry() ( "," MapEntry() )* "}" )
-    MapLiteral()
+  LOOKAHEAD( "{" MapEntry() ) MapLiteral()
 |
-  LOOKAHEAD( "[" Parameter() ( "," Parameter() )* "]" )
-    ArrayLiteral()
+  LOOKAHEAD( "[" Expression() ) ArrayLiteral()
 }
 
 
+/***************************************
+ *      Literals
+ ***************************************/
+
 void Literal() #void :
 {
    Token t;
@@ -331,10 +335,8 @@
   Token t;
 }
 {
- (
   t=<INTEGER_LITERAL>
   { jjtThis.image = t.image; }
- )
 }
 
 void FloatLiteral() :
@@ -342,10 +344,8 @@
   Token t;
 }
 {
- (
   t=<FLOAT_LITERAL>
   { jjtThis.image = t.image; }
- )
 }
 
 void StringLiteral() :
@@ -353,76 +353,52 @@
    Token t;
 }
 {
- (
   t=<STRING_LITERAL>
   { jjtThis.image = Parser.buildString(t.image, true); }
- )
 }
 
-/*
- * Statement syntax follows.
- */
+/***************************************
+ *      Statements
+ ***************************************/
 
-void Statement() #void :
-{}
+void Statement() #void : {}
 {
-  ";"
-|
-  LOOKAHEAD(3)
-  Block()
-|
-  LOOKAHEAD( Reference() ";" ) ReferenceExpression()
-|
-  LOOKAHEAD( Reference() "=" ) StatementExpression()
-|
-  ExpressionExpression()
-|
-  IfStatement()
-|
-  ForeachStatement()
-|
-  WhileStatement()
+    ";"
+    | LOOKAHEAD(3) Block()
+    | IfStatement()
+    | ForeachStatement()
+    | WhileStatement()
+    | ExpressionStatement()
 }
 
 
-void ExpressionExpression() : {}
-{
-    Expression() ";"
-}
-
-void StatementExpression() : {}
+void ExpressionStatement() #void : {}
 {
-  Assignment() ";"
+    Expression() (LOOKAHEAD(2) ";")?
 }
 
-void ReferenceExpression() : {}
-{
-  Reference() ";"
-}
 
-void IfStatement() :{}
+void IfStatement() : {}
 {
-  "if" "(" Expression() ")" Statement() [ LOOKAHEAD(1) "else" Statement() ]
+    "if" "(" Expression() ")" Statement() ( LOOKAHEAD(1) "else" Statement() )?
 }
 
 
-void WhileStatement() :
-{}
+void WhileStatement() : {}
 {
   "while" "(" Expression() ")" Statement()
 }
 
-void ForeachStatement() :
-{}
+void ForeachStatement() : {}
 {
-  "for" "(" Reference() ":"  Reference() ")" Statement()
+    "for" "(" Reference() ":"  Expression() ")" Statement()
 |
-  "foreach" "(" Reference() "in"  Reference() ")" Statement()
+    "foreach" "(" Reference() "in"  Expression() ")" Statement()
 }
 
 void ArrayLiteral() : {}
 {
-  "[" Parameter() ( "," Parameter() )* "]"
+  "[" Expression() ( "," Expression() )* "]"
 }
 
 void MapLiteral() : {}
@@ -432,22 +408,22 @@
 
 void MapEntry() : {}
 {
-    Parameter() ":" Parameter()
+    Expression() ":" Expression()
 }
 
 void Method() #MethodNode: {}
 {
-   Identifier() "("[ Parameter() ( "," Parameter() )* ] ")"
+   Identifier() "("[ Expression() ( "," Expression() )* ] ")"
 }
 
 void Function() #FunctionNode: {}
 {
-   Identifier() ":" Identifier() "("[ Parameter() ( "," Parameter() )* ] ")"
+   Identifier() ":" Identifier() "("[ Expression() ( "," Expression() )* ] ")"
 }
 
 void ArrayAccess() : {}
 {
-    Identifier() ("[" ( LOOKAHEAD(3) Expression() | IntegerLiteral() | Reference() ) "]")+
+   Identifier() (LOOKAHEAD(2) "[" Expression() "]")+
 }
 
 void AnyMethod() #void : {}
@@ -459,7 +435,7 @@
 
 void Constructor() # ConstructorNode() : {}
 {
-  "new" "("[ Parameter() ( "," Parameter() )* ] ")"
+  "new" "("[ Expression() ( "," Expression() )* ] ")"
 }
 
 void SizeMethod() : {}
@@ -469,26 +445,43 @@
 
 void Reference() : {}
 {
-  (LOOKAHEAD("new") Constructor() |
-   LOOKAHEAD(Identifier() "[" ( Expression() | IntegerLiteral() | Reference()) "]") ArrayAccess()
|
-   LOOKAHEAD(Identifier() ":" Identifier() "(") Function() |
-   LOOKAHEAD(Identifier() "(") Method() |
-   Identifier() |
-   MapLiteral())
-  (LOOKAHEAD(2) "."
-    (
-      LOOKAHEAD(Identifier() "[" ( Expression() | IntegerLiteral() | Reference()) "]") ArrayAccess()
|
-      (LOOKAHEAD(3) AnyMethod() | Identifier() |  IntegerLiteral() )
-    )
-  )*
+  ( LOOKAHEAD("new") Constructor()
+|
+   LOOKAHEAD(Identifier() "[" ) ArrayAccess()
+|
+   LOOKAHEAD(Identifier() ":" Identifier() "(") Function()
+|
+   LOOKAHEAD(Identifier() "(") Method()
+|
+   Identifier()
+|
+   LOOKAHEAD("{") MapLiteral()
+|
+   LOOKAHEAD("[") ArrayLiteral() ) DotReference()
 }
 
-
-void Parameter() #void: {}
+void DotReference() #void : {}
 {
-   LOOKAHEAD(3) Expression() |  Literal() | Reference()
+  ("."
+     ( LOOKAHEAD(Identifier() "[" )
+         ArrayAccess()
+       |
+       ( LOOKAHEAD(3)
+            AnyMethod()
+          |
+            Identifier()
+          |
+            IntegerLiteral()
+        )
+      )
+  )*
 }
 
+
+/***************************************
+ *     Identifier & String tokens
+ ***************************************/
+
 TOKEN : /* IDENTIFIERS */
 {
   < IDENTIFIER: <LETTER> (<LETTER>|<DIGIT>)* >
@@ -501,8 +494,8 @@
 TOKEN :
 {
     <STRING_LITERAL :
-        ("\"" ( ~["\"","\n","\r"] | "\\" ["n","t","b","r","f","\\","\""] )* "\"" )
+        ("\"" ( ~["\"","\n","\r"] | "\\" ["u","n","t","b","r","f","\\","\""] )* "\"" )
      |
-        ("\'" ( ~["\'","\n","\r"] | "\\" ["n","t","b","r","f","\\","\'"])* "\'" )
+        ("\'" ( ~["\'","\n","\r"] | "\\" ["u","n","t","b","r","f","\\","\'"])* "\'" )
     >
 }



Mime
View raw message