Skip to content

Commit be5f750

Browse files
committed
evaluate bool expression
1 parent 48655d5 commit be5f750

File tree

4 files changed

+44
-15
lines changed

4 files changed

+44
-15
lines changed

core/common.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func (rule *Rule) Parse(ctx *PipelineContext, depends map[string]IFeature) (outp
4545
return
4646
}
4747

48-
var conditionRet = make(map[string]interface{}, 0)
48+
var conditionRet = make(map[string]bool, 0)
4949
for _, condition := range rule.Conditions {
5050
if feature, ok := depends[condition.Feature]; ok {
5151
rs, err := feature.Compare(condition.Operator, condition.Value)
@@ -67,7 +67,7 @@ func (rule *Rule) Parse(ctx *PipelineContext, depends map[string]IFeature) (outp
6767

6868
//rule.Decision
6969
expr := rule.Decision.Logic
70-
logicRet, err := operator.Evaluate(expr, conditionRet)
70+
logicRet, err := operator.EvaluateBoolExpr(expr, conditionRet)
7171
//某个表达式执行失败会导致最终逻辑执行失败
7272
if err != nil {
7373
return

core/conditional.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func (conditional ConditionalNode) Parse(ctx *PipelineContext) (*NodeResult, err
3939
depends := ctx.GetFeatures(info.Depends)
4040
var matchBranch bool
4141
for _, branch := range conditional.Branchs { //loop all the branch
42-
var conditionRet = make(map[string]interface{}, 0)
42+
var conditionRet = make(map[string]bool, 0)
4343
for _, condition := range branch.Conditions {
4444
if feature, ok := depends[condition.Feature]; ok {
4545
rs, err := feature.Compare(condition.Operator, condition.Value)
@@ -55,7 +55,7 @@ func (conditional ConditionalNode) Parse(ctx *PipelineContext) (*NodeResult, err
5555
if len(conditionRet) == 0 { //current branch not match
5656
continue
5757
}
58-
logicRs, err := operator.Evaluate(branch.Decision.Logic, conditionRet)
58+
logicRs, err := operator.EvaluateBoolExpr(branch.Decision.Logic, conditionRet)
5959
if err != nil {
6060
continue
6161
}

internal/operator/logic.go

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,12 @@ import (
77

88
// evaluate 计算逻辑表达式的值
99
func EvaluateBoolExpr(expr string, variables map[string]bool) (bool, error) {
10-
expr = strings.ReplaceAll(expr, " ", "") // 去除空格
11-
if len(expr) == 0 {
12-
return false, fmt.Errorf("empty expression")
13-
}
14-
if !isValid(expr) {
15-
return false, fmt.Errorf("invalid expression")
16-
}
1710

1811
// 将表达式拆分成一个个token
19-
tokens := splitExpression(expr)
12+
tokens, err := splitExpression(expr)
13+
if err != nil {
14+
return false, err
15+
}
2016

2117
// 开始执行逻辑运算
2218
stack := make([]bool, 0)
@@ -126,7 +122,10 @@ func evaluateOp(b1, b2 bool, op string) bool {
126122

127123
// isValid 检查表达式是否合法
128124
func isValid(expr string) bool {
129-
allowed := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!()+-*%/|&"
125+
if len(expr) == 0 {
126+
return false
127+
}
128+
allowed := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!()+-_*%/|&,"
130129
stack := make([]rune, 0)
131130
for _, ch := range expr {
132131
if ch == '(' {
@@ -144,9 +143,14 @@ func isValid(expr string) bool {
144143
}
145144

146145
// splitExpression 将表达式拆分为token
147-
func splitExpression(expr string) []string {
146+
func splitExpression(expr string) ([]string, error) {
147+
expr = strings.ReplaceAll(expr, " ", "") // 去除空格
148+
if !isValid(expr) {
149+
return nil, fmt.Errorf("invalid expression")
150+
}
148151
tokens := make([]string, 0)
149152
buf := make([]rune, 0)
153+
150154
for i := 0; i < len(expr); i++ {
151155
ch := rune(expr[i])
152156
if ch == '&' && i < len(expr)-1 && rune(expr[i+1]) == '&' {
@@ -169,12 +173,18 @@ func splitExpression(expr string) []string {
169173
buf = []rune{}
170174
}
171175
tokens = append(tokens, string(ch))
176+
} else if ch == ',' {
177+
if len(buf) > 0 {
178+
tokens = append(tokens, string(buf))
179+
buf = []rune{}
180+
}
181+
tokens = append(tokens, string(ch))
172182
} else {
173183
buf = append(buf, ch)
174184
}
175185
}
176186
if len(buf) > 0 {
177187
tokens = append(tokens, string(buf))
178188
}
179-
return tokens
189+
return tokens, nil
180190
}

internal/operator/operator_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,22 @@ func TestBoolExpr(t *testing.T) {
5656
t.Log(expr, result, err)
5757
t.Log(EvaluateBoolExpr("!(foo&&bar)||!a1", variables))
5858
}
59+
60+
func TestSplit(t *testing.T) {
61+
//t.Log(splitExpression("max(foo,bar)"))
62+
// t.Log(splitExpression("tmax(foo,bar)"))
63+
// t.Log(splitExpression("!max(foo,bar)"))
64+
variables := map[string]bool{
65+
"foo": true,
66+
"bar": false,
67+
}
68+
t.Log(EvaluateExpr("max(foo,bar)", variables))
69+
}
70+
71+
func TestEval(t *testing.T) {
72+
variables := map[string]interface{}{
73+
"foo": 1,
74+
"bar": 2,
75+
}
76+
t.Log(Evaluate("max(foo, bar)", variables))
77+
}

0 commit comments

Comments
 (0)