diff --git a/rule/logic/and.go b/rule/logic/and.go index f75de048..01862e51 100644 --- a/rule/logic/and.go +++ b/rule/logic/and.go @@ -11,7 +11,7 @@ type AND struct { func NewAND(payload string, adapter string) (*AND, error) { and := &AND{payload: payload, adapter: adapter} - rules, err := parseRule(payload) + rules, err := parseRuleByPayload(payload) if err != nil { return nil, err } diff --git a/rule/logic/common.go b/rule/logic/common.go index 4c1aa44c..11d67915 100644 --- a/rule/logic/common.go +++ b/rule/logic/common.go @@ -10,63 +10,29 @@ import ( "strings" ) -func parseRule(payload string) ([]C.Rule, error) { +func parseRuleByPayload(payload string) ([]C.Rule, error) { regex, err := regexp.Compile("\\(.*\\)") if err != nil { return nil, err } if regex.MatchString(payload) { - subRanges, err := format(payload) + subAllRanges, err := format(payload) if err != nil { return nil, err } - rules := make([]C.Rule, 0, len(subRanges)) + rules := make([]C.Rule, 0, len(subAllRanges)) + + subRanges := findSubRuleRange(payload, subAllRanges) + for _, subRange := range subRanges { + subPayload := payload[subRange.start+1 : subRange.end] - if len(subRanges) == 1 { - subPayload := payload[subRanges[0].start+1 : subRanges[0].end-1] rule, err := payloadToRule(subPayload) if err != nil { return nil, err } rules = append(rules, rule) - } else { - preStart := subRanges[0].start - preEnd := subRanges[0].end - for _, sr := range subRanges[1:] { - if containRange(sr, preStart, preEnd) && sr.start-preStart > 1 { - str := "" - if preStart+1 <= sr.start-1 { - str = strings.TrimSpace(payload[preStart+1 : sr.start-1]) - } - - if str == "AND" || str == "OR" || str == "NOT" { - subPayload := payload[preStart+1 : preEnd] - rule, err := payloadToRule(subPayload) - if err != nil { - return nil, err - } - - rules = append(rules, rule) - preStart = sr.start - preEnd = sr.end - } - - continue - } - - preStart = sr.start - preEnd = sr.end - - subPayload := payload[sr.start+1 : sr.end] - rule, err := payloadToRule(subPayload) - if err != nil { - return nil, err - } - - rules = append(rules, rule) - } } return rules, nil @@ -84,23 +50,14 @@ func payloadToRule(subPayload string) (C.Rule, error) { tp := splitStr[0] payload := splitStr[1] if tp == "NOT" || tp == "OR" || tp == "AND" { - return parseSubRule(tp, payload, nil) + return parseRule(tp, payload, nil) } param := strings.Split(payload, ",") - return parseSubRule(tp, param[0], param[1:]) + return parseRule(tp, param[0], param[1:]) } -func splitSubRule(subRuleStr string) (string, string, []string, error) { - typeAndRule := strings.Split(subRuleStr, ",") - if len(typeAndRule) < 2 { - return "", "", nil, fmt.Errorf("format error:[%s]", typeAndRule) - } - - return strings.TrimSpace(typeAndRule[0]), strings.TrimSpace(typeAndRule[1]), typeAndRule[2:], nil -} - -func parseSubRule(tp, payload string, params []string) (C.Rule, error) { +func parseRule(tp, payload string, params []string) (C.Rule, error) { var ( parseErr error parsed C.Rule @@ -183,3 +140,29 @@ func format(payload string) ([]Range, error) { return sortResult, nil } + +func findSubRuleRange(payload string, ruleRanges []Range) []Range { + payloadLen := len(payload) + subRuleRange := make([]Range, 0) + for _, rr := range ruleRanges { + if rr.start == 0 && rr.end == payloadLen-1 { + // 最大范围跳过 + continue + } + + containInSub := false + for _, r := range subRuleRange { + if containRange(rr, r.start, r.end) { + // The subRuleRange contains a range of rr, which is the next level node of the tree + containInSub = true + break + } + } + + if !containInSub { + subRuleRange = append(subRuleRange, rr) + } + } + + return subRuleRange +} diff --git a/rule/logic/not.go b/rule/logic/not.go index 94ca0e3c..79102d4e 100644 --- a/rule/logic/not.go +++ b/rule/logic/not.go @@ -13,7 +13,7 @@ type NOT struct { func NewNOT(payload string, adapter string) (*NOT, error) { not := &NOT{payload: payload, adapter: adapter} - rule, err := parseRule(payload) + rule, err := parseRuleByPayload(payload) if err != nil { return nil, err } diff --git a/rule/logic/or.go b/rule/logic/or.go index fb38a20f..3822e315 100644 --- a/rule/logic/or.go +++ b/rule/logic/or.go @@ -41,7 +41,7 @@ func (or *OR) RuleExtra() *C.RuleExtra { func NewOR(payload string, adapter string) (*OR, error) { or := &OR{payload: payload, adapter: adapter} - rules, err := parseRule(payload) + rules, err := parseRuleByPayload(payload) if err != nil { return nil, err }