[Refactor] logic rule parse
This commit is contained in:
parent
9afe58058d
commit
9c0705f310
4 changed files with 39 additions and 56 deletions
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue