#ifndef TOML11_SYNTAX_FWD_HPP #define TOML11_SYNTAX_FWD_HPP #include "../scanner.hpp" #include "../spec.hpp" #include "../version.hpp" namespace toml { inline namespace TOML11_INLINE_VERSION_NAMESPACE { namespace detail { namespace syntax { using char_type = location::char_type; // =========================================================================== // UTF-8 // avoid redundant representation and out-of-unicode sequence character_in_range const& utf8_1byte (const spec&); sequence const& utf8_2bytes(const spec&); sequence const& utf8_3bytes(const spec&); sequence const& utf8_4bytes(const spec&); class non_ascii final : public scanner_base { public: using char_type = location::char_type; public: explicit non_ascii(const spec& s) noexcept : utf8_2B_(utf8_2bytes(s)), utf8_3B_(utf8_3bytes(s)), utf8_4B_(utf8_4bytes(s)) {} ~non_ascii() override = default; region scan(location& loc) const override { { const auto reg = utf8_2B_.scan(loc); if(reg.is_ok()) {return reg;} } { const auto reg = utf8_3B_.scan(loc); if(reg.is_ok()) {return reg;} } { const auto reg = utf8_4B_.scan(loc); if(reg.is_ok()) {return reg;} } return region{}; } std::string expected_chars(location&) const override { return "non-ascii utf-8 bytes"; } scanner_base* clone() const override { return new non_ascii(*this); } std::string name() const override { return "non_ascii"; } private: sequence utf8_2B_; sequence utf8_3B_; sequence utf8_4B_; }; // =========================================================================== // Whitespace character_either const& wschar(const spec&); repeat_at_least const& ws(const spec& s); // =========================================================================== // Newline either const& newline(const spec&); // =========================================================================== // Comments either const& allowed_comment_char(const spec& s); // XXX Note that it does not take newline sequence const& comment(const spec& s); // =========================================================================== // Boolean either const& boolean(const spec&); // =========================================================================== // Integer class digit final : public scanner_base { public: using char_type = location::char_type; public: explicit digit(const spec&) noexcept : scanner_(char_type('0'), char_type('9')) {} ~digit() override = default; region scan(location& loc) const override { return scanner_.scan(loc); } std::string expected_chars(location&) const override { return "digit [0-9]"; } scanner_base* clone() const override { return new digit(*this); } std::string name() const override { return "digit"; } private: character_in_range scanner_; }; class alpha final : public scanner_base { public: using char_type = location::char_type; public: explicit alpha(const spec&) noexcept : lowercase_(char_type('a'), char_type('z')), uppercase_(char_type('A'), char_type('Z')) {} ~alpha() override = default; region scan(location& loc) const override { { const auto reg = lowercase_.scan(loc); if(reg.is_ok()) {return reg;} } { const auto reg = uppercase_.scan(loc); if(reg.is_ok()) {return reg;} } return region{}; } std::string expected_chars(location&) const override { return "alpha [a-zA-Z]"; } scanner_base* clone() const override { return new alpha(*this); } std::string name() const override { return "alpha"; } private: character_in_range lowercase_; character_in_range uppercase_; }; class hexdig final : public scanner_base { public: using char_type = location::char_type; public: explicit hexdig(const spec& s) noexcept : digit_(s), lowercase_(char_type('a'), char_type('f')), uppercase_(char_type('A'), char_type('F')) {} ~hexdig() override = default; region scan(location& loc) const override { { const auto reg = digit_.scan(loc); if(reg.is_ok()) {return reg;} } { const auto reg = lowercase_.scan(loc); if(reg.is_ok()) {return reg;} } { const auto reg = uppercase_.scan(loc); if(reg.is_ok()) {return reg;} } return region{}; } std::string expected_chars(location&) const override { return "hex [0-9a-fA-F]"; } scanner_base* clone() const override { return new hexdig(*this); } std::string name() const override { return "hexdig"; } private: digit digit_; character_in_range lowercase_; character_in_range uppercase_; }; sequence const& num_suffix(const spec& s); sequence const& dec_int(const spec& s); sequence const& hex_int(const spec& s); sequence const& oct_int(const spec&); sequence const& bin_int(const spec&); either const& integer(const spec& s); // =========================================================================== // Floating sequence const& zero_prefixable_int(const spec& s); sequence const& fractional_part(const spec& s); sequence const& exponent_part(const spec& s); sequence const& hex_floating(const spec& s); either const& floating(const spec& s); // =========================================================================== // Datetime sequence const& local_date(const spec& s); sequence const& local_time(const spec& s); either const& time_offset(const spec& s); sequence const& full_time(const spec& s); character_either const& time_delim(const spec&); sequence const& local_datetime(const spec& s); sequence const& offset_datetime(const spec& s); // =========================================================================== // String sequence const& escaped_x2(const spec& s); sequence const& escaped_u4(const spec& s); sequence const& escaped_U8(const spec& s); sequence const& escaped (const spec& s); either const& basic_char (const spec& s); sequence const& basic_string(const spec& s); // --------------------------------------------------------------------------- // multiline string sequence const& escaped_newline(const spec& s); sequence const& ml_basic_string(const spec& s); // --------------------------------------------------------------------------- // literal string either const& literal_char(const spec& s); sequence const& literal_string(const spec& s); sequence const& ml_literal_string(const spec& s); either const& string(const spec& s); // =========================================================================== // Keys // to keep `expected_chars` simple class non_ascii_key_char final : public scanner_base { public: using char_type = location::char_type; private: using in_range = character_in_range; // make definition short public: explicit non_ascii_key_char(const spec& s) noexcept; ~non_ascii_key_char() override = default; region scan(location& loc) const override; std::string expected_chars(location&) const override { return "bare key non-ASCII script"; } scanner_base* clone() const override { return new non_ascii_key_char(*this); } std::string name() const override { return "non-ASCII bare key"; } private: std::uint32_t read_utf8(location& loc) const; }; repeat_at_least const& unquoted_key(const spec& s); either const& quoted_key(const spec& s); either const& simple_key(const spec& s); sequence const& dot_sep(const spec& s); sequence const& dotted_key(const spec& s); class key final : public scanner_base { public: using char_type = location::char_type; public: explicit key(const spec& s) noexcept : dotted_(dotted_key(s)), simple_(simple_key(s)) {} ~key() override = default; region scan(location& loc) const override { { const auto reg = dotted_.scan(loc); if(reg.is_ok()) {return reg;} } { const auto reg = simple_.scan(loc); if(reg.is_ok()) {return reg;} } return region{}; } std::string expected_chars(location&) const override { return "basic key([a-zA-Z0-9_-]) or quoted key(\" or ')"; } scanner_base* clone() const override { return new key(*this); } std::string name() const override { return "key"; } private: sequence dotted_; either simple_; }; sequence const& keyval_sep(const spec& s); // =========================================================================== // Table key sequence const& std_table(const spec& s); sequence const& array_table(const spec& s); // =========================================================================== // extension: null literal const& null_value(const spec&); } // namespace syntax } // namespace detail } // TOML11_INLINE_VERSION_NAMESPACE } // namespace toml #endif // TOML11_SYNTAX_FWD_HPP