]> Cypherpunks.ru repositories - gostls13.git/blob - src/regexp/onepass_test.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / src / regexp / onepass_test.go
1 // Copyright 2014 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package regexp
6
7 import (
8         "reflect"
9         "regexp/syntax"
10         "strings"
11         "testing"
12 )
13
14 var runeMergeTests = []struct {
15         left, right, merged []rune
16         next                []uint32
17         leftPC, rightPC     uint32
18 }{
19         {
20                 // empty rhs
21                 []rune{69, 69},
22                 []rune{},
23                 []rune{69, 69},
24                 []uint32{1},
25                 1, 2,
26         },
27         {
28                 // identical runes, identical targets
29                 []rune{69, 69},
30                 []rune{69, 69},
31                 []rune{},
32                 []uint32{mergeFailed},
33                 1, 1,
34         },
35         {
36                 // identical runes, different targets
37                 []rune{69, 69},
38                 []rune{69, 69},
39                 []rune{},
40                 []uint32{mergeFailed},
41                 1, 2,
42         },
43         {
44                 // append right-first
45                 []rune{69, 69},
46                 []rune{71, 71},
47                 []rune{69, 69, 71, 71},
48                 []uint32{1, 2},
49                 1, 2,
50         },
51         {
52                 // append, left-first
53                 []rune{71, 71},
54                 []rune{69, 69},
55                 []rune{69, 69, 71, 71},
56                 []uint32{2, 1},
57                 1, 2,
58         },
59         {
60                 // successful interleave
61                 []rune{60, 60, 71, 71, 101, 101},
62                 []rune{69, 69, 88, 88},
63                 []rune{60, 60, 69, 69, 71, 71, 88, 88, 101, 101},
64                 []uint32{1, 2, 1, 2, 1},
65                 1, 2,
66         },
67         {
68                 // left surrounds right
69                 []rune{69, 74},
70                 []rune{71, 71},
71                 []rune{},
72                 []uint32{mergeFailed},
73                 1, 2,
74         },
75         {
76                 // right surrounds left
77                 []rune{69, 74},
78                 []rune{68, 75},
79                 []rune{},
80                 []uint32{mergeFailed},
81                 1, 2,
82         },
83         {
84                 // overlap at interval begin
85                 []rune{69, 74},
86                 []rune{74, 75},
87                 []rune{},
88                 []uint32{mergeFailed},
89                 1, 2,
90         },
91         {
92                 // overlap ar interval end
93                 []rune{69, 74},
94                 []rune{65, 69},
95                 []rune{},
96                 []uint32{mergeFailed},
97                 1, 2,
98         },
99         {
100                 // overlap from above
101                 []rune{69, 74},
102                 []rune{71, 74},
103                 []rune{},
104                 []uint32{mergeFailed},
105                 1, 2,
106         },
107         {
108                 // overlap from below
109                 []rune{69, 74},
110                 []rune{65, 71},
111                 []rune{},
112                 []uint32{mergeFailed},
113                 1, 2,
114         },
115         {
116                 // out of order []rune
117                 []rune{69, 74, 60, 65},
118                 []rune{66, 67},
119                 []rune{},
120                 []uint32{mergeFailed},
121                 1, 2,
122         },
123 }
124
125 func TestMergeRuneSet(t *testing.T) {
126         for ix, test := range runeMergeTests {
127                 merged, next := mergeRuneSets(&test.left, &test.right, test.leftPC, test.rightPC)
128                 if !reflect.DeepEqual(merged, test.merged) {
129                         t.Errorf("mergeRuneSet :%d (%v, %v) merged\n have\n%v\nwant\n%v", ix, test.left, test.right, merged, test.merged)
130                 }
131                 if !reflect.DeepEqual(next, test.next) {
132                         t.Errorf("mergeRuneSet :%d(%v, %v) next\n have\n%v\nwant\n%v", ix, test.left, test.right, next, test.next)
133                 }
134         }
135 }
136
137 var onePassTests = []struct {
138         re        string
139         isOnePass bool
140 }{
141         {`^(?:a|(?:a*))$`, false},
142         {`^(?:(a)|(?:a*))$`, false},
143         {`^(?:(?:(?:.(?:$))?))$`, true},
144         {`^abcd$`, true},
145         {`^(?:(?:a{0,})*?)$`, false},
146         {`^(?:(?:a+)*)$`, true},
147         {`^(?:(?:a|(?:aa)))$`, true},
148         {`^(?:[^\s\S])$`, true},
149         {`^(?:(?:a{3,4}){0,})$`, false},
150         {`^(?:(?:(?:a*)+))$`, true},
151         {`^[a-c]+$`, true},
152         {`^[a-c]*$`, true},
153         {`^(?:a*)$`, true},
154         {`^(?:(?:aa)|a)$`, true},
155         {`^[a-c]*`, false},
156         {`^...$`, true},
157         {`^(?:a|(?:aa))$`, true},
158         {`^a((b))c$`, true},
159         {`^a.[l-nA-Cg-j]?e$`, true},
160         {`^a((b))$`, true},
161         {`^a(?:(b)|(c))c$`, true},
162         {`^a(?:(b*)|(c))c$`, false},
163         {`^a(?:b|c)$`, true},
164         {`^a(?:b?|c)$`, true},
165         {`^a(?:b?|c?)$`, false},
166         {`^a(?:b?|c+)$`, true},
167         {`^a(?:b+|(bc))d$`, false},
168         {`^a(?:bc)+$`, true},
169         {`^a(?:[bcd])+$`, true},
170         {`^a((?:[bcd])+)$`, true},
171         {`^a(:?b|c)*d$`, true},
172         {`^.bc(d|e)*$`, true},
173         {`^(?:(?:aa)|.)$`, false},
174         {`^(?:(?:a{1,2}){1,2})$`, false},
175         {`^l` + strings.Repeat("o", 2<<8) + `ng$`, true},
176 }
177
178 func TestCompileOnePass(t *testing.T) {
179         var (
180                 p   *syntax.Prog
181                 re  *syntax.Regexp
182                 err error
183         )
184         for _, test := range onePassTests {
185                 if re, err = syntax.Parse(test.re, syntax.Perl); err != nil {
186                         t.Errorf("Parse(%q) got err:%s, want success", test.re, err)
187                         continue
188                 }
189                 // needs to be done before compile...
190                 re = re.Simplify()
191                 if p, err = syntax.Compile(re); err != nil {
192                         t.Errorf("Compile(%q) got err:%s, want success", test.re, err)
193                         continue
194                 }
195                 isOnePass := compileOnePass(p) != nil
196                 if isOnePass != test.isOnePass {
197                         t.Errorf("CompileOnePass(%q) got isOnePass=%v, expected %v", test.re, isOnePass, test.isOnePass)
198                 }
199         }
200 }
201
202 // TODO(cespare): Unify with onePassTests and rationalize one-pass test cases.
203 var onePassTests1 = []struct {
204         re    string
205         match string
206 }{
207         {`^a(/b+(#c+)*)*$`, "a/b#c"}, // golang.org/issue/11905
208 }
209
210 func TestRunOnePass(t *testing.T) {
211         for _, test := range onePassTests1 {
212                 re, err := Compile(test.re)
213                 if err != nil {
214                         t.Errorf("Compile(%q): got err: %s", test.re, err)
215                         continue
216                 }
217                 if re.onepass == nil {
218                         t.Errorf("Compile(%q): got nil, want one-pass", test.re)
219                         continue
220                 }
221                 if !re.MatchString(test.match) {
222                         t.Errorf("onepass %q did not match %q", test.re, test.match)
223                 }
224         }
225 }