/* Implementation of backtracking std.regex engine. Contains both compile-time and run-time versions. */ module std.regex.internal.backtracking; package(std.regex): import std.regex.internal.ir; import std.range.primitives, std.typecons, std.traits, core.stdc.stdlib; /+ BacktrackingMatcher implements backtracking scheme of matching regular expressions. +/ template BacktrackingMatcher(bool CTregex) { @trusted struct BacktrackingMatcher(Char, Stream = Input!Char) if (is(Char : dchar)) { alias DataIndex = Stream.DataIndex; struct State {//top bit in pc is set if saved along with matches DataIndex index; uint pc, counter, infiniteNesting; } static assert(State.sizeof % size_t.sizeof == 0); enum stateSize = State.sizeof / size_t.sizeof; enum initialStack = 1<<11; // items in a block of segmented stack alias String = const(Char)[]; alias RegEx = Regex!Char; alias MatchFn = bool function (ref BacktrackingMatcher!(Char, Stream)); const(Bytecode)[] ir; uint ngroup; uint flags; const(Interval[])[] charsets; const(CharMatcher)[] matchers; const(BitTable)[] filters; const Kickstart!Char kickstart; static if (CTregex) MatchFn nativeFn; //native code for that program //Stream state Stream s; DataIndex index; dchar front; bool exhausted; //backtracking machine state uint pc, counter; DataIndex lastState = 0; //top of state stack static if (!CTregex) uint infiniteNesting; size_t[] memory; Trace[] merge; static struct Trace { ulong mask; size_t offset; bool mark(size_t idx) { immutable d = idx - offset; if (d < 64) // including overflow { immutable p = mask & (1UL<