Formatted includes/services/xeger

This commit is contained in:
Aaron Po
2026-07-19 04:10:32 -04:00
parent fad1611685
commit eb32a55831

View File

@@ -55,33 +55,33 @@ struct Alternation;
struct Repeat; struct Repeat;
struct Visitor { struct Visitor {
virtual void Visit(const Literal&) = 0; virtual void Visit(const Literal&) = 0;
virtual void Visit(const AnyChar&) = 0; virtual void Visit(const AnyChar&) = 0;
virtual void Visit(const CharClass&) = 0; virtual void Visit(const CharClass&) = 0;
virtual void Visit(const Concat&) = 0; virtual void Visit(const Concat&) = 0;
virtual void Visit(const Alternation&) = 0; virtual void Visit(const Alternation&) = 0;
virtual void Visit(const Repeat&) = 0; virtual void Visit(const Repeat&) = 0;
virtual ~Visitor() = default; virtual ~Visitor() = default;
}; };
struct Node { struct Node {
virtual void Accept(Visitor&) const = 0; virtual void Accept(Visitor&) const = 0;
virtual ~Node() = default; virtual ~Node() = default;
}; };
using NodePtr = std::unique_ptr<Node>; using NodePtr = std::unique_ptr<Node>;
template <typename Derived> template <typename Derived>
struct Visitable : Node { struct Visitable : Node {
void Accept(Visitor& visitor) const override { void Accept(Visitor& visitor) const override {
visitor.Visit(static_cast<const Derived&>(*this)); visitor.Visit(static_cast<const Derived&>(*this));
} }
}; };
// One fixed character, e.g. 'a'. // One fixed character, e.g. 'a'.
struct Literal : Visitable<Literal> { struct Literal : Visitable<Literal> {
char ch; char ch;
explicit Literal(const char c) : ch(c) {} explicit Literal(const char c) : ch(c) {}
}; };
// The "." wildcard: any single printable character. // The "." wildcard: any single printable character.
@@ -91,18 +91,18 @@ struct AnyChar : Visitable<AnyChar> {};
// character 'x' is the range {'x', 'x'}. `negated` flips the meaning to // character 'x' is the range {'x', 'x'}. `negated` flips the meaning to
// "any character NOT listed" (i.e. `[^...]`). // "any character NOT listed" (i.e. `[^...]`).
struct CharClass : Visitable<CharClass> { struct CharClass : Visitable<CharClass> {
std::vector<std::pair<char, char>> ranges; std::vector<std::pair<char, char>> ranges;
bool negated = false; bool negated = false;
}; };
// "Do these children one after another." // "Do these children one after another."
struct Concat : Visitable<Concat> { struct Concat : Visitable<Concat> {
std::vector<NodePtr> parts; std::vector<NodePtr> parts;
}; };
// "Pick exactly one of these options at random" -- the `|` operator. // "Pick exactly one of these options at random" -- the `|` operator.
struct Alternation : Visitable<Alternation> { struct Alternation : Visitable<Alternation> {
std::vector<NodePtr> options; std::vector<NodePtr> options;
}; };
// "Repeat one child between min and max times." // "Repeat one child between min and max times."
@@ -111,9 +111,9 @@ struct Alternation : Visitable<Alternation> {
// a? -> min 0, max 1 // a? -> min 0, max 1
// a{2,5} -> min 2, max 5 // a{2,5} -> min 2, max 5
struct Repeat : Visitable<Repeat> { struct Repeat : Visitable<Repeat> {
NodePtr child; NodePtr child;
unsigned int min = 0; unsigned int min = 0;
std::optional<unsigned int> max; // std::nullopt means "no upper bound" std::optional<unsigned int> max; // std::nullopt means "no upper bound"
}; };
// Parser (recursive descent) // Parser (recursive descent)
@@ -125,75 +125,75 @@ struct Repeat : Visitable<Repeat> {
// ParseAtom ::= a . [..] (..) \d // ParseAtom ::= a . [..] (..) \d
class Parser { class Parser {
public: public:
explicit Parser(std::string_view pattern); explicit Parser(std::string_view pattern);
NodePtr Parse(); NodePtr Parse();
private: private:
std::string src_; std::string src_;
size_t pos_ = 0; size_t pos_ = 0;
// Strips anchors (leading '^' and trailing '$') as they are not needed for // Strips anchors (leading '^' and trailing '$') as they are not needed for
// generation. // generation.
static std::string StripAnchors(std::string_view pattern); static std::string StripAnchors(std::string_view pattern);
[[nodiscard]] bool AtEnd() const; [[nodiscard]] bool AtEnd() const;
[[nodiscard]] char Peek() const; [[nodiscard]] char Peek() const;
char Advance(); char Advance();
bool Match(char c); bool Match(char c);
void Expect(char c); void Expect(char c);
// Level 1: alternation -- ( concat | concat | concat ) // Level 1: alternation -- ( concat | concat | concat )
NodePtr ParseAlternation(); NodePtr ParseAlternation();
// Level 2: concatenation -- a run of items back to back // Level 2: concatenation -- a run of items back to back
NodePtr ParseConcat(); NodePtr ParseConcat();
// Level 3: an atom plus an optional quantifier // Level 3: an atom plus an optional quantifier
NodePtr ParseRepeat(); NodePtr ParseRepeat();
// Curly-brace quantifiers: {n}, {n,}, {n,m} // Curly-brace quantifiers: {n}, {n,}, {n,m}
NodePtr ParseBrace(NodePtr atom); NodePtr ParseBrace(NodePtr atom);
// Level 4: an atom -- the smallest standalone unit // Level 4: an atom -- the smallest standalone unit
NodePtr ParseAtom(); NodePtr ParseAtom();
static NodePtr MakeClass(std::vector<std::pair<char, char>> ranges, static NodePtr MakeClass(std::vector<std::pair<char, char>> ranges,
bool negated); bool negated);
NodePtr ParseEscape(); NodePtr ParseEscape();
NodePtr ParseCharClass(); NodePtr ParseCharClass();
// Reads one character inside [ ], turning \] \n etc. into the real // Reads one character inside [ ], turning \] \n etc. into the real
// character they represent. // character they represent.
char ClassChar(); char ClassChar();
}; };
// Generator -- a Visitor that emits a random matching string // Generator -- a Visitor that emits a random matching string
class XegerGenerator final : public Visitor { class XegerGenerator final : public Visitor {
public: public:
XegerGenerator(std::mt19937& rng, int unbounded_cap); XegerGenerator(std::mt19937& rng, int unbounded_cap);
std::string Run(const Node& root); std::string Run(const Node& root);
void Visit(const Literal& node) override; void Visit(const Literal& node) override;
void Visit(const AnyChar&) override; void Visit(const AnyChar&) override;
void Visit(const CharClass& node) override; void Visit(const CharClass& node) override;
void Visit(const Concat& node) override; void Visit(const Concat& node) override;
void Visit(const Alternation& node) override; void Visit(const Alternation& node) override;
void Visit(const Repeat& node) override; void Visit(const Repeat& node) override;
private: private:
std::mt19937& rng_; std::mt19937& rng_;
int unbounded_cap_; int unbounded_cap_;
std::string out_; std::string out_;
static bool InRanges(const CharClass& node, char c); static bool InRanges(const CharClass& node, char c);
char PickFromClass(const CharClass& node); char PickFromClass(const CharClass& node);
}; };
} // namespace xeger_internal } // namespace xeger_internal