И что сказал, что java не ФП ? :)
От: NotGonnaGetUs  
Дата: 14.01.09 16:19
Оценка:
Понадобился язык с кастрированным 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)));


Ну, чем не хаскелл? :)))
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.