Понадобился язык с кастрированным LDAP search syntax'ом.
Краткое описание 'языка':
<логическая операция> = '>=' или '>' или '<=' или '<' или '='
<Простое выражение> = '('<имя свойства><логическая операция><константа>')'
<композитная операция>= '|' или '&' или '!'
<Составное выражение> = '('<композитная операция><Простое|Составное выражение>(<Простое|Составное выражение>)*')'
Смеха ради, решил написать породию на парсер комбинаторы из хаскелл, которая позволила бы из строки сразу получать выражение, готовое для вычислений.
Получился такой дикабраз (простыни кода поддержки благоразумно спрятал :)):
static final Parser/*String*/ positive_integer_ = wordOf("0123456789");
static final Parser/*String*/ integer_ = or(positive_integer_,
seq(STR_CONCAT,
eq("-"), positive_integer_));
static final Parser/*Double*/ double_ = seq(STR_CONCAT,
integer_, opt(0, 1, seq(STR_CONCAT,
eq("."), positive_integer_))).wrap(MAKE_DOUBLE);
static final Parser/*String*/ text_ = wordOf("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz?*");
static final Parser/*String*/ ref_ = wordOf("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.");
static final Parser/*SimpleP*/ simpleExpr_ =
seq(SimpleP.MAKE,
eq("("), ref_, or(eq(">="), eq(">"), eq("<="), eq("<"), eq("=")), or(double_, text_), eq(")"));
static Parser ref_compositeExpr_ = new Parser() // trick to allow recursive references ...
{
Pair apply_(String chars)
{
return compositeExpr_.apply_(chars);
}
};
static Parser/*CompositeP*/ compositeExpr_ =
seq(CompositeP.MAKE,
eq("("), or(eq("!"), eq("&"), eq("|")), opt(1, Integer.MAX_VALUE, or(simpleExpr_, ref_compositeExpr_)), eq(")"));
static final Parser/*Predicate*/ expr_ = or(simpleExpr_, compositeExpr_);
Использование:
String expr = "(&(a>=5)(a<10))";
Predicate p = (Predicate) expr_.apply_(expr).left;
int a = 7;
System.out.println(expr + " with a = " + a + " := " + e.eval(FP_.newFMap().pair("a", a)));
Ну, чем не хаскелл? :)))