#pragma once #include "abnf/code_point.h" #include #include #include #include #include #include #include #include namespace abnf { struct rule { rule() = default; rule(rule_part part); rule(rule_part_like auto && part); rule(std::initializer_list rules); friend bool operator==(rule const & lhs, rule const & rhs); std::vector rules; }; struct literal { explicit literal(std::string_view lit); friend bool operator==(literal const &, literal const &) = default; std::string value; }; struct reference { explicit reference(std::string_view ref); friend bool operator==(reference const &, reference const &) = default; std::string value; }; struct char_range { char_range() = default; char_range(int val) : first(val), last(val) {} char_range(int first, int last) : first(first), last(last) {} friend bool operator==(char_range const &, char_range const &) = default; code_point first; code_point last; }; struct repeated { friend bool operator==(repeated const &, repeated const &) = default; rule rule; size_t min = 0; size_t max = std::numeric_limits::max(); }; struct one_of { explicit one_of(rule_part part) : rules{part} {} one_of(std::initializer_list rules) : rules(rules) {} one_of(std::initializer_list rules) : rules(rules.begin(), rules.end()) {} friend bool operator==(one_of const &, one_of const &) = default; std::vector rules; }; inline bool operator==(rule const & lhs, rule const & rhs) { return lhs.rules == rhs.rules; } class grammar { public: using rule_store = std::map; private: struct satisfies_result; public: grammar(std::string_view name, rule base_rule, rule_store rules = {}) : name_(name), base_rule_(std::move(base_rule)), rules_(std::move(rules)) {} bool satisfies(std::string_view text) const; private: grammar() = default; satisfies_result satisfies(std::string_view & text, rule const & rule) const; satisfies_result satisfies(std::string_view text, auto const & lit) const; friend bool operator==(grammar const &, grammar const &) = default; private: friend std::ostream & operator<<(std::ostream &, grammar const &); friend grammar parse(std::istream &); std::string name_; rule base_rule_; // TODO: Default Rules of ABNF static rule_store const s_default_rules_; rule_store rules_; }; rule::rule(rule_part_like auto && part) : rule(rule_part(std::forward(part))) {} }