moonbitstack/moonregex/parse does not have a README file

    Refused

    pub(all) suberror Refused {
    Pattern(msg~ : String, at~ : Int, line~ : Int, column~ : Int)
    Exceeded(limit~ : Int, got~ : Int)
    Ambiguous(groups~ : Int)
    Accept(start~ : Int, end~ : Int)
    Commit
    Prune
    Skip(target~ : Int)
    } derive(Eq,
    Debug
    )

    Why a pattern, or a run of one, was refused.

    The word is deliberate: a pattern is input, and this library is fed patterns it did not write. Refusals say what was wrong and where; the step ceiling says how far the run got before giving up.
    impl Show for Refused

    Refused::equal

    fn Refused::equal(Refused, Refused) -> Bool

    Refused::not_equal

    fn Refused::not_equal(x : Refused, y : Refused) -> Bool

    Refused::output

    fn Refused::output(self : Refused, logger : &Logger) -> Unit

    Refused::to_repr

    Refused::to_string

    fn Refused::to_string(self : Refused) -> String

    Anchor

    pub enum Anchor {
    StartLine(multiline~ : Bool)
    EndLine(multiline~ : Bool, before_final_newline~ : Bool)
    TextStart
    TextEnd
    WordBoundary(negate~ : Bool, ascii~ : Bool)
    WordStart
    WordEnd
    SearchAnchor
    } derive(Eq,
    Debug
    )

    An assertion: something true of a position rather than of the text in it.

    Every dialect difference about anchors is settled here at parse time — ^ under m is a different node from ^ without it, and Python's $ (which also matches before a trailing newline) from ECMA-262's (which does not) — so the executor reads one meaning per node.

    Anchor::equal

    fn Anchor::equal(Anchor, Anchor) -> Bool

    Anchor::not_equal

    fn Anchor::not_equal(x : Anchor, y : Anchor) -> Bool

    Anchor::to_repr

    Ast

    pub struct Ast {
    root : Node
    groups : Int
    groupindex : Map[String, Array[Int]]
    named_lists : Map[String, Array[String]]
    flags : Flags
    }

    A parsed pattern: the tree, and what the parse learned about it.

    flags is the compile-time flags with the pattern's own global inline flags merged in — what Pattern::flags answers.

    Ast::built

    fn Ast::built(root : Node, groups~ : Int, groupindex~ : Map[String, Array[Int]], flags~ : Flags) -> Ast

    An Ast assembled from parts rather than parsed, so patterns can be composed in code and still be the same kind of value as a parsed one.

    Ast::dump

    fn Ast::dump(self : Ast) -> String

    The syntax tree as text: what Pattern::dump answers.

    Not the pattern — a parse and re-print loses spacing and comments, and folds flags into the nodes — but close enough to read a pattern back from, which is what tests and debugging want.

    Ast::flags

    fn Ast::flags(self : Ast) -> Flags

    The effective flags.

    Ast::groupindex

    fn Ast::groupindex(self : Ast) -> Map[String, Array[Int]]

    Group name to the slots carrying it.

    Ast::groups

    fn Ast::groups(self : Ast) -> Int

    How many capture groups the pattern has.

    Ast::named_lists

    fn Ast::named_lists(self : Ast) -> Map[String, Array[String]]

    The named lists the pattern declared with \L<name>.

    Ast::root

    fn Ast::root(self : Ast) -> Node

    The tree on its own, for the executor.

    Ast::to_lexmatch

    fn Ast::to_lexmatch(self : Ast) -> String?

    The tree as a lexmatch pattern — what the core library's engine reads.

    None when the tree uses something that grammar cannot say, which is the line between the two engines: everything above it can be handed to the core library, everything below has to run here.

    Cond

    pub enum Cond {
    ByGroup(slot~ : Int)
    ByLook(node~ : Node, look~ : Look)
    ByRecurse(target~ : RecurseCond)
    } derive(Eq,
    Debug
    )

    What a conditional tests.

    Cond::equal

    fn Cond::equal(Cond, Cond) -> Bool

    Cond::not_equal

    fn Cond::not_equal(x : Cond, y : Cond) -> Bool

    Cond::to_repr

    Dialect

    pub(all) enum Dialect {
    Python
    Ecma262
    Lexmatch
    } derive(Eq,
    Debug
    )

    Which grammar a pattern is written in.

    The interface is the same whichever is chosen; the grammar is a parameter because the callers need different ones. JSON Schema's pattern and OpenAPI's pattern are defined as ECMA-262 §22.2 and are unforgiving about it, while everyone else writes Python's.
    impl Show for Dialect

    Dialect::equal

    fn Dialect::equal(Dialect, Dialect) -> Bool

    Dialect::not_equal

    fn Dialect::not_equal(x : Dialect, y : Dialect) -> Bool

    Dialect::output

    fn Dialect::output(self : Dialect, logger : &Logger) -> Unit

    Dialect::to_repr

    Dialect::to_string

    fn Dialect::to_string(self : Dialect) -> String

    Flags

    pub(all) struct Flags {
    ignorecase : Bool
    multiline : Bool
    dotall : Bool
    verbose : Bool
    ascii : Bool
    unicode : Bool
    unicode_sets : Bool
    fullcase : Bool
    bestmatch : Bool
    enhancematch : Bool
    posix : Bool
    reverse : Bool
    word : Bool
    version : Version
    } derive(Eq,
    Debug
    )

    The switches a pattern can carry.

    A record rather than a bitmask, because every one of these is a thing a reader may want to look at, set, or refuse — (?a) inside a scoped group changes what \w means for that group alone, and a bitmask cannot be asked about politely.

    Flags are resolved into the syntax tree at parse time: (?s:.) puts the dotall behaviour inside the node, so the executor never consults them.

    Flags::equal

    fn Flags::equal(Flags, Flags) -> Bool

    Flags::new

    fn Flags::new(ignorecase? : Bool, multiline? : Bool, dotall? : Bool, verbose? : Bool, ascii? : Bool, unicode? : Bool, unicode_sets? : Bool, fullcase? : Bool, bestmatch? : Bool, enhancematch? : Bool, posix? : Bool, reverse? : Bool, word? : Bool, version? : Version) -> Flags

    Build flags, leaving unset switches at their preset.

    A flag that is only meaningful in one dialect is accepted everywhere and refused by the parser when the grammar cannot honour it — verbose under ECMA-262, for instance — so that the mistake is named where it happens.

    Flags::not_equal

    fn Flags::not_equal(x : Flags, y : Flags) -> Bool

    Flags::to_repr

    FuzzySpec

    pub struct FuzzySpec {
    insertions : Int?
    deletions : Int?
    substitutions : Int?
    errors : Int?
    cost : (Int, Int, Int)?
    } derive(Eq,
    Debug
    )

    How much fuzz a fuzzy quantifier allows.

    mrab-regex writes these as {e<=1}, {i<=2,d<=1}, {2i+1d+1s<=3}: a budget over insertions, deletions and substitutions, either counted or weighed. The representation is settled here before any of it executes, so the executor grows one interpreter for fuzzy nodes rather than a fuzzy branch in every path.

    FuzzySpec::equal

    fn FuzzySpec::equal(FuzzySpec, FuzzySpec) -> Bool

    FuzzySpec::not_equal

    fn FuzzySpec::not_equal(x : FuzzySpec, y : FuzzySpec) -> Bool

    Look

    pub enum Look {
    Ahead(positive~ : Bool)
    Behind(positive~ : Bool)
    } derive(Eq,
    Debug
    )

    Which way a lookaround looks, and whether it wants to find something.

    Look::equal

    fn Look::equal(Look, Look) -> Bool

    Look::not_equal

    fn Look::not_equal(x : Look, y : Look) -> Bool

    Look::to_repr

    Node

    pub enum Node {
    Empty
    Char(code~ : Int)
    Any(dotall~ : Bool)
    Class(set~ :
    CharSet
    )
    Seq(items~ : Array[Node])
    Alt(items~ : Array[Node])
    Repeat(node~ : Node, min~ : Int, max~ : Int?, greedy~ : Bool)
    Group(slot~ : Int, node~ : Node)
    Atomic(node~ : Node)
    Lookaround(node~ : Node, look~ : Look)
    Backref(slot~ : Int, icase~ : Bool)
    Cond(probe~ : Cond, yes~ : Node, no~ : Node?)
    Anchor(anchor~ : Anchor)
    Keep
    Grapheme
    Fuzzy(spec~ : FuzzySpec, node~ : Node)
    Define(node~ : Node)
    Recurse(target~ : Recurse)
    Verb(kind~ : VerbKind)
    } derive(Eq,
    Debug
    )

    One node of the syntax tree every dialect is lowered into.

    The tree is resolved: flags have been folded into the nodes that care ((?s:.) is an Any that eats newlines, (?i)k is a class holding both cases), so the executor never asks which grammar a node came from.

    Node::equal

    fn Node::equal(Node, Node) -> Bool

    Node::not_equal

    fn Node::not_equal(x : Node, y : Node) -> Bool

    Node::shift_slots

    fn Node::shift_slots(self : Node, by : Int) -> Node

    The tree with every capture slot moved up by by.

    Composing two patterns renumbers the right-hand one's groups so the result is numbered as one written pattern would be — the left operand keeps 1..n, the right one continues at n+1.

    Node::to_repr

    Recurse

    pub enum Recurse {
    Whole
    Group(slot~ : Int)
    Named(name~ : String)
    } derive(Eq,
    Debug
    )

    What a recursion calls back into.

    Recurse::equal

    fn Recurse::equal(Recurse, Recurse) -> Bool

    Recurse::not_equal

    fn Recurse::not_equal(x : Recurse, y : Recurse) -> Bool

    Recurse::to_repr

    RecurseCond

    pub enum RecurseCond {
    AnyRecursion
    GroupRecursion(slot~ : Int)
    NamedRecursion(name~ : String)
    } derive(Eq,
    Debug
    )

    The target of a recursion condition (?(R)…).

    RecurseCond::equal

    fn RecurseCond::equal(RecurseCond, RecurseCond) -> Bool

    RecurseCond::not_equal

    fn RecurseCond::not_equal(x : RecurseCond, y : RecurseCond) -> Bool

    VerbKind

    pub enum VerbKind {
    Accept
    Fail
    Commit
    Mark(name~ : String)
    Prune(name~ : String?)
    Skip(name~ : String?)
    Then(name~ : String?)
    LimitMatch(n~ : Int)
    LimitRecursion(n~ : Int)
    Version
    Fence
    } derive(Eq,
    Debug
    )

    A control verb from the regex superset: (*ACCEPT), (*FAIL), and the rest. Accept ends the whole match at the current position; Fail forces the current match attempt to fail; Mark records a name; Prune and Skip carry the position past a failure so the scan does not retry it.

    VerbKind::equal

    fn VerbKind::equal(VerbKind, VerbKind) -> Bool

    VerbKind::not_equal

    fn VerbKind::not_equal(x : VerbKind, y : VerbKind) -> Bool

    VerbKind::to_repr

    Version

    pub(all) enum Version {
    V0
    V1
    } derive(Eq,
    Debug
    )

    Which regex-module behaviour set a Python pattern is read under.

    V0 is re as everyone writes it; V1 opens the set algebra (--, &&, ~~, nested sets) and the rest of what (?V1) unlocks. Only the Python dialect has versions — ECMA-262 gates the same algebra behind its v flag.

    Version::equal

    fn Version::equal(Version, Version) -> Bool

    Version::not_equal

    fn Version::not_equal(x : Version, y : Version) -> Bool

    Version::to_repr

    captured

    fn captured(a : Ast, name~ : String) -> Ast raise Refused

    a.capture(name) — one more group, numbered after the ones already there.

    concat

    fn concat(a : Ast, b : Ast) -> Ast

    One after the other: a + b.

    dialect

    let dialect : Dialect

    The dialect a pattern is read under when the caller does not say.

    ecma_parse

    fn ecma_parse(pattern : StringView) -> Ast raise Refused

    Parse pattern as an ECMA-262 RegExp — the grammar JSON Schema and OpenAPI mean by a "string" pattern, and what a browser hands new RegExp.

    The tree is the same one Python's re reads into; only the dialect differs, so the executor never asks which grammar a node came from.

    ecma_parse_with

    fn ecma_parse_with(pattern : StringView, flags : Flags) -> Ast raise Refused

    Parse an ECMA-262 RegExp with the flags already chosen by the caller.

    either

    fn either(a : Ast, b : Ast) -> Ast

    One or the other: a | b.

    flags

    let flags : Flags

    Everything off, unicode on, version V0.

    This is the preset every default argument points at, so a pattern written with no flags at all behaves the way Python's re does by default.

    lexmatch_parse

    fn lexmatch_parse(pattern : StringView) -> Ast raise Refused

    Parse pattern as a MoonBit lexmatch literal — the grammar MoonBit's own @string.Regex speaks, the lexer uses, and lexmatch documents.

    lexmatch_parse_with

    fn lexmatch_parse_with(pattern : StringView, flags : Flags) -> Ast raise Refused

    Parse a lexmatch literal with the flags already chosen by the caller.

    literal

    fn literal(text : StringView) -> Ast

    An Ast matching exactly text, character for character.

    parse

    fn parse(pattern : StringView, flags? : Flags, dialect? : Dialect, lists? : Map[String, Array[String]]) -> Ast raise Refused

    Read a pattern into the syntax tree.

    flags are the compile-time flags; the pattern's own global inline flags are merged into them as they are met, and the merged result is what Ast::flags answers.

    repeated

    fn repeated(a : Ast, min~ : Int, max? : Int, greedy~ : Bool) -> Ast raise Refused

    a.repeat(…).

    Powered by MoonBit

    Site sourceReport issueModulesSkillsBuild queueStatistics

    © 2026 mooncakes.io