]>
Commit | Line | Data |
---|---|---|
1 | // © 2016 and later: Unicode, Inc. and others. | |
2 | // License & terms of use: http://www.unicode.org/copyright.html | |
3 | // | |
4 | // regexcmp.h | |
5 | // | |
6 | // Copyright (C) 2002-2016, International Business Machines Corporation and others. | |
7 | // All Rights Reserved. | |
8 | // | |
9 | // This file contains declarations for the class RegexCompile | |
10 | // | |
11 | // This class is internal to the regular expression implementation. | |
12 | // For the public Regular Expression API, see the file "unicode/regex.h" | |
13 | // | |
14 | ||
15 | ||
16 | #ifndef RBBISCAN_H | |
17 | #define RBBISCAN_H | |
18 | ||
19 | #include "unicode/utypes.h" | |
20 | #if !UCONFIG_NO_REGULAR_EXPRESSIONS | |
21 | ||
22 | #include "unicode/parseerr.h" | |
23 | #include "unicode/uniset.h" | |
24 | #include "unicode/uobject.h" | |
25 | #include "unicode/utext.h" | |
26 | #include "uhash.h" | |
27 | #include "uvector.h" | |
28 | #include "uvectr32.h" | |
29 | ||
30 | ||
31 | ||
32 | U_NAMESPACE_BEGIN | |
33 | ||
34 | ||
35 | //-------------------------------------------------------------------------------- | |
36 | // | |
37 | // class RegexCompile Contains the regular expression compiler. | |
38 | // | |
39 | //-------------------------------------------------------------------------------- | |
40 | struct RegexTableEl; | |
41 | class RegexPattern; | |
42 | ||
43 | ||
44 | class U_I18N_API RegexCompile : public UMemory { | |
45 | public: | |
46 | ||
47 | enum { | |
48 | kStackSize = 100 // The size of the state stack for | |
49 | }; // pattern parsing. Corresponds roughly | |
50 | // to the depth of parentheses nesting | |
51 | // that is allowed in the rules. | |
52 | ||
53 | struct RegexPatternChar { | |
54 | UChar32 fChar; | |
55 | UBool fQuoted; | |
56 | }; | |
57 | ||
58 | RegexCompile(RegexPattern *rp, UErrorCode &e); | |
59 | ||
60 | void compile(const UnicodeString &pat, UParseError &pp, UErrorCode &e); | |
61 | void compile(UText *pat, UParseError &pp, UErrorCode &e); | |
62 | ||
63 | ||
64 | virtual ~RegexCompile(); | |
65 | ||
66 | void nextChar(RegexPatternChar &c); // Get the next char from the input stream. | |
67 | ||
68 | static void cleanup(); // Memory cleanup | |
69 | ||
70 | ||
71 | ||
72 | // Categories of parentheses in pattern. | |
73 | // The category is saved in the compile-time parentheses stack frame, and | |
74 | // determines the code to be generated when the matching close ) is encountered. | |
75 | enum EParenClass { | |
76 | plain = -1, // No special handling | |
77 | capturing = -2, | |
78 | atomic = -3, | |
79 | lookAhead = -4, | |
80 | negLookAhead = -5, | |
81 | flags = -6, | |
82 | lookBehind = -7, | |
83 | lookBehindN = -8 | |
84 | }; | |
85 | ||
86 | private: | |
87 | ||
88 | ||
89 | UBool doParseActions(int32_t a); | |
90 | void error(UErrorCode e); // error reporting convenience function. | |
91 | ||
92 | UChar32 nextCharLL(); | |
93 | UChar32 peekCharLL(); | |
94 | UnicodeSet *scanProp(); | |
95 | UnicodeSet *scanPosixProp(); | |
96 | void handleCloseParen(); | |
97 | int32_t blockTopLoc(UBool reserve); // Locate a position in the compiled pattern | |
98 | // at the top of the just completed block | |
99 | // or operation, and optionally ensure that | |
100 | // there is space to add an opcode there. | |
101 | void compileSet(UnicodeSet *theSet); // Generate the compiled pattern for | |
102 | // a reference to a UnicodeSet. | |
103 | void compileInterval(int32_t InitOp, // Generate the code for a {min,max} quantifier. | |
104 | int32_t LoopOp); | |
105 | UBool compileInlineInterval(); // Generate inline code for a {min,max} quantifier | |
106 | void literalChar(UChar32 c); // Compile a literal char | |
107 | void fixLiterals(UBool split=FALSE); // Generate code for pending literal characters. | |
108 | void insertOp(int32_t where); // Open up a slot for a new op in the | |
109 | // generated code at the specified location. | |
110 | void appendOp(int32_t op); // Append a new op to the compiled pattern. | |
111 | void appendOp(int32_t type, int32_t val); // Build & append a new op to the compiled pattern. | |
112 | int32_t buildOp(int32_t type, int32_t val); // Construct a new pcode instruction. | |
113 | int32_t allocateData(int32_t size); // Allocate space in the matcher data area. | |
114 | // Return index of the newly allocated data. | |
115 | int32_t allocateStackData(int32_t size); // Allocate space in the match back-track stack frame. | |
116 | // Return offset index in the frame. | |
117 | int32_t minMatchLength(int32_t start, | |
118 | int32_t end); | |
119 | int32_t maxMatchLength(int32_t start, | |
120 | int32_t end); | |
121 | void matchStartType(); | |
122 | void stripNOPs(); | |
123 | ||
124 | void setEval(int32_t op); | |
125 | void setPushOp(int32_t op); | |
126 | UChar32 scanNamedChar(); | |
127 | UnicodeSet *createSetForProperty(const UnicodeString &propName, UBool negated); | |
128 | ||
129 | public: // Public for testing only. | |
130 | static void U_EXPORT2 findCaseInsensitiveStarters(UChar32 c, UnicodeSet *starterChars); | |
131 | private: | |
132 | ||
133 | ||
134 | UErrorCode *fStatus; | |
135 | RegexPattern *fRXPat; | |
136 | UParseError *fParseErr; | |
137 | ||
138 | // | |
139 | // Data associated with low level character scanning | |
140 | // | |
141 | int64_t fScanIndex; // Index of current character being processed | |
142 | // in the rule input string. | |
143 | UBool fQuoteMode; // Scan is in a \Q...\E quoted region | |
144 | UBool fInBackslashQuote; // Scan is between a '\' and the following char. | |
145 | UBool fEOLComments; // When scan is just after '(?', inhibit #... to | |
146 | // end of line comments, in favor of (?#...) comments. | |
147 | int64_t fLineNum; // Line number in input file. | |
148 | int64_t fCharNum; // Char position within the line. | |
149 | UChar32 fLastChar; // Previous char, needed to count CR-LF | |
150 | // as a single line, not two. | |
151 | UChar32 fPeekChar; // Saved char, if we've scanned ahead. | |
152 | ||
153 | ||
154 | RegexPatternChar fC; // Current char for parse state machine | |
155 | // processing. | |
156 | ||
157 | // | |
158 | // Data for the state machine that parses the regular expression. | |
159 | // | |
160 | RegexTableEl **fStateTable; // State Transition Table for regex Rule | |
161 | // parsing. index by p[state][char-class] | |
162 | ||
163 | uint16_t fStack[kStackSize]; // State stack, holds state pushes | |
164 | int32_t fStackPtr; // and pops as specified in the state | |
165 | // transition rules. | |
166 | ||
167 | // | |
168 | // Data associated with the generation of the pcode for the match engine | |
169 | // | |
170 | int32_t fModeFlags; // Match Flags. (Case Insensitive, etc.) | |
171 | // Always has high bit (31) set so that flag values | |
172 | // on the paren stack are distinguished from relocatable | |
173 | // pcode addresses. | |
174 | int32_t fNewModeFlags; // New flags, while compiling (?i, holds state | |
175 | // until last flag is scanned. | |
176 | UBool fSetModeFlag; // true for (?ismx, false for (?-ismx | |
177 | ||
178 | UnicodeString fLiteralChars; // Literal chars or strings from the pattern are accumulated here. | |
179 | // Once completed, meaning that some non-literal pattern | |
180 | // construct is encountered, the appropriate opcodes | |
181 | // to match the literal will be generated, and this | |
182 | // string will be cleared. | |
183 | ||
184 | int64_t fPatternLength; // Length of the input pattern string. | |
185 | ||
186 | UVector32 fParenStack; // parentheses stack. Each frame consists of | |
187 | // the positions of compiled pattern operations | |
188 | // needing fixup, followed by negative value. The | |
189 | // first entry in each frame is the position of the | |
190 | // spot reserved for use when a quantifier | |
191 | // needs to add a SAVE at the start of a (block) | |
192 | // The negative value (-1, -2,...) indicates | |
193 | // the kind of paren that opened the frame. Some | |
194 | // need special handling on close. | |
195 | ||
196 | ||
197 | int32_t fMatchOpenParen; // The position in the compiled pattern | |
198 | // of the slot reserved for a state save | |
199 | // at the start of the most recently processed | |
200 | // parenthesized block. Updated when processing | |
201 | // a close to the location for the corresponding open. | |
202 | ||
203 | int32_t fMatchCloseParen; // The position in the pattern of the first | |
204 | // location after the most recently processed | |
205 | // parenthesized block. | |
206 | ||
207 | int32_t fIntervalLow; // {lower, upper} interval quantifier values. | |
208 | int32_t fIntervalUpper; // Placed here temporarily, when pattern is | |
209 | // initially scanned. Each new interval | |
210 | // encountered overwrites these values. | |
211 | // -1 for the upper interval value means none | |
212 | // was specified (unlimited occurences.) | |
213 | ||
214 | int64_t fNameStartPos; // Starting position of a \N{NAME} name in a | |
215 | // pattern, valid while remainder of name is | |
216 | // scanned. | |
217 | ||
218 | UStack fSetStack; // Stack of UnicodeSets, used while evaluating | |
219 | // (at compile time) set expressions within | |
220 | // the pattern. | |
221 | UStack fSetOpStack; // Stack of pending set operators (&&, --, union) | |
222 | ||
223 | UChar32 fLastSetLiteral; // The last single code point added to a set. | |
224 | // needed when "-y" is scanned, and we need | |
225 | // to turn "x-y" into a range. | |
226 | ||
227 | UnicodeString *fCaptureName; // Named Capture, the group name is built up | |
228 | // in this string while being scanned. | |
229 | }; | |
230 | ||
231 | // Constant values to be pushed onto fSetOpStack while scanning & evalueating [set expressions] | |
232 | // The high 16 bits are the operator precedence, and the low 16 are a code for the operation itself. | |
233 | ||
234 | enum SetOperations { | |
235 | setStart = 0 << 16 | 1, | |
236 | setEnd = 1 << 16 | 2, | |
237 | setNegation = 2 << 16 | 3, | |
238 | setCaseClose = 2 << 16 | 9, | |
239 | setDifference2 = 3 << 16 | 4, // '--' set difference operator | |
240 | setIntersection2 = 3 << 16 | 5, // '&&' set intersection operator | |
241 | setUnion = 4 << 16 | 6, // implicit union of adjacent items | |
242 | setDifference1 = 4 << 16 | 7, // '-', single dash difference op, for compatibility with old UnicodeSet. | |
243 | setIntersection1 = 4 << 16 | 8 // '&', single amp intersection op, for compatibility with old UnicodeSet. | |
244 | }; | |
245 | ||
246 | U_NAMESPACE_END | |
247 | #endif // !UCONFIG_NO_REGULAR_EXPRESSIONS | |
248 | #endif // RBBISCAN_H |