drools dsl使用'-';不起作用

drools dsl使用'-';不起作用,drools,dsl,Drools,Dsl,我使用drools规则已经有一段时间了,最近刚刚开始使用dsl,以使最终用户更容易编写规则。虽然我已经能够像预期的那样定义一个简单的dsl并正确地编译成drl,但我无法让dsl的“向以前的表达式添加约束”功能发挥作用。 我甚至在尝试drools dsl指南中最简单的示例,这不会将我定义的以“-”开头的条件编译到前面的表达式中。在编译规则“Rule1Sample_0”时,我一直收到一个“不匹配的输入”价格错误。 正如我所说的,我对简单的条件表达式和结果表达式进行了研究。但是,在文档之后添加约束根本

我使用drools规则已经有一段时间了,最近刚刚开始使用dsl,以使最终用户更容易编写规则。虽然我已经能够像预期的那样定义一个简单的dsl并正确地编译成drl,但我无法让dsl的“向以前的表达式添加约束”功能发挥作用。 我甚至在尝试drools dsl指南中最简单的示例,这不会将我定义的以“-”开头的条件编译到前面的表达式中。在编译规则“Rule1Sample_0”时,我一直收到一个“不匹配的输入”价格错误。 正如我所说的,我对简单的条件表达式和结果表达式进行了研究。但是,在文档之后添加约束根本不起作用。 我使用的是drools版本7.0.0.Final,这是在更高版本之前不受支持的吗

在我正在测试的简单示例中,我的dsl文件只包含:

[condition][]There is a {ShoppingCart} that=${ShoppingCart!lc} : ${ShoppingCart!ucfirst}()
[condition][]- total price is greater than 1000 =totalPrice > 1000

[consequence]Update {ShoppingCart}=System.out.println("{ShoppingCart}" + " test")
这是条件

"There is a ShoppingCart that total price is greater than 1000"
以及我为模板的when和then部分指定的操作:

"Action" "Update ShoppingCart"
以下是在我将其传递给DrlParser之前编译的drl:


    rule "Test1"
      dialect "mvel"
      when
         "There is a ShoppingCart that total price is greater than 1000"
      then
        "Update ShoppingCart"
    end
这是运行上述代码段后expandedDrl字符串包含的内容:

package com.sample.test

rule "Test1"
  dialect "mvel"
  when
     $shoppingcart : $Shoppingcart() total price is greater than 1000
  then
    System.out.println("ShoppingCart" + " test")
end
package com.sample.test

rule "Test1"
  dialect "mvel"
  when
     $shoppingcart : $Shoppingcart() total price is greater than 1000
  then
    System.out.println("ShoppingCart" + " test")
end
下面是我使用DRLParser解析它时为此生成的drl:

(此处是代码片段,省略了一些)

这是运行上述代码段后expandedDrl字符串包含的内容:

package com.sample.test

rule "Test1"
  dialect "mvel"
  when
     $shoppingcart : $Shoppingcart() total price is greater than 1000
  then
    System.out.println("ShoppingCart" + " test")
end
package com.sample.test

rule "Test1"
  dialect "mvel"
  when
     $shoppingcart : $Shoppingcart() total price is greater than 1000
  then
    System.out.println("ShoppingCart" + " test")
end
以及我在控制台中看到的编译器错误:

[[13,43]: [ERR 102] Line 13:43 mismatched input 'price' in rule "Test1"  ....

你能试试这个条件吗

There is a ShoppingCart that
- total price is greater than 1000

你能试试下面的dsl吗

... business definitions
[when]complex condition = (simple condition 
                           or another condition)
[when]simple condition = (total price is not 0)
[when]another condition = (total price greater than 10)

... field definitions
[when]total price = totalPrice

... consequences I advise to wrap in java util class each as a static method to write java code in java code
[consequence]Update {ShoppingCart}=System.out.println("{ShoppingCart}" + " test")

... tech dsl at the bottom

[when]There (is( an?)?|are) {entityType}s?( that)? = ${entityType}: {entityType}()
[when](is\s+)?not less than(\s+an?)? = >=
[when](is\s+)?less than(\s+an?)? = <
[when](is\s+)?not greater than(\s+an?)? = <=
[when](is\s+)?greater than(\s+an?)? = >
[when]((is|do(es)?)\s+)?not equals?(\s+to)? = !=
[when](is\s+)?equals?(\s+to)? = ==
[when]is not(\s+an?)? = !=
[when]is(\s+an?)? = ==
[when]like(\s+an?)? = matches
[when]{prefix}?\s*(?<![\w])and(?![\w])\s*{suffix}? = {prefix} && {suffix}
[when]{prefix}?\s*(?<![\w])or(?![\w])\s*{suffix}? = {prefix} || {suffix}
[when]{prefix}?\s*(?<![\w])not(?! (in|matches|contains|memberOf|soundslike|str))(\s+an?)?(?![\w])\s*\({suffix}? = {prefix} false == (true && {suffix}
[when]{prefix}?\s*(?<![\w])not(?! (in|matches|contains|memberOf|soundslike|str))(\s+an?)?(?![\w])\s*{suffix}? = {prefix} !{suffix}
[when](?<![^\(,])\s*- = 
如果希望在其他条件中重用条件,则希望它们是原子的。很好的经验法则是用大括号()拥抱RHS,不要打破记录的原子性


测试

@DroolsSession({ "classpath:/test.rdslr", "classpath:/business.dsl", "classpath:/keywords.dsl" })
public class PlaygroundTest {

    @Rule
    public DroolsAssert drools = new DroolsAssert();

    @Test
    public void testIt() {
        drools.insertAndFire(new ShoppingCart(BigDecimal.valueOf(1000.5)));
        drools.insertAndFire(new ShoppingCart(BigDecimal.valueOf(999)));
    }
}
领域

public class ShoppingCart {
    public BigDecimal totalPrice;

    public ShoppingCart(BigDecimal totalPrice) {
        this.totalPrice = totalPrice; 
    }
}
rdslr

business.dsl

[when]worth a discount = 
    (total price is not less than 500
    and not over limit
    or total price is greater than 5000)
// stupid condition just for demonstration
[when]over limit = ((total price + total price * 0.05) > total price + 50)
[when]total price = totalPrice

[then]print eligible price = System.out.println($ShoppingCart.totalPrice);
关键词.dsl

[when]There (is( an?)?|are) {entityType}s?( that)? = ${entityType}: {entityType}()
[when](is )?not within\s*\({tail}?= not in ({tail}
[when](is )?within\s*\({tail}?= in ({tail}
[when](is )?not one of\s*\({tail}?= not in ({tail}
[when](is )?one of\s*\({tail}?= in ({tail}
[when]ignore case '{tail}?= '(?i){tail}
[when]{param:[$\w\.!'\[\]]+} as {param2:[$\w\.!'\[\]]+}=(({param2}) {param})
[when](is\s+)?not less than(\s+an?)? = >=
[when](is\s+)?less than(\s+an?)? = <
[when](is\s+)?not greater than(\s+an?)? = <=
[when](is\s+)?greater than(\s+an?)? = >
[when]((is|do(es)?)\s+)?not equals?(\s+to)? = !=
[when](is\s+)?equals?(\s+to)? = ==
[when]is not(\s+an?)? = !=
[when]is(\s+an?)? = ==
[when]like(\s+an?)? = matches
[when]{prefix}?\s*(?<![\w])and(?![\w])\s*{suffix}? = {prefix} && {suffix}
[when]{prefix}?\s*(?<![\w])or(?![\w])\s*{suffix}? = {prefix} || {suffix}
[when]{prefix}?\s*(?<![\w])not(?! (in|matches|contains|memberOf|soundslike|str))(\s+an?)?(?![\w])\s*\({suffix}? = {prefix} false == (true && {suffix}
[when]{prefix}?\s*(?<![\w])not(?! (in|matches|contains|memberOf|soundslike|str))(\s+an?)?(?![\w])\s*{suffix}? = {prefix} !{suffix}
[when](?<![^\(,])\s*- = 
[当]有(一个?|是){entityType}s?(那)?=${entityType}:{entityType}()
[何时](是)?不在\s*\({tail}?=不在({tail}
[何时](是)?在\s*\({tail}?=in({tail}
[何时](是)?不是\s*\({tail}?=不在({tail})中的一个
[when](is)?\s*\({tail}?=in({tail})中的一个
[when]忽略大小写“{tail}?”=”(?i){tail}
[when]{param:[$\w\.!'\[\]]+}作为{param2:[$\w\.!'\[\]+}=(({param2}){param})
[何时](是\s+?)不小于(\s+an?)=>=
[何时](是\s+?小于(\s+an?)=<
[何时](是\s+?)不大于(\s+an?)=
[何时]((是| do(es))\s+)?不等于?(\s+to)?==
[何时](是\s+?)等于(\s+到)?===
[何时]不是(\s+an?)==
[何时]是(\s+an?)===
[when]like(\s+an?)=匹配项
[何时]{prefix}?\s*(?
测试输出

00:00:00 --> inserted: ShoppingCart[totalPrice=1000.5]
00:00:00 --> fireAllRules
00:00:00 <-- 'Test1' has been activated by the tuple [ShoppingCart]
1000.5
00:00:00 --> inserted: ShoppingCart[totalPrice=999]
00:00:00 --> fireAllRules
00:00:00 <-- 'Test2' has been activated by the tuple [ShoppingCart]
999
00:00:00-->插入:ShoppingCart[totalPrice=1000.5]
00:00:00-->fireAllRules
00:00:00插入:ShoppingCart[totalPrice=999]
00:00:00-->fireAllRules

00:00:00我尝试了这个方法,但在规则中得到了相同的结果不匹配的输入“价格”。谢谢,我将尝试这种方法。那么,你的意思是破折号在向事实添加约束时不起作用吗?它起作用了,破折号表示“使用作为最近类型的子约束”(此处)“。但当您希望复杂的正则表达式替换多次发生时,它会造成限制。通常情况下,您会这样做,因为DSL处理器可以按可预测的顺序重复替换代码段(从单个文件的顶部到底部,以不可预测的顺序加载多个文件)然后一步一步地将非常复杂的语句解析为有效的逻辑结构。因此,当您使用破折号开始语句时,您只能将其用作“整行语句”,它在“-simple condition”或-other condition”定义中看起来很难看。我从上面尝试了您的dsl,但我没有看到()对于他们应用的实体?例如,我看到$shoppingCart:shoppingCart()totalPrice<1000,而不是$shoppingCart:shoppingCart(totalPrice<1000)这就是我所需要的。我如何在实体上使用这种方法进行约束?对于我的用例,我将有约束的组合,使用“and”和“OR”多次重用相同的条件。例如,我将需要类似-$shoppingCart:shoppingCart(totalPrice<1000&&totalPrice>500 | | totalPrice==350)很抱歉,我在这里使用了一个糟糕的示例!它肯定应该作为内部约束。这里还有其他原因导致了这个问题。有人能给我指出一个github示例来说明这个功能吗?在那里我可以看到一个工作代码示例,以确认它确实有效?
00:00:00 --> inserted: ShoppingCart[totalPrice=1000.5]
00:00:00 --> fireAllRules
00:00:00 <-- 'Test1' has been activated by the tuple [ShoppingCart]
1000.5
00:00:00 --> inserted: ShoppingCart[totalPrice=999]
00:00:00 --> fireAllRules
00:00:00 <-- 'Test2' has been activated by the tuple [ShoppingCart]
999