REAL
Regular Expression Algorithmic Library — constexpr C++20 regex
Loading...
Searching...
No Matches
program.hpp
Go to the documentation of this file.
1
10#ifndef REAL_PROGRAM_HPP
11#define REAL_PROGRAM_HPP
12
13// Internal — do not include directly.
14// Users: #include <real/real.hpp> (or the documented opt-ins <real/dfa.hpp>, <real/std/regex.hpp>).
15
16#include "real/version.hpp"
17
18#include <array>
19#include <cstdint>
20#include <exception>
21#include <limits>
22#include <span>
23#include <string>
24#include <vector>
25
27
28namespace real {
29
33 inline constexpr std::size_t npos {std::numeric_limits<std::size_t>::max()};
34
41 enum class flags : std::uint8_t
42 {
43 none = 0,
44 icase = 1,
45 multiline = 2,
46 dotall = 4,
47 bytes = 8,
48 verbose = 16,
49 ecma = 32,
50 ascii = 64,
51 dollar_endonly = 128,
52 };
53
56 enum class match_semantics : std::uint8_t
57 {
58 first = 0,
59 longest = 1,
60 };
61
68 constexpr flags operator|(flags lhs,
69 flags rhs)
70 {
71 return static_cast<flags>(static_cast<std::uint8_t>(lhs) | static_cast<std::uint8_t>(rhs));
72 }
73
80 constexpr flags operator&(flags lhs,
81 flags rhs)
82 {
83 return static_cast<flags>(static_cast<std::uint8_t>(lhs) & static_cast<std::uint8_t>(rhs));
84 }
85
92 constexpr bool has_flag(flags value,
93 flags flag)
94 {
95 return (value & flag) != flags::none;
96 }
97
107 enum class error_kind : std::uint8_t
108 {
109 syntax,
111 };
112
113 class regex_error : public std::exception
114 {
115 public:
116
123 regex_error(const std::string& message,
124 std::size_t position,
126 : message_("regex_error at " + std::to_string(position) + ": " + message),
128 kind_(kind)
129 {}
130
134 [[nodiscard]] error_kind kind() const noexcept
135 {
136 return kind_;
137 }
138
142 [[nodiscard]] const char* what() const noexcept override
143 {
144 return message_.c_str();
145 }
146
150 [[nodiscard]] std::size_t position() const noexcept
151 {
152 return position_;
153 }
154
155 private:
156
157 std::string message_;
158 std::size_t position_;
160 };
161
162 namespace detail {
163
168 {
169 std::uint32_t lo {};
170 std::uint32_t hi {};
171 };
172
178 struct cp_class
179 {
181 std::uint32_t range_begin {};
182 std::uint32_t range_count {};
183 };
184
188 enum class opcode : std::uint8_t
189 {
190 byte,
191 klass,
192 klass_cp,
193 split,
194 jump,
195 save,
197 match,
199 };
200
207 enum class assert_kind : std::uint8_t
208 {
209 text_start,
210 text_end,
212 line_start,
213 line_end,
216 word_start,
217 word_end,
218 };
219
223 enum class look_dir : std::uint8_t
224 {
225 ahead,
226 behind,
227 };
228
239 {
240 std::int32_t code_offset {};
241 std::int32_t code_length {};
242 std::int32_t l_max {};
244 bool negative {};
245 };
246
250 struct instr
251 {
253 std::uint8_t arg8 {};
254 std::uint16_t arg16 {};
255 std::int32_t primary_target {};
256 std::int32_t secondary_target {};
257 };
258
267 {
268 std::array<char, 16> prefix {};
269 std::uint8_t prefix_size {};
274 std::int16_t single_first {-1};
276 std::array<char, 4> small_set {};
277 std::uint8_t small_set_size {};
278 std::int32_t greedy_class_loop {-1};
279 std::int32_t greedy_cp_class {-1};
281 std::int16_t greedy_group_start {-1};
282 std::int16_t greedy_group_end {-1};
283 bool fixed_shape {};
284 std::int32_t codepoint_class_ascii {-1};
287
296 std::uint8_t exact_literal_len {};
297
301 std::array<char, 6> stop_set {};
302 std::uint8_t stop_set_size {};
303
308 std::int16_t rare_byte {-1};
309 std::uint8_t rare_offset {};
310
317 std::array<std::uint8_t, 16> inner_literal {};
318 std::uint8_t inner_literal_len {};
319 std::int32_t inner_literal_prefix {-1};
320 };
321
329 {
330 std::int32_t group {};
331 std::int32_t begin {};
332 std::int32_t end {};
333 };
334
344 struct regex_immutables;
346 {
347 std::span<const instr> code;
348 std::span<const char_class> classes;
349 std::span<const named_group> names;
350 std::span<const lookaround_sub> lookarounds;
351 std::span<const cp_class> cp_classes;
352 std::span<const code_range> cp_ranges;
353 std::span<const instr> prefix_code;
354 std::span<const char_class> prefix_classes;
355 std::span<const cp_class> prefix_cp_classes;
356 std::span<const code_range> prefix_cp_ranges;
357 std::uint16_t slot_count {2};
358 bool byte_mode {};
359 bool unicode_word {};
362 };
363
368 {
369 std::vector<instr> code;
370 std::vector<char_class> classes;
371 std::vector<named_group> names;
372 std::vector<lookaround_sub> lookarounds;
373 std::vector<cp_class> cp_classes;
374 std::vector<code_range> cp_ranges;
375 std::vector<instr> prefix_code;
376 std::vector<char_class> prefix_classes;
377 std::vector<cp_class> prefix_cp_classes;
378 std::vector<code_range> prefix_cp_ranges;
379 std::uint16_t slot_count {2};
380 bool byte_mode {};
381 bool unicode_word {};
383
384 // Codepoint-class marker, set by `emit_codepoint_class` at emission so the
385 // prefilter need not reverse-engineer the emitted block's bytecode shape.
386 std::int32_t codepoint_mark_ascii {-1};
387 std::int32_t codepoint_mark_offset {-1};
388
392 [[nodiscard]] constexpr program_view view() const
393 {
394 return {.code = std::span<const instr>(code),
395 .classes = std::span<const char_class>(classes),
396 .names = std::span<const named_group>(names),
397 .lookarounds = std::span<const lookaround_sub>(lookarounds),
398 .cp_classes = std::span<const cp_class>(cp_classes),
399 .cp_ranges = std::span<const code_range>(cp_ranges),
400 .prefix_code = std::span<const instr>(prefix_code),
401 .prefix_classes = std::span<const char_class>(prefix_classes),
402 .prefix_cp_classes = std::span<const cp_class>(prefix_cp_classes),
403 .prefix_cp_ranges = std::span<const code_range>(prefix_cp_ranges),
404 .slot_count = slot_count,
405 .byte_mode = byte_mode,
406 .unicode_word = unicode_word,
407 .hints = hints};
408 }
409 };
410 } // namespace detail
411} // namespace real
412
413#endif // REAL_PROGRAM_HPP
256-bit byte set with O(1) membership, fully constexpr.
error_kind kind_
Malformed (syntax) vs unsupported-by-REAL.
Definition program.hpp:159
std::size_t position_
Offset in the pattern text.
Definition program.hpp:158
regex_error(const std::string &message, std::size_t position, error_kind kind=error_kind::syntax)
Builds the error.
Definition program.hpp:123
const char * what() const noexcept override
Returns the formatted error message (with position).
Definition program.hpp:142
std::string message_
Formatted message returned by what().
Definition program.hpp:157
error_kind kind() const noexcept
Whether the pattern is malformed (syntax) or well-formed but unsupported by REAL.
Definition program.hpp:134
std::size_t position() const noexcept
Returns the byte offset in the pattern where the error was found.
Definition program.hpp:150
look_dir
Direction of a lookaround sub-pattern.
Definition program.hpp:224
@ ahead
(?= / (?! — the sub matches starting at the position.
@ behind
(?<= / (?<! — the sub matches ending exactly at the position.
assert_kind
Kind of zero-width assertion carried in assert_position's arg8.
Definition program.hpp:208
@ word_start
< (non-word/start on the left, word on the right).
@ word_end
> (word on the left, non-word/end on the right).
@ line_start
^ with multiline.
@ line_end
$ with multiline.
@ word_boundary
\b (Unicode word-ness in text mode; ASCII in bytes / re.A).
@ text_start
\A, and ^ without multiline.
@ text_end_or_final_newline
$ without multiline (Python semantics).
opcode
NFA instruction opcodes executed by the Pike VM.
Definition program.hpp:189
@ klass_cp
Consume one code point tested against cp_classes[arg16] (decode + range bsearch); enters a 3-instr co...
@ byte
Consume one byte equal to arg8; fall through to pc+1.
@ save
Store current position in slot arg16; fall through (epsilon).
@ klass
Consume one byte in classes[arg16]; fall through to pc+1.
@ assert_lookaround
Epsilon; proceeds only if the lookaround sub-program arg16 holds here.
@ assert_position
Epsilon; proceeds only if assertion arg8 holds here.
@ jump
Epsilon-jump to x.
@ split
Epsilon-branch to x (preferred) and y.
error_kind
Exception thrown for an invalid pattern (or one exceeding a limit).
Definition program.hpp:108
constexpr std::size_t npos
Sentinel for "no position" / unset capture slot (akin to std::string::npos).
Definition program.hpp:33
match_semantics
Which match a search returns among those starting at the leftmost position (an experimental,...
Definition program.hpp:57
@ longest
Leftmost-longest (POSIX / RE2 set_longest_match): the longest overall match wins the bounds.
@ first
Leftmost-first (Perl / Python re / the crate): source-order thread priority decides....
constexpr bool has_flag(flags value, flags flag)
Tests whether flag is set in value.
Definition program.hpp:92
constexpr flags operator|(flags lhs, flags rhs)
Bitwise-OR of two flag sets.
Definition program.hpp:68
constexpr flags operator&(flags lhs, flags rhs)
Bitwise-AND of two flag sets.
Definition program.hpp:80
flags
Compilation flags, mirroring Python's re.I, re.M and re.S.
Definition program.hpp:42
@ dotall
. also matches \n.
@ verbose
Verbose mode (re.X): ignore unescaped whitespace and # comments outside classes.
@ none
No flags.
@ bytes
Binary mode: . and [^…] match raw bytes, not codepoints.
@ ascii
ASCII mode (re.A): \d \w \s \b stay ASCII and icase folds ASCII only, even in text mode....
@ icase
Case-insensitive (ASCII).
@ ecma
ECMAScript compatibility: $ (no multiline) matches only at the very end (not before a final \n,...
@ multiline
^ and $ also match at line boundaries.
@ dollar_endonly
$ (no multiline) matches only at the very end of the text, never before a final \n — the Rust/\z sema...
A set of byte values (0–255) as a 256-bit bitmap.
Definition charclass.hpp:30
An inclusive code-point range [lo, hi]. Shared by character classes (ast.hpp) and the generated Unico...
Definition program.hpp:168
std::uint32_t lo
First code point (inclusive).
Definition program.hpp:169
std::uint32_t hi
Last code point (inclusive).
Definition program.hpp:170
A match-time code-point class for the klass_cp opcode: an ASCII bitmap for code points < 0x80 plus a ...
Definition program.hpp:179
std::uint32_t range_count
Number of ranges belonging to this class.
Definition program.hpp:182
std::uint32_t range_begin
First range in the program's cp_ranges buffer.
Definition program.hpp:181
char_class ascii
Members < 0x80.
Definition program.hpp:180
Owning, heap-allocated program: the storage backing real::regex.
Definition program.hpp:368
std::int32_t codepoint_mark_ascii
ASCII sub-class index of an emitted codepoint-class block (-1 = none).
Definition program.hpp:386
std::vector< cp_class > cp_classes
Match-time code-point classes (for klass_cp).
Definition program.hpp:373
pattern_hints hints
Search-acceleration hints.
Definition program.hpp:382
std::vector< instr > prefix_code
IL: the inner-literal prefix sub-program (the part before the literal), for the reverse start-finder....
Definition program.hpp:375
std::uint16_t slot_count
2 * (capture groups + 1).
Definition program.hpp:379
std::vector< instr > code
The instruction stream (main program + lookaround sub-program regions).
Definition program.hpp:369
std::vector< char_class > prefix_classes
IL: classes for prefix_code.
Definition program.hpp:376
constexpr program_view view() const
Returns a non-owning program_view over this program.
Definition program.hpp:392
std::int32_t codepoint_mark_offset
Where that block starts (program offset); the whole-pattern hint requires offset 1.
Definition program.hpp:387
std::vector< cp_class > prefix_cp_classes
IL: code-point classes (klass_cp) for prefix_code.
Definition program.hpp:377
std::vector< code_range > prefix_cp_ranges
IL: flat range buffer for prefix_cp_classes.
Definition program.hpp:378
bool unicode_word
\b \B < > use Unicode word-ness (text mode).
Definition program.hpp:381
std::vector< code_range > cp_ranges
Flat range buffer the cp_class slices index into.
Definition program.hpp:374
bool byte_mode
flags::bytes mode.
Definition program.hpp:380
std::vector< lookaround_sub > lookarounds
Bounded lookaround sub-programs (regions of code).
Definition program.hpp:372
std::vector< char_class > classes
Interned character classes.
Definition program.hpp:370
std::vector< named_group > names
Named capture groups.
Definition program.hpp:371
The best required inner literal of a pattern (the memmem candidate). len == 0 means the pattern decli...
One NFA instruction. Field meaning depends on op.
Definition program.hpp:251
std::int32_t secondary_target
Secondary branch target (split).
Definition program.hpp:256
std::uint8_t arg8
Byte literal, or assert_kind, depending on op.
Definition program.hpp:253
std::uint16_t arg16
Class index (klass) or capture slot (save).
Definition program.hpp:254
opcode op
The operation.
Definition program.hpp:252
std::int32_t primary_target
Primary branch target (split/jump).
Definition program.hpp:255
A bounded lookaround sub-program, referenced by assert_lookaround's arg16.
Definition program.hpp:239
std::int32_t code_length
Instruction count of the sub-program.
Definition program.hpp:241
bool negative
(?! / (?<! (negated assertion).
Definition program.hpp:244
std::int32_t code_offset
First instruction of the sub-program in code.
Definition program.hpp:240
std::int32_t l_max
Max bytes the sub-pattern can consume (bounded).
Definition program.hpp:242
look_dir direction
Ahead or behind.
Definition program.hpp:243
A named capture group.
Definition program.hpp:329
std::int32_t begin
Start offset of the name in the pattern text.
Definition program.hpp:331
std::int32_t end
End offset (exclusive) of the name.
Definition program.hpp:332
std::int32_t group
Capture group number.
Definition program.hpp:330
Search-acceleration hints extracted from a compiled program.
Definition program.hpp:267
std::uint8_t exact_literal_len
Length of the pure-literal match, or 0.
Definition program.hpp:296
bool greedy_cp_class_plus
The greedy_cp_class pattern is a greedy + loop (vs a single code point).
Definition program.hpp:280
std::int16_t rare_byte
A required literal byte at a fixed offset from the match start that is statically rarer than the patt...
Definition program.hpp:308
std::array< char, 16 > prefix
Required literal prefix (possibly truncated).
Definition program.hpp:268
std::int32_t inner_literal_prefix
Definition program.hpp:319
bool fixed_alternation
Whole pattern is an alternation of straight-line branches (no captures/asserts).
Definition program.hpp:286
bool anchored_start
\A / ^ (no multiline): only position 0.
Definition program.hpp:270
std::uint8_t prefix_size
Valid bytes in prefix.
Definition program.hpp:269
std::int16_t greedy_group_start
For a class-loop wrapped in one capturing group ((\w+), ([a-z]+)): the group's start slot to mirror t...
Definition program.hpp:281
std::array< char, 6 > stop_set
For a whole-pattern class+ run whose accepted set has a small (<= 6-byte) complement: the STOP bytes ...
Definition program.hpp:301
bool line_anchored
^ multiline: position 0 or after \n.
Definition program.hpp:271
std::int16_t greedy_group_end
The enveloping group's end slot (mirrors the whole-match end).
Definition program.hpp:282
std::int32_t greedy_cp_class
cp_class index if the whole pattern is a code-point class klass_cp (optionally +),...
Definition program.hpp:279
bool empty_match_possible
The pattern can match the empty string (the nullable gate; conservative: assertions/lookarounds pass ...
Definition program.hpp:273
std::int32_t greedy_class_loop
Class index if the whole pattern is "class+", else -1.
Definition program.hpp:278
std::uint8_t small_set_size
Number of valid members in small_set — 0 when not a small set, else 2..4. Drives the memchr-cascade s...
Definition program.hpp:277
bool fixed_shape
Whole pattern is a fixed-width byte/klass sequence (no branches/asserts/captures).
Definition program.hpp:283
char_class first_bytes
All possible first bytes.
Definition program.hpp:275
bool codepoint_class_plus
The codepoint_class_ascii pattern is a greedy + loop (vs a single codepoint).
Definition program.hpp:285
std::uint8_t inner_literal_len
Definition program.hpp:318
std::uint8_t stop_set_size
Members in stop_set — 0 when the complement is too large, else 1..6.
Definition program.hpp:302
bool first_bytes_valid
False when an empty match is possible.
Definition program.hpp:272
std::array< char, 4 > small_set
The 2..4 possible first bytes, enumerated (the memchr-cascade set). Empty unless small_set_size is se...
Definition program.hpp:276
std::uint8_t rare_offset
The fixed byte offset of rare_byte from the match start.
Definition program.hpp:309
std::int32_t codepoint_class_ascii
ASCII-class index when the whole pattern is ./negated-class (optionally +), else -1.
Definition program.hpp:284
std::int16_t single_first
The unique possible first byte, or -1.
Definition program.hpp:274
bool byte_mode
flags::bytes mode — positions are raw bytes.
Definition program.hpp:358
std::span< const instr > prefix_code
IL: inner-literal prefix sub-program (the reverse start-finder). Empty unless there is a required lit...
Definition program.hpp:353
std::span< const named_group > names
Named capture groups.
Definition program.hpp:349
regex_immutables * immut
Per-regex DFA/one-pass cache (dynamic storage only; else null).
Definition program.hpp:361
std::span< const lookaround_sub > lookarounds
Bounded lookaround sub-programs (regions of code).
Definition program.hpp:350
std::span< const code_range > prefix_cp_ranges
IL: flat range buffer for prefix_cp_classes.
Definition program.hpp:356
std::uint16_t slot_count
2 * (capture groups + 1).
Definition program.hpp:357
std::span< const cp_class > prefix_cp_classes
IL: code-point classes for prefix_code.
Definition program.hpp:355
pattern_hints hints
Search-acceleration hints.
Definition program.hpp:360
std::span< const code_range > cp_ranges
Flat range buffer the cp_class slices index into.
Definition program.hpp:352
bool unicode_word
\b \B < > use Unicode word-ness (text mode, not bytes / re.A).
Definition program.hpp:359
std::span< const char_class > prefix_classes
IL: classes for prefix_code.
Definition program.hpp:354
std::span< const char_class > classes
Interned character classes.
Definition program.hpp:348
std::span< const cp_class > cp_classes
Match-time code-point classes (for klass_cp).
Definition program.hpp:351
std::span< const instr > code
The instruction stream (main + lookaround regions).
Definition program.hpp:347
The per-regex immutable cache the router shares across every find_iter on a regex: the byte- program ...
Definition onepass.hpp:502
REAL's version macros and the C++20 language-standard guard.