Merge pull request #347 from JamesB7/master
[mono.git] / mcs / class / System / System.Text.RegularExpressions / arch.cs
1 //
2 // assembly:    System
3 // namespace:   System.Text.RegularExpressions
4 // file:        arch.cs
5 //
6 // author:      Dan Lewis (dlewis@gmx.co.uk)
7 //              (c) 2002
8
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29
30 using System;
31 using System.Collections;
32
33 namespace System.Text.RegularExpressions {
34
35         enum OpCode : ushort {
36                 False           = 0,    // always fails
37                 True,                   // always succeeds
38
39                 // matching
40
41                 Position,               // zero-width position assertion
42                 String,                 // match string literal
43                 Reference,              // back reference
44
45                 // character matching
46
47                 Character,              // match character exactly
48                 Category,               // match character from category
49                 NotCategory,            // match character _not_ from category
50                 Range,                  // match character from range
51                 Set,                    // match character from set
52                 In,                     // match character from group of tests
53
54                 // capturing
55
56                 Open,                   // open group
57                 Close,                  // close group
58                 Balance,                // balance groups
59                 BalanceStart,           //track balance group length
60
61                 // control flow
62
63                 IfDefined,              // conditional on capture
64                 Sub,                    // non-backtracking subexpression
65                 Test,                   // non-backtracking lookahead/behind
66                 Branch,                 // alternative expression
67                 Jump,                   // unconditional goto
68                 Repeat,                 // new repeat context
69                 Until,                  // repeat subexpression within context
70                 FastRepeat,             // repeat simple subexpression
71                 Anchor,                 // anchoring expression
72
73                 // miscellaneous
74                 
75                 Info,                   // pattern information
76                 
77                 JumpTest                // Jump if we didn't already go
78                                         // through this path with an alternative
79                                         // option (an "or" path).. i.e. so we
80                                         // don't do short circuit or
81         }
82
83         [Flags]
84         enum OpFlags : ushort {
85                 None            = 0x000,
86                 Negate          = 0x100,        // succeed on mismatch
87                 IgnoreCase      = 0x200,        // case insensitive matching
88                 RightToLeft     = 0x400,        // right-to-left matching
89                 Lazy            = 0x800         // minimizing repeat
90         }
91
92         enum Position : ushort {
93                 Any,                    // anywhere
94                 Start,                  // start of string                      \A
95                 StartOfString,          // start of string                      \A
96                 StartOfLine,            // start of line                        ^
97                 StartOfScan,            // start of scan                        \G
98                 End,                    // end or before newline at end         \Z
99                 EndOfString,            // end of string                        \z
100                 EndOfLine,              // end of line                          $
101                 Boundary,               // word boundary                        \b
102                 NonBoundary             // not word boundary                    \B
103         };
104         
105         // see category.cs for Category enum
106
107         interface IMachine {
108                 Match Scan (Regex regex, string text, int start, int end);
109                 string [] Split (Regex regex, string input, int count, int startat);
110                 string Replace (Regex regex, string input, string replacement, int count, int startat);
111                 string Result (string replacement, Match match);
112         }
113
114         interface IMachineFactory {
115                 IMachine NewInstance ();
116                 IDictionary Mapping { get; set; }
117                 int GroupCount { get; }
118                 int Gap { get; set; } // Index of first group whose number differs from its index, or 1+GroupCount
119                 string [] NamesMapping { get; set; }
120         }
121
122         // Anchor SKIP OFFSET
123         //
124         // Flags:       [RightToLeft] ??
125         // SKIP:        relative address of tail expression
126         // OFFSET:      offset of anchor from start of pattern
127         //
128         // Usage:
129         //
130         //      Anchor :1 OFFSET
131         //              <expr>
132         //              True
133         // 1:   <tail>
134         //
135         // Notes:
136         //
137         // In practice, the anchoring expression is only going to be
138         // Position (StartOfString, StartOfLine, StartOfScan) or String.
139         // This is because the optimizer looks for position anchors at the
140         // start of the expression, and if that fails it looks for the
141         // longest substring. If an expression has neither a position
142         // anchor or a longest substring anchor, then the anchoring expression
143         // is left empty. Since an empty expression will anchor at any
144         // position in any string, the entire input string will be scanned.
145
146         // String LEN STR...
147         //
148         // Flags:       [RightToLeft, IgnoreCase]
149         // LEN:         length of string
150         // STR:         string characters
151
152         // Branch SKIP
153         //
154         // SKIP:        relative address of next branch
155         //
156         //      Branch :1
157         //              <alt expr 1>
158         //              Jump :4
159         // 1:   Branch :2
160         //              <alt expr 2>
161         //              Jump :4
162         // 2:   Branch :3
163         //              <alt expr 3>
164         //              Jump :4
165         // 3:   False
166         // 4:   <tail>
167
168         // Repeat SKIP MIN MAX
169         //
170         // Flags:       [Lazy]
171         // SKIP:        relative address of Until instruction
172         // MIN:         minimum iterations (2 slots)
173         // MAX:         maximum iterations (2 slots, 0x7fffffff is infinity)
174         //
175         //      Repeat :1 MIN MAX
176         //              <expr>
177         //              Until
178         // 1:   <tail>
179
180         // FastRepeat SKIP MIN MAX
181         //
182         // Flags:       [Lazy]
183         // SKIP:        relative address of tail expression
184         // MIN:         minimum iterations (2 slots)
185         // MAX:         maximum iterations (2 slots, 0x7fffffff is infinity)
186         //
187         //      FastRepeat :1 MIN MAX
188         //              <expr>
189         //              True
190         // 1:   <tail>
191         //
192         // Notes:
193         //
194         // The subexpression of a FastRepeat construct must not contain any
195         // complex operators. These include: Open, Close, Balance, Repeat,
196         // FastRepeat, Sub, Test. In addition, the subexpression must have
197         // been determined to have a fixed width.
198         
199         // Sub SKIP
200         //
201         // SKIP:        relative address of tail expression
202         //
203         //      Sub :1
204         //              <expr>
205         // 1:   <tail>
206         //
207         // Notes:
208         //
209         // The Sub operator invokes an independent subexpression. This means
210         // that the subexpression will match only once and so will not
211         // participate in any backtracking.
212
213         // Test TSKIP FSKIP
214         //
215         // TSKIP:       relative address of true expression
216         // FSKIP:       relative address of false expression
217         //
218         // Usage:       (?(?=test)true|false)
219         //
220         //      Test :1 :2
221         //              <test expr>
222         // 1:           <true expr>
223         //              Jump
224         // 2:           <false epxr>
225         //      <tail>
226         //
227         // Usage:       (?(?=test)true)
228         //
229         //      Test :1 :2
230         //              <test expr>
231         // 1:           <true expr>
232         // 2:   <tail>
233         //
234         // Usage:       (?=test)
235         //
236         //      Test :1 :2
237         //              <test expr>
238         // 1:           <true expr>
239         //              Jump 3:
240         // 2:           False
241         // 3:           <tail>
242         //
243         // Notes:
244         //
245         // For negative lookaheads, just swap the values of TSKIP and
246         // FSKIP. For lookbehinds, the test expression must be compiled
247         // in reverse. The test expression is always executed as an
248         // independent subexpression, so its behaviour is non-backtracking
249         // (like a Sub clause.)
250
251         // IfDefined SKIP GID
252         //
253         // SKIP:        relative address of else expression
254         // GID:         number of group to check
255         //
256         // Usage:       (?(gid)true)
257         //
258         //      IfDefined :1
259         //              <true expr>
260         // 1:   <tail>
261         //
262         // Usage:       (?(gid)true|false)
263         //
264         //      IfDefined :1
265         //              <true expr>
266         //              Jump :2
267         // 1:           <false expr>
268         // 2:   <tail>
269
270         // Jump SKIP
271         //
272         // SKIP:        relative address of target expression
273         //
274         //      Jump :1
275         //      ...
276         // :1   <target expr>
277
278         // Character CHAR
279         //
280         // Flags:       [Negate, IgnoreCase, RightToLeft]
281         // CHAR:        exact character to match
282
283         // Category CAT
284         //
285         // Flags:       [Negate, RightToLeft]
286         // CAT:         category to match (see Category enum)
287
288         // Range LO HI
289         //
290         // Flags:       [Negate, IgnoreCase, RightToLeft]
291         // LO:          lowest character in range
292         // HI:          higest character in range
293
294         // Set LO LEN SET...
295         //
296         // Flags:       [Negate, IgnoreCase, RightToLeft]
297         // LO:          lowest character in set
298         // LEN:         number of words in set
299         // SET:         bit array representing characters in set
300         //
301         // Notes:
302         //
303         // Each word in the set represents 16 characters, so the first word
304         // defines membership for characters LO to LO + 15, the second for
305         // LO + 16 to LO + 31, and so on up to LO + (LEN * 16 - 1). It is
306         // up to the compiler to provide a compact representation for sparse
307         // unicode sets. The simple way is to use Set 0 4096. Other methods
308         // involve paritioning the set and placing the components into an
309         // In block.
310
311         // In SKIP
312         //
313         // SKIP:        relative address of tail expression
314         //
315         // Usage:       [expr]
316         //
317         //      In :1
318         //              <expr>
319         //              True
320         // :1   <tail>
321         //
322         // Usage:       [^expr]
323         //
324         //      In :1
325         //              <expr>
326         //              False
327         // :1   <tail>
328         //
329         // Notes:
330         //
331         // The In instruction consumes a single character, using the flags
332         // of the first instruction in the subexpression to determine its
333         // IgnoreCase and RightToLeft properties. The subexpression is then
334         // applied to the single character as a disjunction. If any instruction
335         // in the subexpression succeeds, the entire In construct succeeds
336         // and matching continues with the tail.
337
338         // Position POS
339         //
340         // POS:         position to match (see Position enum)
341
342         // Open GID
343         //
344         // GID:         number of group to open
345
346         // Close GID
347         //
348         // GID:         number of group to close
349         
350         // Balance GID BAL
351         //
352         // GID:         number of capturing group (0 if none)
353         // BAL:         number of group to undefine
354
355         // Info GROUPS MIN MAX
356         //
357         // GROUPS:      number of capturing groups (2 slots)
358         // MIN:         minimum width of pattern (2 slots)
359         // MAX:         maximum width of pattern (2 slots, 0x7fffffff means undefined)
360
361         // False
362
363         // True
364
365         // Reference GID
366         //
367         // Flags:       [IgnoreCase, RightToLeft]
368         // GID:         number of group to reference
369 }