Skip to content
Architecture

Architecture

Architecture

Module map

Every public module of the trex crate.

ModuleResponsibility
actionthe action reading: the magnitude energy sum(m^2) and the stress load sum(depth) combined over a span
astthe pattern AST the parser emits and the engines consume, with quantifier normalization and the predicates the streaming, pipeline and device paths route on
bpelearned subword tokenization (byte-pair encoding)
buildera pattern built with its readings named, rather than parsed
byte_dfathe determinizer over a byte-grain automaton, built as it is walked
byte_lexthe lexer’s recognizers as byte automata
byte_nfaa byte-grain nondeterministic automaton and the simulation that reads it
byte_simdSIMD substring search (AVX2, SSE2 or scalar, chosen at run time, each returning the scalar path’s position) under the content guard
bytepatthe byte grain inside a token: a byte-pattern matched against one whole token
canonthe canonical representative of a symmetry orbit
capturesa capture buffer the caller owns and refills, and the pattern properties fixed before any input is seen
contextthe rolling context: every axis folded over a sliding window at the token and unit rungs, and the agreement of the grains’ boundaries
cursormatches taken one at a time, and the operations that stop before the end
curvaturefor each edge of the relation graph, how many neighbours its two ends share: positive in a dense region, negative at a bridge
customthe declarations a lex and a parse share: token shapes, token kinds declared from patterns over the stream, and the named sub-patterns \{name} inlines
decodedthe decoded content of an encoded token: a base64 blob’s bytes, a JSON Web Token’s header and payload
dual_grainlexing and matching on two threads as a producer and a consumer (dual-grain scanning)
e8the E8 root lattice and its Weyl group, the symmetry under the deepest orbit rung
echothe echo axis: whether each token’s content occurs elsewhere, how often, how far away and how regularly
editedit distance over whole tokens: whether one text is within k character insertions, deletions or substitutions of another
encodinginput transcoding: UTF-32, UTF-16 or UTF-8 selected by a byte-order mark, and BOM-less UTF-16 detected strictly enough never to misread binary
ends_simdthe leftmost, non-overlapping selection: the first anchor in a range whose longest match end lies past it, found a vector at a time
enginethe set-reachability engine with its register environment, for the patterns the single-pass engine routes away
entanglementthe count of enclosure, operator and reuse edges crossing each cut of the token stream; a cut with none splits two independent parts
explainwhat a match is made of, for --explain: the kinds of its tokens, the guard each passed, every axis the pattern read there, and the rung that answered
filesthe inputs a command reads: a tree walk under ignore rules, the binary check, the line and column of a byte offset, and a unified diff of a rewrite’s edits
flowthe flow axis: the windowed slope, direction, momentum and reversals of any per-token signal
followfiles followed as they grow: the bytes appended to each, and a note where one was truncated, replaced or removed
gaugea term with each bound name replaced by its de Bruijn index, so terms that differ only by renaming compare equal
geodesicthe shortest-path distance between two tokens through the relation graph, read against their distance in the stream
gputhe CUDA SIMT scan backend (the default gpu feature): detects the device at run time and falls back to the CPU
grammara parser generator over the typed tokens: named rules, left recursion as precedence, EBNF quantifiers and groups, and a semiring chart
gravitythe pull the input shows one unit type to have on another at a gap, and the readings taken from it
holographywhether the sequence of open and close bracket events alone reconstructs the lexer’s bracket pairing
indexan index over a tree that says which files a pattern cannot match, so a scan never opens them
inferpattern inference: the most specific pattern every example matches, read off an alignment of their token sequences
isawhich instruction-set rung this CPU can run, resolved once
kind_routea pattern that is a fixed sequence of token kinds, such as \W \N, answered over the lexer’s chunk parts in place
lexerbytes to typed tokens with bracket pairing; a multi-byte letter joins its word and a CJK run is one token
librarythe shipped library: named token kinds with a shape and, where a standard defines one, a checksum guard, and named sub-patterns
magnitudethe magnitude axis: each token’s order of magnitude, with its energy and gradient
nfathe single-pass engine, a Pike-style virtual machine over the token stream, and the device’s bit-NFA tables
observationthe observation axis: byte-class entropy read from past-only, future-only and centred windows, and where they disagree
orbitthe orbit axis: a token’s class under a symmetry such as case, shape or notation
paintcolor for reports: the depth a console renders, the roles a report paints, and the overrides --colors spells
parallel_lextokenization across cores, byte-identical to the serial lexer
parsera pattern string to a pattern AST
pattern_setmany patterns asked of one input over one lex
prefilterapproximate-membership filters over a corpus’s n-grams (Bloom, Cuckoo, Xor) answering whether a literal might occur, with no false negatives
prior_cachethe baked prior laid out on disk as the coder’s tables and mapped rather than decoded (the compress feature)
profilethe per-axis monoid that lifts a token reading to any unit above it
quantityphysical quantities: a number with a unit symbol, compared within the unit’s family after normalizing to its base unit
recordsthe units a record query (--all, --any, --none, --at-least) is asked of: lines, paragraphs, runs between matches, or regions an axis finds
relationthe relation axis: enclosure, operator, adjacency and reuse edges between tokens
reportthe text of a scan’s report for every surface: a match, its registers and an explanation as JSON, and lines with their matches painted
resonatora bank of complex-pole resonators over any symbol stream: period and phase at byte, token and unit grain
rewritetemplate substitution over matches: match, render, splice
rule_scanthe rules of pattern files scanned over an input, each finding reported under its rule with its message, severity and fix
seamthe seam axis: segmentation where the stream stops predicting itself, read in both directions
shapethe shape axis: each token’s shape, the period at which shapes repeat, and the regions that repeat like a table
spectralthe spectral axis: the texture, entropy and period of the byte stream at each position
streamingchunk-fed scanning that recovers exactly the matches a whole-input scan produces
stressthe stress axis: nesting depth, how long open spans are held, and where a deep structure closes
supertokenthe unit above the token: a run of tokens collapsed to a role-tagged unit, with no grammar
tandemCPU and GPU batch dispatch through the scheduler’s hybrid join (the default tandem feature, which implies gpu)
templateslog-template mining: lines grouped by token-kind silhouette, and the rarity of each line’s template
tokenthe typed-token contract the lexer and the engines share: kinds, spans, bracket mates, kind codes
tokutiltoken utilities the axes share: significant-token lexing, a hasher for pre-hashed keys, and the identifier-shape classifier
topologythe relation graph’s components, independent cycles b1 = E - V + b0, and Euler characteristic
tracewhich rung of a ladder answered a call
typedtyped value predicates: a kind atom’s {...} body compared in the type’s own units
windowthe part of an input a head, a tail or a line range selects, and readers that fetch only that much

Execution surfaces

The same pattern and the same matches are reachable through several backends, chosen by the caller. Each returns exactly what a plain whole-input scan returns.

SurfaceEntryWhat it adds
Whole-input scanscanthe default: a route where one answers, then the single-pass engine, then the set-reachability engine (the engine)
Streamingscan_chunked / StreamScannerfeed the input in chunks of any size and recover the whole-input match set; a match commits only once no later byte can change it, which for an unbounded pattern means once no attempt still running reaches back over the cut
Parallel tokenizationparallel_lex::lex_parallellex a large input across cores, stitched byte-identical to the serial lexer
Dual-grain pipelinescan_dual_grainrun lexing and matching on two threads as a producer and a consumer
Device backendscan_gpu, GpuTokensmap the all-starts scan onto a GPU for the alternation-free subset - typed atoms, magnitude tests, literals, byte classes, spectral tests against a per-token reading of the field the host builds, and one-token back-references with host-resolved captures (a bind and a spectral test do not share a device pattern); GpuTokens holds the tokens and their properties on the device across scans, upload_with_spectral the spectral reading too; falls back to the engine otherwise and when no device is present
Rewriterewrite / rewrite_with_backendreplace each match with a rendered template

The device backend compiles its kernel to PTX at build time and loads it through the driver at runtime, so a deployed binary needs only the graphics driver, not a full toolkit. Its eligibility gate keeps the device and the engine from ever disagreeing: a pattern the device cannot represent runs on the engine instead. The automatic router places a pattern that reads nothing of a token but its kind by what it has measured at the input’s size: the engine alone, or the input’s anchors split between the cores and the device at once, the share set by each side’s measured cost. A pattern that reads a property stays on the cores; --gpu forces a device attempt and --cpu forces the engine.

Regex parity

On the subset trex shares with a regular expression - literals, \N, \W, ., sequence, |, and the greedy and lazy quantifiers - the single-pass engine reports the spans the regex crate reports. The measurement is tests/conformance.rs: it generates a pattern as one abstract tree, renders it to both syntaxes so the two are equivalent by construction, and compares spans over generated corpora against the crate’s PikeVM, its reference machine. The test runs 20,000 cases at depth 6 by default, and TREX_CONFORMANCE_CASES and TREX_CONFORMANCE_DEPTH widen it:

CasesDepthComparisonsSingle-pass engine disagreesSet-reachability engine disagrees
20,0006118,520073
50,0006296,5920172
6,0001035,992054

The engine lays a loop out as the crate’s compiler does, so the two rank the same derivations the same way: a loop head is a plain split, a thread that returns to a head it already reached at this position is dropped, and a star over a body that can match empty is laid out as (P+)?. Where Perl and the crate differ - a loop iteration that matched empty ends the loop in Perl and is dropped as a duplicate in the crate, which then tries the body’s other alternatives before the exit - trex follows the crate.

The set-reachability engine, which runs only the constructs the single-pass engine routes away, is compared on the same cases. Its disagreements are nested quantifiers with a lazy inner, where it returns several shorter matches in place of one: (((\N \W . | .) (\N*){2,3}? . | \N*? | \W+?))+ . over 792 foo 313 baz is the one match [0..15] on the single-pass engine and the PikeVM, and [0..11], [12..15] on the set-reachability engine. The test prints every such case on each run.