70 lines
3.7 KiB
C#
70 lines
3.7 KiB
C#
// -----------------------------------------------------------------------------
|
|
// file="TextRegexSourceGen.GenClass.SingleIR"
|
|
// Project: StgSharp
|
|
// Copyright (c) Nitload.
|
|
// SPDX-License-Identifier: MIT
|
|
// -----------------------------------------------------------------------------
|
|
|
|
namespace StgSharp.RegularAnalysis.Text
|
|
{
|
|
internal partial class TextRegexSourceGen
|
|
{
|
|
|
|
/*
|
|
* =======================================================================================
|
|
* L4, one instruction
|
|
* =======================================================================================
|
|
*
|
|
* The fallback of the dispatch chain. Every RegexIRCommand needs a generator here, because
|
|
* this is the only layer guaranteed to be offered every window. L1 and L3 may decline, L4
|
|
* may not.
|
|
*
|
|
* Each generator consumes exactly one entry and describes only what the instruction does.
|
|
* When it runs, which result it reads and whether it leaves the region early are all added
|
|
* by L5, so nothing here should inspect RegexIR.Prefix beyond WorkingRegion.
|
|
*
|
|
* Contract for a generated body, names owned by SourceGenContext:
|
|
*
|
|
* - assign the outcome to __ok
|
|
* - advance __cur only on success
|
|
* - never index __cur past the end of the input
|
|
* - declare scratch variables inside a block of their own, so a repeated shape does not
|
|
* collide with itself
|
|
*
|
|
* A body must be generated into a detached emitter and only spliced in once it is known to
|
|
* be claimed. Emitting a prefix for an instruction that turns out to have no generator
|
|
* would open a brace nobody closes.
|
|
*
|
|
* Checklist:
|
|
*
|
|
* L4.1 MATCH_SEQ abc, \., a\*b
|
|
* L4.2 MATCH_SET, discrete [abc], [123abc], [.]
|
|
* L4.3 MATCH_SET, range [1-9]
|
|
* L4.4 MATCH_SET, escape class \w
|
|
* L4.5 MATCH_SET, any element .
|
|
* L4.6 COUNT_SEQ a*, a?
|
|
* L4.7 COUNT_SET [abc]*, \w+, .{11,13}, [.]*
|
|
* L4.8 FIND_SEQ degradation path of .*abc
|
|
* L4.9 FIND_SET -
|
|
* L4.10 POP ALT tail
|
|
* L4.11 PACK (abc), ordinal group
|
|
*
|
|
* Semantics worth pinning down before writing these:
|
|
*
|
|
* - [.] and . are different sets. The former is a literal dot, the latter is any
|
|
* element, and [.]* must not be folded into the dot star optimisation.
|
|
* - \w has to keep full .NET semantics. TextRegex.IsCharWord is inherited by the
|
|
* generated class and already carries them, so the generated code can call it
|
|
* directly instead of approximating with an ASCII test.
|
|
* - This backend does not backtrack. A lazy repetition therefore consumes exactly its
|
|
* lower bound and leaves the rest to the following anchor. Lazy forms needing more
|
|
* are expected to have been rewritten into a find by the IR optimizer, so confirm
|
|
* that before adding backtracking here.
|
|
* - An epsilon sequence and an empty repetition unit both reach these generators.
|
|
* Decide whether they are vacuous successes or an optimizer bug worth reporting.
|
|
* - PACK decides nothing, so it should leave __ok untouched. Whether it runs at all is
|
|
* already expressed by its execution condition.
|
|
*/
|
|
}
|
|
}
|