Optimize compilation

This commit is contained in:
s.kamardin 2016-01-13 20:13:11 +03:00
parent ed79d1d679
commit b3ce5dedcb
3 changed files with 41 additions and 32 deletions

View File

@ -89,11 +89,8 @@ func glueMatchers(matchers []match.Matcher) match.Matcher {
}
func glueAsRow(matchers []match.Matcher) match.Matcher {
switch len(matchers) {
case 0:
if len(matchers) <= 1 {
return nil
case 1:
return matchers[0]
}
row := match.Row{}
@ -108,11 +105,8 @@ func glueAsRow(matchers []match.Matcher) match.Matcher {
}
func glueAsEvery(matchers []match.Matcher) match.Matcher {
switch len(matchers) {
case 0:
if len(matchers) <= 1 {
return nil
case 1:
return matchers[0]
}
var (
@ -193,25 +187,37 @@ func glueAsEvery(matchers []match.Matcher) match.Matcher {
return every
}
func convertMatchers(matchers []match.Matcher, result []match.Matcher) []match.Matcher {
var (
buf []match.Matcher
done match.Matcher
)
for idx, m := range matchers {
buf = append(buf, m)
if g := glueMatchers(buf); g != nil {
done = g
} else {
return convertMatchers(matchers[idx:], append(result, done))
func convertMatchers(matchers []match.Matcher) []match.Matcher {
var done match.Matcher
var left, right, count int
for l := 0; l < len(matchers); l++ {
for r := len(matchers); r > l; r-- {
if glued := glueMatchers(matchers[l:r]); glued != nil {
if done == nil || count < r-l {
done = glued
left = l
right = r
count = r - l
}
}
}
}
if done != nil {
return append(result, done)
if done == nil {
return matchers
}
return result
next := append(append([]match.Matcher{}, matchers[:left]...), done)
if right < len(matchers) {
next = append(next, matchers[right:]...)
}
if len(next) == len(matchers) {
return next
}
return convertMatchers(next)
}
func compileMatchers(matchers []match.Matcher) (match.Matcher, error) {
@ -219,6 +225,10 @@ func compileMatchers(matchers []match.Matcher) (match.Matcher, error) {
return nil, fmt.Errorf("compile error: need at least one matcher")
}
if len(matchers) == 1 {
return matchers[0], nil
}
if m := glueMatchers(matchers); m != nil {
return m, nil
}
@ -285,7 +295,7 @@ func do(node node, s string) (m match.Matcher, err error) {
if _, ok := node.(*nodeAnyOf); ok {
m = match.AnyOf{matchers}
} else {
m, err = compileMatchers(convertMatchers(matchers, nil))
m, err = compileMatchers(convertMatchers(matchers))
if err != nil {
return nil, err
}
@ -349,7 +359,7 @@ func do2(node node, s string) ([]match.Matcher, error) {
}
for _, matchers := range ways {
c, err := compileMatchers(convertMatchers(matchers, nil))
c, err := compileMatchers(convertMatchers(matchers))
if err != nil {
return nil, err
}
@ -383,7 +393,7 @@ func do2(node node, s string) ([]match.Matcher, error) {
}
for _, matchers := range ways {
c, err := compileMatchers(convertMatchers(matchers, nil))
c, err := compileMatchers(convertMatchers(matchers))
if err != nil {
return nil, err
}

View File

@ -162,13 +162,12 @@ func TestConvertMatchers(t *testing.T) {
match.Range{'a', 'c', true},
match.List{"zte", false},
match.Raw{"c"},
match.Single{},
}},
match.Min{2},
match.Min{3},
},
},
} {
act := convertMatchers(test.in, nil)
act := convertMatchers(test.in)
if !reflect.DeepEqual(act, test.exp) {
t.Errorf("#%d unexpected convert matchers 2 result:\nact: %s;\nexp: %s", id, act, test.exp)
continue

View File

@ -81,10 +81,10 @@ func TestCompilePattern(t *testing.T) {
sep string
exp match.Matcher
}{
// {
// pattern: "left*??B*abcd*[!b]??*abc*right",
// exp: match.Raw{"t"},
// },
// {
// pattern: "left*??B*abcd*[!b]??*abc*right",
// exp: match.Raw{"t"},
// },
// {
// pattern: "abc*??def",
// exp: match.Raw{"t"},