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
32U_NAMESPACE_BEGIN
33
34
35//--------------------------------------------------------------------------------
36//
37// class RegexCompile Contains the regular expression compiler.
38//
39//--------------------------------------------------------------------------------
40struct RegexTableEl;
41class RegexPattern;
42
43
44class U_I18N_API RegexCompile : public UMemory {
45public:
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
86private:
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
129public: // Public for testing only.
130 static void U_EXPORT2 findCaseInsensitiveStarters(UChar32 c, UnicodeSet *starterChars);
131private:
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
234enum 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
246U_NAMESPACE_END
247#endif // !UCONFIG_NO_REGULAR_EXPRESSIONS
248#endif // RBBISCAN_H
249