Слюни логическое сравнение - PullRequest
0 голосов
/ 31 декабря 2018

Почему false == (cancelationCode == 'C') отличается от
от (cancelationCode == 'C') == false?

Это ошибка в слюнах 6.5.0 или я что-то упустил?


Вот полныйstory:

Я использую Drools DSL, и мне нужно реализовать правило:

rule "my business rule"
    dialect "mvel"
    when
        There is a trade that
        - Supervised Trade
        ...
    then
        ...
end

У меня есть следующие определения DSL:

[when] Supervised Trade = 
    Customer Trade 
    AND NOT Canceled 

[when] Customer Trade = (recordTypeCode is equal to '910')
[when] Canceled = (cancellationCode is equal to 'C')

[when] is equal to = ==

[when] {var1}?(?<![\w'])\s*AND\s*(?![\w']){var2}? = {var1} && {var2}
[when] {var1}?(?<![\w'])\s*OR\s*(?![\w']){var2}? = {var1} || {var2}
[when] {var1}?(?<![\w'])\s*NOT\s*(?![\w']){var2}? = {var1} false == {var2}

Требованияписать многократно используемые операторы DSL в позитивном ключе и иметь возможность отрицать их.

Изначально НЕ было реализовано как !, и оно работало для текущего сценария.Но оно не работало для случаев, подобных buySellTypeCode in ('B', 'S'), который работает с false == statement.

Правило не запускается для объекта ввода, когда его DSL оценивается как

$trade: Trade((recordTypeCode == '910') && false == (cancellationCode == 'C'))    

и он запускается для того же входного объекта, когда DSL оценивается как

$trade: Trade((recordTypeCode == '910') && (cancellationCode == 'C') == false)

1 Ответ

0 голосов
/ 01 января 2019

Он действительно ведет себя по-разному, так как он анализируется по-разному с помощью лексера DRL6.
org.drools.compiler.compiler.DrlExprParser.parse принимает эти фрагменты текста как есть, но
BaseDescr expr = parser.conditionalOrExpression(); показывает, что анализатор ANTLR обрабатывает их по-разному.

Когда я изменил false == (cancelationCode == 'C') на true ^ (cancelationCode == 'C'), я получил ошибку: «Предикат» true ^ cancellationCode == «C» должен быть логическим выражением ».Это выявляет основную причину проблемы - синтаксический анализатор ANTLR убирает скобки вокруг отдельных операторов, поэтому

false == cancelationCode == 'C' -> doesn't work as expected    
cancelationCode == 'C' == false -> works as expected

Интересно, но скобки не разбираются вокруг сложных операторов, поэтому оба работают, как и ожидалось:

false == (true && cancelationCode == 'C')
(true && cancelationCode == 'C') == false

Я бы сказал, что эта «оптимизация» - это ошибка.

...