mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-10-15 01:54:43 +00:00
Formatted includes/services/xeger
This commit is contained in:
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user