REAL
Regular Expression Algorithmic Library — constexpr C++20 regex
Loading...
Searching...
No Matches
real::detail::compiler Class Reference

Compiles an ast into a dynamic_program (NFA bytecode). More...

#include <compiler.hpp>

Collaboration diagram for real::detail::compiler:
[legend]

Public Member Functions

constexpr compiler (const ast &tree, flags compile_flags)
 Binds the compiler to a parsed pattern and its flags.
 
constexpr dynamic_program compile ()
 Emits the full NFA program for the bound AST.
 

Private Member Functions

constexpr void emit_codepoint_class (dynamic_program &prog, const char_class &ascii) const
 Emits "one codepoint matching \p ascii, or any non-ASCII codepoint".
 
constexpr void emit_byte_sequences (dynamic_program &prog, const std::vector< std::vector< char_class > > &branches) const
 Emits an alternation of byte-range sequences (branches) as split/jump — the general form of emit_codepoint_class. Each branch is a chain of klass steps; the leftmost matching branch wins. Used for a character class carrying specific code-point ranges.
 
constexpr void emit_class_codepoints (dynamic_program &prog, const char_class &ascii, const std::vector< code_range > &ranges) const
 Emits a code-point class: the ASCII bitmap (one byte, if any) OR the canonical UTF-8 byte sequences of each code-point range. This is the specific-code-point generalization of emit_codepoint_class (whose [U+0080, U+10FFFF] "any non-ASCII" is one case).
 
constexpr class_def effective_class (const ast_node &node) const
 The class a node_kind::klass node effectively accepts, after negation, icase folding and the bytes/code-point split. This is the ONE source of truth consumed by both emit_node and l_max_bytes, so what is emitted and its measured width can never disagree. Positive: as written. Negated: the ASCII complement plus, in code-point mode, the code-point complement over [U+0080, U+10FFFF] minus surrogates.
 
constexpr void emit_node (dynamic_program &prog, std::int32_t index, bool capture_free=false) const
 Emits the bytecode for the AST node at index (recursively).
 
constexpr assert_kind assert_kind_for (anchor_kind anchor, flags node_flags) const
 Maps an AST anchor_kind to the runtime assert_kind.
 
constexpr void emit_alternation (dynamic_program &prog, const ast_node &node, bool capture_free) const
 Emits an alternation: branches chained with leftmost-preferred splits.
 
constexpr void emit_repeat (dynamic_program &prog, const ast_node &node, bool capture_free) const
 Emits a quantifier (Thompson construction).
 
constexpr void emit_lookaround (dynamic_program &prog, const ast_node &node, bool capture_free) const
 Emits a bounded lookaround: an assert_lookaround whose sub-program is a capture-free region the main flow jumps over.
 
constexpr std::int32_t l_max_bytes (std::int32_t index) const
 Upper bound, in bytes, on what the sub-AST at index can consume; -1 if unbounded (a *, + or {n,} repeat) or if it nests a lookaround.
 

Static Private Member Functions

static constexpr std::int32_t here (const dynamic_program &prog)
 Returns the index of the next instruction.
 
static constexpr void emit (dynamic_program &prog, instr instruction)
 Appends one instruction, enforcing the program-size cap.
 
static constexpr std::int32_t emit_split (dynamic_program &prog)
 Emits a split with placeholder targets.
 
static constexpr std::int32_t emit_jump (dynamic_program &prog)
 Emits a jump with a placeholder target.
 
static constexpr void patch_primary (dynamic_program &prog, std::int32_t pc, std::int32_t target)
 Sets the primary branch target of the instruction at pc.
 
static constexpr void patch_secondary (dynamic_program &prog, std::int32_t pc, std::int32_t target)
 Sets the secondary branch target of the split at pc.
 
static constexpr void emit_klass (dynamic_program &prog, const char_class &klass)
 Emits a klass instruction, interning klass.
 
static constexpr void emit_klass_cp (dynamic_program &prog, const class_def &cd)
 Emits a match-time code-point predicate for a Unicode shorthand (\w \d \s and their negations) in text mode: a klass_cp over the interned code-point class, followed by a three-instruction continuation chain (klass utf8_cont ×3). At match time klass_cp decodes one code point and, on membership, enters the chain at a computed skip so the remaining continuation bytes are walked one per step — see pike.hpp. The class is the already-effective set (the fold and any external negation were materialised by effective_class), so membership is a plain positive test.
 

Private Attributes

const asttree_
 The AST being compiled.
 
flags flags_ {flags::none}
 Effective compilation flags.
 

Detailed Description

Compiles an ast into a dynamic_program (NFA bytecode).

Definition at line 108 of file compiler.hpp.

Constructor & Destructor Documentation

◆ compiler()

constexpr real::detail::compiler::compiler ( const ast tree,
flags  compile_flags 
)
inlineconstexpr

Binds the compiler to a parsed pattern and its flags.

Parameters
[in]treeThe AST to compile (borrowed, must outlive the compiler).
[in]compile_flagsThe effective compilation flags.

Definition at line 117 of file compiler.hpp.

Member Function Documentation

◆ assert_kind_for()

constexpr assert_kind real::detail::compiler::assert_kind_for ( anchor_kind  anchor,
flags  node_flags 
) const
inlineconstexprprivate

Maps an AST anchor_kind to the runtime assert_kind.

^ and $ depend on the multiline flag; everything else maps one-to-one.

Parameters
[in]anchorThe AST anchor kind.
[in]node_flagsThe flag set in force at this anchor's scope; its multiline selects the line-relative vs absolute form of ^/$ (a scoped (?m:...)).
Returns
The assertion the engine should evaluate.

Definition at line 616 of file compiler.hpp.

◆ compile()

constexpr dynamic_program real::detail::compiler::compile ( )
inlineconstexpr

Emits the full NFA program for the bound AST.

Returns
The compiled dynamic_program (code, classes, names, hints).
Exceptions
real::regex_errorif the program exceeds max_program_size.

Definition at line 128 of file compiler.hpp.

◆ effective_class()

constexpr class_def real::detail::compiler::effective_class ( const ast_node node) const
inlineconstexprprivate

The class a node_kind::klass node effectively accepts, after negation, icase folding and the bytes/code-point split. This is the ONE source of truth consumed by both emit_node and l_max_bytes, so what is emitted and its measured width can never disagree. Positive: as written. Negated: the ASCII complement plus, in code-point mode, the code-point complement over [U+0080, U+10FFFF] minus surrogates.

Definition at line 451 of file compiler.hpp.

◆ emit()

static constexpr void real::detail::compiler::emit ( dynamic_program prog,
instr  instruction 
)
inlinestaticconstexprprivate

Appends one instruction, enforcing the program-size cap.

The check lives inside emit so it fires during a large unroll loop, before the vector grows to the full bad size — this is the central defense (max_program_size) against the DoS where tiny nested bounded quantifiers expand to hundreds of millions of instructions. It is constexpr-friendly: exceeding the cap fails compilation for a static_regex, or throws at run time.

Parameters
[in,out]progThe program being built.
[in]instructionThe instruction to append.
Exceptions
real::regex_errorwhen max_program_size would be exceeded.

Definition at line 183 of file compiler.hpp.

◆ emit_alternation()

constexpr void real::detail::compiler::emit_alternation ( dynamic_program prog,
const ast_node node,
bool  capture_free 
) const
inlineconstexprprivate

Emits an alternation: branches chained with leftmost-preferred splits.

Every branch but the last jumps to a shared exit, patched once at the end.

Parameters
[in,out]progThe program being built.
[in]nodeThe node_kind::alternation node.
[in]capture_freePropagated to each branch (see emit_node).

Definition at line 668 of file compiler.hpp.

◆ emit_byte_sequences()

constexpr void real::detail::compiler::emit_byte_sequences ( dynamic_program prog,
const std::vector< std::vector< char_class > > &  branches 
) const
inlineconstexprprivate

Emits an alternation of byte-range sequences (branches) as split/jump — the general form of emit_codepoint_class. Each branch is a chain of klass steps; the leftmost matching branch wins. Used for a character class carrying specific code-point ranges.

Definition at line 389 of file compiler.hpp.

◆ emit_class_codepoints()

constexpr void real::detail::compiler::emit_class_codepoints ( dynamic_program prog,
const char_class ascii,
const std::vector< code_range > &  ranges 
) const
inlineconstexprprivate

Emits a code-point class: the ASCII bitmap (one byte, if any) OR the canonical UTF-8 byte sequences of each code-point range. This is the specific-code-point generalization of emit_codepoint_class (whose [U+0080, U+10FFFF] "any non-ASCII" is one case).

Definition at line 416 of file compiler.hpp.

◆ emit_codepoint_class()

constexpr void real::detail::compiler::emit_codepoint_class ( dynamic_program prog,
const char_class ascii 
) const
inlineconstexprprivate

Emits "one codepoint matching \p ascii, or any non-ASCII codepoint".

Expands to the byte-level alternation ascii | lead2 cont | lead3 cont cont | lead4 cont cont cont, so the engine steps one byte at a time while still consuming whole codepoints. The UTF-8 byte sets come from charclass.hpp, shared with the prefilter that recognizes this exact shape.

Parameters
[in,out]progThe program being built.
[in]asciiThe accepted ASCII bytes (the non-ASCII branches are always included).

Definition at line 338 of file compiler.hpp.

◆ emit_jump()

static constexpr std::int32_t real::detail::compiler::emit_jump ( dynamic_program prog)
inlinestaticconstexprprivate

Emits a jump with a placeholder target.

Returns
Its instruction index.

Definition at line 206 of file compiler.hpp.

◆ emit_klass()

static constexpr void real::detail::compiler::emit_klass ( dynamic_program prog,
const char_class klass 
)
inlinestaticconstexprprivate

Emits a klass instruction, interning klass.

Identical bitmaps share one slot, so the UTF-8 continuation class is stored once however often it is emitted.

Parameters
[in,out]progThe program being built.
[in]klassThe class bitmap to match.
Exceptions
real::regex_errorif more than 65536 distinct classes are needed.

Definition at line 248 of file compiler.hpp.

◆ emit_klass_cp()

static constexpr void real::detail::compiler::emit_klass_cp ( dynamic_program prog,
const class_def cd 
)
inlinestaticconstexprprivate

Emits a match-time code-point predicate for a Unicode shorthand (\w \d \s and their negations) in text mode: a klass_cp over the interned code-point class, followed by a three-instruction continuation chain (klass utf8_cont ×3). At match time klass_cp decodes one code point and, on membership, enters the chain at a computed skip so the remaining continuation bytes are walked one per step — see pike.hpp. The class is the already-effective set (the fold and any external negation were materialised by effective_class), so membership is a plain positive test.

Parameters
[in,out]progThe program being built.
[in]cdThe effective code-point class (ASCII bitmap + non-ASCII ranges).

Definition at line 279 of file compiler.hpp.

◆ emit_lookaround()

constexpr void real::detail::compiler::emit_lookaround ( dynamic_program prog,
const ast_node node,
bool  capture_free 
) const
inlineconstexprprivate

Emits a bounded lookaround: an assert_lookaround whose sub-program is a capture-free region the main flow jumps over.

Layout: assert_lookaround sub_id; jump AFTER; [sub-program] match; AFTER: …. The main VM only steps the assert_lookaround (epsilon) and the skip-jump; the sub region is entered solely by the sub-VM at code_offset. The sub-pattern must be bounded (L_max in bytes ≤ max_lookaround_length) — the linear-time guarantee.

Parameters
[in,out]progThe program being built.
[in]nodeThe node_kind::lookaround node.
[in]capture_freeTrue only when already inside a lookaround (rejected).
Exceptions
real::regex_erroron an unbounded or over-long sub-pattern, or nesting.

Definition at line 764 of file compiler.hpp.

◆ emit_node()

constexpr void real::detail::compiler::emit_node ( dynamic_program prog,
std::int32_t  index,
bool  capture_free = false 
) const
inlineconstexprprivate

Emits the bytecode for the AST node at index (recursively).

Parameters
[in,out]progThe program being built.
[in]indexIndex of the node in ast::nodes.
[in]capture_freeWhen true, capturing groups emit no save ops — used inside a lookaround sub-program, whose captures do not participate in the overall match.

Definition at line 494 of file compiler.hpp.

◆ emit_repeat()

constexpr void real::detail::compiler::emit_repeat ( dynamic_program prog,
const ast_node node,
bool  capture_free 
) const
inlineconstexprprivate

Emits a quantifier (Thompson construction).

Greedy prefers split.primary_target (enter the body); lazy swaps the branches. Counted forms unroll: min mandatory copies, then either a loop (max == -1) or optional copies sharing one exit.

Parameters
[in,out]progThe program being built.
[in]nodeThe node_kind::repeat node.
[in]capture_freePropagated to the body copies (see emit_node).

Definition at line 705 of file compiler.hpp.

◆ emit_split()

static constexpr std::int32_t real::detail::compiler::emit_split ( dynamic_program prog)
inlinestaticconstexprprivate

Emits a split with placeholder targets.

Returns
Its instruction index.

Definition at line 196 of file compiler.hpp.

◆ here()

static constexpr std::int32_t real::detail::compiler::here ( const dynamic_program prog)
inlinestaticconstexprprivate

Returns the index of the next instruction.

Parameters
[in]progThe program.
Returns
The index of the next instruction.

Definition at line 164 of file compiler.hpp.

◆ l_max_bytes()

constexpr std::int32_t real::detail::compiler::l_max_bytes ( std::int32_t  index) const
inlineconstexprprivate

Upper bound, in bytes, on what the sub-AST at index can consume; -1 if unbounded (a *, + or {n,} repeat) or if it nests a lookaround.

Codepoint-consuming shapes (., a negated class outside bytes mode) count as one codepoint = up to 4 bytes (A1); a literal byte or an ASCII class is one byte.

Parameters
[in]indexIndex of the sub-AST node.
Returns
The byte upper bound, or -1 when not statically bounded.

Definition at line 807 of file compiler.hpp.

◆ patch_primary()

static constexpr void real::detail::compiler::patch_primary ( dynamic_program prog,
std::int32_t  pc,
std::int32_t  target 
)
inlinestaticconstexprprivate

Sets the primary branch target of the instruction at pc.

Parameters
[in,out]progThe program being built.
[in]pcIndex of the split/jump to patch.
[in]targetInstruction index to branch to.

Definition at line 218 of file compiler.hpp.

◆ patch_secondary()

static constexpr void real::detail::compiler::patch_secondary ( dynamic_program prog,
std::int32_t  pc,
std::int32_t  target 
)
inlinestaticconstexprprivate

Sets the secondary branch target of the split at pc.

Parameters
[in,out]progThe program being built.
[in]pcIndex of the split to patch.
[in]targetInstruction index to branch to.

Definition at line 231 of file compiler.hpp.

Member Data Documentation

◆ flags_

flags real::detail::compiler::flags_ {flags::none}
private

Effective compilation flags.

Definition at line 155 of file compiler.hpp.

◆ tree_

const ast& real::detail::compiler::tree_
private

The AST being compiled.

Definition at line 154 of file compiler.hpp.


The documentation for this class was generated from the following file: