소스 검색

impl obj ref parsing

git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/branches/exprs@1038 f203690c-595d-4dc9-a70b-905162fa7fd2
tags/jackcess-2.2.0
James Ahlborn 7 년 전
부모
커밋
6fbbe53848

+ 4
- 0
src/main/java/com/healthmarketscience/jackcess/util/ExpressionTokenizer.java 파일 보기

@@ -482,6 +482,10 @@ class ExpressionTokenizer
return _val;
}

public String getValueStr() {
return (String)_val;
}

@Override
public String toString() {
if(_type == TokenType.SPACE) {

+ 90
- 22
src/main/java/com/healthmarketscience/jackcess/util/Expressionator.java 파일 보기

@@ -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);
}
}


Loading…
취소
저장