Browse Source

add ability to get original expression; implement some parsing tests

git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@1181 f203690c-595d-4dc9-a70b-905162fa7fd2
tags/jackcess-2.2.0
James Ahlborn 5 years ago
parent
commit
37338c5a25

+ 3
- 1
src/main/java/com/healthmarketscience/jackcess/expr/Expression.java View File

@@ -22,12 +22,14 @@ import java.util.Collection;
*
* @author James Ahlborn
*/
public interface Expression
public interface Expression
{
public Object eval(EvalContext ctx);

public String toDebugString();

public String toRawString();

public boolean isConstant();

public void collectIdentifiers(Collection<Identifier> identifiers);

+ 4
- 0
src/main/java/com/healthmarketscience/jackcess/impl/BaseEvalContext.java View File

@@ -195,6 +195,10 @@ public abstract class BaseEvalContext implements EvalContext
return "<raw>{" + _exprStr + "}";
}

public String toRawString() {
return _exprStr;
}

public boolean isConstant() {
return getExpr().isConstant();
}

+ 22
- 15
src/main/java/com/healthmarketscience/jackcess/impl/expr/Expressionator.java View File

@@ -427,7 +427,7 @@ public class Expressionator

// this is handled as a literal string value, not an expression. no
// need to memo-ize cause it's a simple literal value
return new ExprWrapper(
return new ExprWrapper(exprStr,
new ELiteralValue(Value.Type.STRING, exprStr, null), resultType);
}

@@ -447,15 +447,15 @@ public class Expressionator
return (expr.isConstant() ?
// for now, just cache at top-level for speed (could in theory
// cache intermediate values?)
new MemoizedExprWrapper(expr, resultType) :
new ExprWrapper(expr, resultType));
new MemoizedExprWrapper(exprStr, expr, resultType) :
new ExprWrapper(exprStr, expr, resultType));
case FIELD_VALIDATOR:
case RECORD_VALIDATOR:
return (expr.isConstant() ?
// for now, just cache at top-level for speed (could in theory
// cache intermediate values?)
new MemoizedCondExprWrapper(expr) :
new CondExprWrapper(expr));
new MemoizedCondExprWrapper(exprStr, expr) :
new CondExprWrapper(exprStr, expr));
default:
throw new ParseException("unexpected expression type " + exprType);
}
@@ -910,7 +910,7 @@ public class Expressionator
t = buf.next();
}
if(!isDelim(t, OPEN_PAREN)) {
throw new ParseException("Malformed In expression " + buf);
throw new ParseException("Malformed 'In' expression " + buf);
}

List<Expr> exprs = findParenExprs(buf, true);
@@ -2007,9 +2007,11 @@ public class Expressionator
*/
private static abstract class BaseExprWrapper implements Expression
{
private final String _rawExprStr;
private final Expr _expr;

private BaseExprWrapper(Expr expr) {
private BaseExprWrapper(String rawExprStr, Expr expr) {
_rawExprStr = rawExprStr;
_expr = expr;
}

@@ -2017,6 +2019,10 @@ public class Expressionator
return _expr.toDebugString();
}

public String toRawString() {
return _rawExprStr;
}

public boolean isConstant() {
return _expr.isConstant();
}
@@ -2080,8 +2086,8 @@ public class Expressionator
{
private final Value.Type _resultType;

private ExprWrapper(Expr expr, Value.Type resultType) {
super(expr);
private ExprWrapper(String rawExprStr, Expr expr, Value.Type resultType) {
super(rawExprStr, expr);
_resultType = resultType;
}

@@ -2096,8 +2102,8 @@ public class Expressionator
*/
private static class CondExprWrapper extends BaseExprWrapper
{
private CondExprWrapper(Expr expr) {
super(expr);
private CondExprWrapper(String rawExprStr, Expr expr) {
super(rawExprStr, expr);
}

public Object eval(EvalContext ctx) {
@@ -2113,8 +2119,9 @@ public class Expressionator
{
private Object _val;

private MemoizedExprWrapper(Expr expr, Value.Type resultType) {
super(expr, resultType);
private MemoizedExprWrapper(String rawExprStr, Expr expr,
Value.Type resultType) {
super(rawExprStr, expr, resultType);
}

@Override
@@ -2134,8 +2141,8 @@ public class Expressionator
{
private Object _val;

private MemoizedCondExprWrapper(Expr expr) {
super(expr);
private MemoizedCondExprWrapper(String rawExprStr, Expr expr) {
super(rawExprStr, expr);
}

@Override

+ 2
- 0
src/test/java/com/healthmarketscience/jackcess/impl/expr/DefaultFunctionsTest.java View File

@@ -33,6 +33,8 @@ public class DefaultFunctionsTest extends TestCase
super(name);
}

// FIXME, test more number/string functions

public void testFuncs() throws Exception
{
assertEquals("foo", eval("=IIf(10 > 1, \"foo\", \"bar\")"));

+ 31
- 0
src/test/java/com/healthmarketscience/jackcess/impl/expr/ExpressionatorTest.java View File

@@ -31,6 +31,7 @@ import com.healthmarketscience.jackcess.expr.EvalContext;
import com.healthmarketscience.jackcess.expr.Expression;
import com.healthmarketscience.jackcess.expr.FunctionLookup;
import com.healthmarketscience.jackcess.expr.Identifier;
import com.healthmarketscience.jackcess.expr.ParseException;
import com.healthmarketscience.jackcess.expr.TemporalConfig;
import com.healthmarketscience.jackcess.expr.Value;
import com.healthmarketscience.jackcess.impl.BaseEvalContext;
@@ -462,6 +463,35 @@ public class ExpressionatorTest extends TestCase
br.close();
}

public void testInvalidExpressions() throws Exception
{
doTestEvalFail("", "empty");
doTestEvalFail("=", "found?");
doTestEvalFail("=(34 + 5", "closing");
doTestEvalFail("=(34 + )", "found?");
doTestEvalFail("=(34 + [A].[B].[C].[D])", "object reference");
doTestEvalFail("=34 + 5,", "delimiter");
doTestEvalFail("=Foo()", "find function");
doTestEvalFail("=(/37)", "left expression");
doTestEvalFail("=(>37)", "left expression");
doTestEvalFail("=(And 37)", "left expression");
doTestEvalFail("=37 In 42", "'In' expression");
doTestEvalFail("=37 Between 42", "'Between' expression");
doTestEvalFail("=(3 + 5) Rnd()", "multiple expressions");
// doTestEvalFail("=Blah", "");
}

private static void doTestEvalFail(String exprStr, String msgStr) {
try {
eval(exprStr);
fail("ParseException should have been thrown");
} catch(ParseException pe) {
// success
System.out.println("FOO " + pe);
assertTrue(pe.getMessage().contains(msgStr));
}
}

private static void validateExpr(String exprStr, String debugStr) {
validateExpr(exprStr, debugStr, exprStr);
}
@@ -479,6 +509,7 @@ public class ExpressionatorTest extends TestCase
assertEquals(debugStr, foundDebugStr);
}
assertEquals(cleanStr, expr.toString());
assertEquals(exprStr, expr.toRawString());
}

static Object eval(String exprStr) {

Loading…
Cancel
Save