]> source.dussan.org Git - jackcess.git/commitdiff
impl obj ref parsing
authorJames Ahlborn <jtahlborn@yahoo.com>
Fri, 16 Sep 2016 01:33:32 +0000 (01:33 +0000)
committerJames Ahlborn <jtahlborn@yahoo.com>
Fri, 16 Sep 2016 01:33:32 +0000 (01:33 +0000)
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/branches/exprs@1038 f203690c-595d-4dc9-a70b-905162fa7fd2

src/main/java/com/healthmarketscience/jackcess/util/ExpressionTokenizer.java
src/main/java/com/healthmarketscience/jackcess/util/Expressionator.java

index 60d6f3fde153118ad8dabeb5f7702129e4182a4f..b55f674314b411b7934b81523f0d14b6e0cc4f87 100644 (file)
@@ -482,6 +482,10 @@ class ExpressionTokenizer
       return _val;
     }
 
+    public String getValueStr() {
+      return (String)_val;
+    }
+
     @Override
     public String toString() {
       if(_type == TokenType.SPACE) {
index 0fd88c51b2b4b2fd34f2f9e4b9b5974f4eb216c3..5621cbc727411ca50274dd620ac8a5c524653304 100644 (file)
@@ -153,13 +153,30 @@ public class Expressionator
 
       switch(t.getType()) {
       case OBJ_NAME:
+
+        buf.setPendingExpr(parseObjectReference(t, buf));
         break;
+
       case LITERAL:
+        
+        buf.setPendingExpr(new ELiteralValue(t.getValue()));
         break;
+        
       case OP:
+
+        WordType wordType = getWordType(t);
+        if(wordType == null) {
+          // shouldn't happen
+          throw new RuntimeException("Invalid operator " + t);
+        }
+
+        
         break;
+        
       case STRING:
-        WordType wordType = getWordType(t);
+
+        // see if it's a special word?
+        wordType = getWordType(t);
         if(wordType == null) {
           // literal string? or possibly function?
           Expr funcExpr = maybeParseFuncCall(t, buf, exprType, isSimpleExpr);
@@ -167,25 +184,68 @@ public class Expressionator
             buf.setPendingExpr(funcExpr);
             continue;
           }
+
+          // FIXME maybe obj name, maybe string?
+          
+        } else {
+        
+        
           // FIXME
         }
+
         break;
+        
       case SPACE:
-        // top-level space is irrelevant
+        // top-level space is irrelevant (and we strip them anyway)
         break;
+        
       default:
-        throw new RuntimeException("unknown token type " + t.getType());
+        throw new RuntimeException("unknown token type " + t);
       }
     }
 
     Expr expr = buf.takePendingExpr();
     if(expr == null) {
-      throw new IllegalArgumentException("No expression found?");
+      throw new IllegalArgumentException("No expression found? " + buf);
     }
 
     return expr;
   }
 
+  private static Expr parseObjectReference(Token firstTok, TokBuf buf) {
+
+    // object references may be joined by '.' or '!';
+    List<String> objNames = new ArrayList<String>();
+    objNames.add(firstTok.getValueStr());
+
+    Token t = null;
+    boolean atSep = false;
+    while((t = buf.peekNext()) != null) {
+      if(!atSep) {
+        if(isOp(t, ".") || isOp(t, "!")) {
+          buf.next();
+          atSep = true;
+          continue;
+        } 
+      } else {
+        if((t.getType() == TokenType.OBJ_NAME) ||
+           (t.getType() == TokenType.STRING)) {
+          buf.next();
+          objNames.add(t.getValueStr());
+          atSep = false;
+          continue;
+        }
+      }
+      break;
+    }
+
+    if(atSep) {
+      throw new IllegalArgumentException("Invalid object reference " + buf);
+    }
+    
+    return new EObjValue(objNames);
+  }
+  
   private static Expr maybeParseFuncCall(Token firstTok, TokBuf buf,
                                          Type exprType, boolean isSimpleExpr) {
 
@@ -210,7 +270,7 @@ public class Expressionator
         }
       }
         
-      return new EFunc((String)firstTok.getValue(), params);
+      return new EFunc(firstTok.getValueStr(), params);
 
     } finally {
       if(!foundFunc) {
@@ -254,7 +314,7 @@ public class Expressionator
             for(TokBuf paramBuf : params) {
               if(!paramBuf.hasNext()) {
                 throw new IllegalArgumentException(
-                    "Invalid empty parameter for function");
+                    "Invalid empty parameter for function " + paramBuf);
               }
             }
           }
@@ -270,7 +330,7 @@ public class Expressionator
     }
 
     throw new IllegalArgumentException("Missing closing '" + FUNC_END_DELIM +
-                                       "' for function call");
+                                       "' for function call " + buf);
   }
 
   private static boolean isSimpleExpression(TokBuf buf, Type exprType) {
@@ -290,12 +350,11 @@ public class Expressionator
   }
 
   private static boolean isOp(Token t, String opStr) {
-    return ((t.getType() == TokenType.OP) && 
-            opStr.equalsIgnoreCase((String)t.getValue()));
+    return ((t.getType() == TokenType.OP) && opStr.equalsIgnoreCase(t.getValueStr()));
   }
 
   private static WordType getWordType(Token t) {
-    return WORD_TYPES.get(((String)t.getValue()).toLowerCase());
+    return WORD_TYPES.get(t.getValueStr().toLowerCase());
   }
 
   private static void setWordType(WordType type, String... words) {
@@ -307,21 +366,21 @@ public class Expressionator
   private static final class TokBuf
   {
     private final List<Token> _tokens;
-    private final boolean _topLevel;
+    private final TokBuf _parent;
     private int _pos;
     private Expr _pendingExpr;
 
     private TokBuf(List<Token> tokens) {
-      this(tokens, true);
+      this(tokens, null);
     }
 
-    private TokBuf(List<Token> tokens, boolean topLevel) {
+    private TokBuf(List<Token> tokens, TokBuf parent) {
       _tokens = tokens;
-      _topLevel = topLevel;
+      _parent = parent;
     }
 
     public boolean isTopLevel() {
-      return _topLevel;
+      return (_parent == null);
     }
 
     public int curPos() {
@@ -352,12 +411,13 @@ public class Expressionator
     }
 
     public TokBuf subBuf(int start, int end) {
-      return new TokBuf(_tokens.subList(start, end), false);
+      return new TokBuf(_tokens.subList(start, end), this);
     }
 
     public void setPendingExpr(Expr expr) {
       if(_pendingExpr == null) {
-        throw new IllegalArgumentException("Found multiple expressions with no operator");
+        throw new IllegalArgumentException(
+            "Found multiple expressions with no operator " + this);
       }
       _pendingExpr = expr;
     } 
@@ -371,6 +431,12 @@ public class Expressionator
     public boolean hasPendingExpr() {
       return (_pendingExpr != null);
     }
+
+    @Override
+    public String toString() {
+      // FIXME show current pos
+      return null;
+    } 
   }
 
   public static abstract class Expr
@@ -415,17 +481,19 @@ public class Expressionator
     }
   }
 
-  private static final class EColumnValue extends Expr
+  private static final class EObjValue extends Expr
   {
-    private final String _colName;
+    private final List<String> _objNames;
 
-    private EColumnValue(String colName) {
-      _colName = colName;
+    private EObjValue(List<String> objNames) {
+      _objNames = objNames;
     }
 
     @Override
     public Object eval(RowContext ctx) {
-      return ctx.getRowValue(_colName);
+      // FIXME
+      return null;
+      // return ctx.getRowValue(_colName);
     }
   }