PEGTL 2.x->3.x
This commit is contained in:
parent
d5faac7614
commit
dcab2833b8
|
@ -37,13 +37,13 @@ std::string NODE::typeString() const
|
|||
{
|
||||
std::stringstream os;
|
||||
|
||||
if( is<MARKUP::subscript>() ) os << "SUBSCRIPT";
|
||||
else if( is<MARKUP::superscript>() ) os << "SUPERSCRIPT";
|
||||
else if( is<MARKUP::anyString>() ) os << "ANYSTRING";
|
||||
else if( is<MARKUP::anyStringWithinBraces>() ) os << "ANYSTRINGWITHINBRACES";
|
||||
else if( is<MARKUP::varNamespaceName>() ) os << "VARNAMESPACENAME";
|
||||
else if( is<MARKUP::varName>() ) os << "VARNAME";
|
||||
else os << "other";
|
||||
if( is_type<MARKUP::subscript>() ) os << "SUBSCRIPT";
|
||||
else if( is_type<MARKUP::superscript>() ) os << "SUPERSCRIPT";
|
||||
else if( is_type<MARKUP::anyString>() ) os << "ANYSTRING";
|
||||
else if( is_type<MARKUP::anyStringWithinBraces>() ) os << "ANYSTRINGWITHINBRACES";
|
||||
else if( is_type<MARKUP::varNamespaceName>() ) os << "VARNAMESPACENAME";
|
||||
else if( is_type<MARKUP::varName>() ) os << "VARNAME";
|
||||
else os << "other";
|
||||
|
||||
return os.str();
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ std::string NODE::asString() const
|
|||
{
|
||||
std::stringstream os;
|
||||
|
||||
os << name(); // << "{" << typeString() << "}";
|
||||
os << type;
|
||||
|
||||
if( has_content() )
|
||||
os << " \"" << string() << "\"";
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define MARKUP_PARSER_H
|
||||
|
||||
#include <pegtl.hpp>
|
||||
#include <pegtl/contrib/parse_tree.hpp>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <utf8.h>
|
||||
|
@ -41,9 +42,9 @@ struct NODE : parse_tree::basic_node<NODE>
|
|||
|
||||
std::string typeString() const;
|
||||
|
||||
bool isOverbar() const { return is<MARKUP::overbar>(); }
|
||||
bool isSubscript() const { return is<MARKUP::subscript>(); }
|
||||
bool isSuperscript() const { return is<MARKUP::superscript>(); }
|
||||
bool isOverbar() const { return is_type<MARKUP::overbar>(); }
|
||||
bool isSubscript() const { return is_type<MARKUP::subscript>(); }
|
||||
bool isSuperscript() const { return is_type<MARKUP::superscript>(); }
|
||||
};
|
||||
|
||||
struct varPrefix : string<'$', '{'> {};
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2007-2020 Dr. Colin Hirsch and Daniel Frey
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -0,0 +1,23 @@
|
|||
Boost Software License - Version 1.0 - August 17th, 2003
|
||||
|
||||
Permission is hereby granted, free of charge, to any person or organization
|
||||
obtaining a copy of the software and accompanying documentation covered by
|
||||
this license (the "Software") to use, reproduce, display, distribute,
|
||||
execute, and transmit the Software, and to prepare derivative works of the
|
||||
Software, and to permit third-parties to whom the Software is furnished to
|
||||
do so, all subject to the following:
|
||||
|
||||
The copyright notices in the Software and this entire statement, including
|
||||
the above license grant, this restriction and the following disclaimer,
|
||||
must be included in all copies of the Software, in whole or in part, and
|
||||
all derivative works of the Software, unless such copies or derivative
|
||||
works are solely in the form of machine-executable object code generated by
|
||||
a source language processor.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,20 @@
|
|||
// Copyright (c) 2014-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_APPLY_MODE_HPP
|
||||
#define TAO_PEGTL_APPLY_MODE_HPP
|
||||
|
||||
#include "config.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
enum class apply_mode : bool
|
||||
{
|
||||
action = true,
|
||||
nothing = false
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,50 @@
|
|||
// Copyright (c) 2017-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_ARGV_INPUT_HPP
|
||||
#define TAO_PEGTL_ARGV_INPUT_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "config.hpp"
|
||||
#include "eol.hpp"
|
||||
#include "memory_input.hpp"
|
||||
#include "tracking_mode.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
[[nodiscard]] inline std::string make_argv_source( const std::size_t argn )
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "argv[" << argn << ']';
|
||||
return std::move( oss ).str();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template< tracking_mode P = tracking_mode::eager, typename Eol = eol::lf_crlf >
|
||||
struct argv_input
|
||||
: memory_input< P, Eol >
|
||||
{
|
||||
template< typename T >
|
||||
argv_input( char** argv, const std::size_t argn, T&& in_source )
|
||||
: memory_input< P, Eol >( static_cast< const char* >( argv[ argn ] ), std::forward< T >( in_source ) )
|
||||
{}
|
||||
|
||||
argv_input( char** argv, const std::size_t argn )
|
||||
: argv_input( argv, argn, internal::make_argv_source( argn ) )
|
||||
{}
|
||||
};
|
||||
|
||||
template< typename... Ts >
|
||||
argv_input( Ts&&... ) -> argv_input<>;
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,55 @@
|
|||
// Copyright (c) 2014-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_ASCII_HPP
|
||||
#define TAO_PEGTL_ASCII_HPP
|
||||
|
||||
#include "config.hpp"
|
||||
|
||||
#include "internal/result_on_found.hpp"
|
||||
#include "internal/rules.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
inline namespace ascii
|
||||
{
|
||||
// clang-format off
|
||||
struct alnum : internal::ranges< internal::peek_char, 'a', 'z', 'A', 'Z', '0', '9' > {};
|
||||
struct alpha : internal::ranges< internal::peek_char, 'a', 'z', 'A', 'Z' > {};
|
||||
struct any : internal::any< internal::peek_char > {};
|
||||
struct blank : internal::one< internal::result_on_found::success, internal::peek_char, ' ', '\t' > {};
|
||||
struct digit : internal::range< internal::result_on_found::success, internal::peek_char, '0', '9' > {};
|
||||
struct ellipsis : internal::string< '.', '.', '.' > {};
|
||||
template< char... Cs > struct forty_two : internal::rep< 42, internal::one< internal::result_on_found::success, internal::peek_char, Cs... > > {};
|
||||
struct identifier_first : internal::identifier_first {};
|
||||
struct identifier_other : internal::identifier_other {};
|
||||
struct identifier : internal::identifier {};
|
||||
template< char... Cs > struct istring : internal::istring< Cs... > {};
|
||||
template< char... Cs > struct keyword : internal::seq< internal::string< Cs... >, internal::not_at< internal::identifier_other > > { static_assert( sizeof...( Cs ) > 0 ); };
|
||||
struct lower : internal::range< internal::result_on_found::success, internal::peek_char, 'a', 'z' > {};
|
||||
template< char... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_char, Cs... > {};
|
||||
template< char Lo, char Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_char, Lo, Hi > {};
|
||||
struct nul : internal::one< internal::result_on_found::success, internal::peek_char, char( 0 ) > {};
|
||||
struct odigit : internal::range< internal::result_on_found::success, internal::peek_char, '0', '7' > {};
|
||||
template< char... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_char, Cs... > {};
|
||||
struct print : internal::range< internal::result_on_found::success, internal::peek_char, char( 32 ), char( 126 ) > {};
|
||||
template< char Lo, char Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_char, Lo, Hi > {};
|
||||
template< char... Cs > struct ranges : internal::ranges< internal::peek_char, Cs... > {};
|
||||
struct seven : internal::range< internal::result_on_found::success, internal::peek_char, char( 0 ), char( 127 ) > {};
|
||||
struct shebang : internal::seq< internal::string< '#', '!' >, internal::until< internal::eolf > > {};
|
||||
struct space : internal::one< internal::result_on_found::success, internal::peek_char, ' ', '\n', '\r', '\t', '\v', '\f' > {};
|
||||
template< char... Cs > struct string : internal::string< Cs... > {};
|
||||
template< char C > struct three : internal::string< C, C, C > {};
|
||||
template< char C > struct two : internal::string< C, C > {};
|
||||
struct upper : internal::range< internal::result_on_found::success, internal::peek_char, 'A', 'Z' > {};
|
||||
struct xdigit : internal::ranges< internal::peek_char, '0', '9', 'a', 'f', 'A', 'F' > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace ascii
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#include "internal/pegtl_string.hpp"
|
||||
|
||||
#endif
|
|
@ -0,0 +1,227 @@
|
|||
// Copyright (c) 2016-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_BUFFER_INPUT_HPP
|
||||
#define TAO_PEGTL_BUFFER_INPUT_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#if defined( __cpp_exceptions )
|
||||
#include <stdexcept>
|
||||
#else
|
||||
#include <cstdio>
|
||||
#include <exception>
|
||||
#endif
|
||||
|
||||
#include "config.hpp"
|
||||
#include "eol.hpp"
|
||||
#include "memory_input.hpp"
|
||||
#include "position.hpp"
|
||||
#include "tracking_mode.hpp"
|
||||
|
||||
#include "internal/action_input.hpp"
|
||||
#include "internal/bump.hpp"
|
||||
#include "internal/iterator.hpp"
|
||||
#include "internal/marker.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
template< typename Reader, typename Eol = eol::lf_crlf, typename Source = std::string, std::size_t Chunk = 64 >
|
||||
class buffer_input
|
||||
{
|
||||
public:
|
||||
using reader_t = Reader;
|
||||
|
||||
using eol_t = Eol;
|
||||
using source_t = Source;
|
||||
|
||||
using iterator_t = internal::iterator;
|
||||
|
||||
using action_t = internal::action_input< buffer_input >;
|
||||
|
||||
static constexpr std::size_t chunk_size = Chunk;
|
||||
static constexpr tracking_mode tracking_mode_v = tracking_mode::eager;
|
||||
|
||||
template< typename T, typename... As >
|
||||
buffer_input( T&& in_source, const std::size_t maximum, As&&... as )
|
||||
: m_reader( std::forward< As >( as )... ),
|
||||
m_maximum( maximum + Chunk ),
|
||||
m_buffer( new char[ maximum + Chunk ] ),
|
||||
m_current( m_buffer.get() ),
|
||||
m_end( m_buffer.get() ),
|
||||
m_source( std::forward< T >( in_source ) )
|
||||
{
|
||||
static_assert( Chunk, "zero chunk size not implemented" );
|
||||
assert( m_maximum > maximum ); // Catches overflow; change to >= when zero chunk size is implemented.
|
||||
}
|
||||
|
||||
buffer_input( const buffer_input& ) = delete;
|
||||
buffer_input( buffer_input&& ) = delete;
|
||||
|
||||
~buffer_input() = default;
|
||||
|
||||
buffer_input& operator=( const buffer_input& ) = delete;
|
||||
buffer_input& operator=( buffer_input&& ) = delete;
|
||||
|
||||
[[nodiscard]] bool empty()
|
||||
{
|
||||
require( 1 );
|
||||
return m_current.data == m_end;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::size_t size( const std::size_t amount )
|
||||
{
|
||||
require( amount );
|
||||
return buffer_occupied();
|
||||
}
|
||||
|
||||
[[nodiscard]] const char* current() const noexcept
|
||||
{
|
||||
return m_current.data;
|
||||
}
|
||||
|
||||
[[nodiscard]] const char* end( const std::size_t amount )
|
||||
{
|
||||
require( amount );
|
||||
return m_end;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::size_t byte() const noexcept
|
||||
{
|
||||
return m_current.byte;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::size_t line() const noexcept
|
||||
{
|
||||
return m_current.line;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::size_t column() const noexcept
|
||||
{
|
||||
return m_current.column;
|
||||
}
|
||||
|
||||
[[nodiscard]] const Source& source() const noexcept
|
||||
{
|
||||
return m_source;
|
||||
}
|
||||
|
||||
[[nodiscard]] char peek_char( const std::size_t offset = 0 ) const noexcept
|
||||
{
|
||||
return m_current.data[ offset ];
|
||||
}
|
||||
|
||||
[[nodiscard]] std::uint8_t peek_uint8( const std::size_t offset = 0 ) const noexcept
|
||||
{
|
||||
return static_cast< std::uint8_t >( peek_char( offset ) );
|
||||
}
|
||||
|
||||
void bump( const std::size_t in_count = 1 ) noexcept
|
||||
{
|
||||
internal::bump( m_current, in_count, Eol::ch );
|
||||
}
|
||||
|
||||
void bump_in_this_line( const std::size_t in_count = 1 ) noexcept
|
||||
{
|
||||
internal::bump_in_this_line( m_current, in_count );
|
||||
}
|
||||
|
||||
void bump_to_next_line( const std::size_t in_count = 1 ) noexcept
|
||||
{
|
||||
internal::bump_to_next_line( m_current, in_count );
|
||||
}
|
||||
|
||||
void discard() noexcept
|
||||
{
|
||||
if( m_current.data > m_buffer.get() + Chunk ) {
|
||||
const auto s = m_end - m_current.data;
|
||||
std::memmove( m_buffer.get(), m_current.data, s );
|
||||
m_current.data = m_buffer.get();
|
||||
m_end = m_buffer.get() + s;
|
||||
}
|
||||
}
|
||||
|
||||
void require( const std::size_t amount )
|
||||
{
|
||||
if( m_current.data + amount <= m_end ) {
|
||||
return;
|
||||
}
|
||||
if( m_current.data + amount > m_buffer.get() + m_maximum ) {
|
||||
#if defined( __cpp_exceptions )
|
||||
throw std::overflow_error( "require() beyond end of buffer" );
|
||||
#else
|
||||
std::fputs( "overflow error: require() beyond end of buffer\n", stderr );
|
||||
std::terminate();
|
||||
#endif
|
||||
}
|
||||
if( const auto r = m_reader( m_end, ( std::min )( buffer_free_after_end(), ( std::max )( amount - buffer_occupied(), Chunk ) ) ) ) {
|
||||
m_end += r;
|
||||
}
|
||||
}
|
||||
|
||||
template< rewind_mode M >
|
||||
[[nodiscard]] internal::marker< iterator_t, M > mark() noexcept
|
||||
{
|
||||
return internal::marker< iterator_t, M >( m_current );
|
||||
}
|
||||
|
||||
[[nodiscard]] TAO_PEGTL_NAMESPACE::position position( const iterator_t& it ) const
|
||||
{
|
||||
return TAO_PEGTL_NAMESPACE::position( it, m_source );
|
||||
}
|
||||
|
||||
[[nodiscard]] TAO_PEGTL_NAMESPACE::position position() const
|
||||
{
|
||||
return position( m_current );
|
||||
}
|
||||
|
||||
[[nodiscard]] const iterator_t& iterator() const noexcept
|
||||
{
|
||||
return m_current;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::size_t buffer_capacity() const noexcept
|
||||
{
|
||||
return m_maximum;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::size_t buffer_occupied() const noexcept
|
||||
{
|
||||
assert( m_end >= m_current.data );
|
||||
return std::size_t( m_end - m_current.data );
|
||||
}
|
||||
|
||||
[[nodiscard]] std::size_t buffer_free_before_current() const noexcept
|
||||
{
|
||||
assert( m_current.data >= m_buffer.get() );
|
||||
return std::size_t( m_current.data - m_buffer.get() );
|
||||
}
|
||||
|
||||
[[nodiscard]] std::size_t buffer_free_after_end() const noexcept
|
||||
{
|
||||
assert( m_buffer.get() + m_maximum >= m_end );
|
||||
return std::size_t( m_buffer.get() + m_maximum - m_end );
|
||||
}
|
||||
|
||||
private:
|
||||
Reader m_reader;
|
||||
std::size_t m_maximum;
|
||||
std::unique_ptr< char[] > m_buffer;
|
||||
iterator_t m_current;
|
||||
char* m_end;
|
||||
const Source m_source;
|
||||
|
||||
public:
|
||||
std::size_t private_depth = 0;
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright (c) 2019-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CHANGE_ACTION_HPP
|
||||
#define TAO_PEGTL_CHANGE_ACTION_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "apply_mode.hpp"
|
||||
#include "config.hpp"
|
||||
#include "nothing.hpp"
|
||||
#include "rewind_mode.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
template< template< typename... > class NewAction >
|
||||
struct change_action
|
||||
: maybe_nothing
|
||||
{
|
||||
template< typename Rule,
|
||||
apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, States&&... st )
|
||||
{
|
||||
static_assert( !std::is_same_v< Action< void >, NewAction< void > >, "old and new action class templates are identical" );
|
||||
return Control< Rule >::template match< A, M, NewAction, Control >( in, st... );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,72 @@
|
|||
// Copyright (c) 2019-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CHANGE_ACTION_AND_STATE_HPP
|
||||
#define TAO_PEGTL_CHANGE_ACTION_AND_STATE_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "apply_mode.hpp"
|
||||
#include "config.hpp"
|
||||
#include "match.hpp"
|
||||
#include "nothing.hpp"
|
||||
#include "rewind_mode.hpp"
|
||||
|
||||
#include "internal/dependent_false.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
template< template< typename... > class NewAction, typename NewState >
|
||||
struct change_action_and_state
|
||||
: maybe_nothing
|
||||
{
|
||||
template< typename Rule,
|
||||
apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, States&&... st )
|
||||
{
|
||||
static_assert( !std::is_same_v< Action< void >, NewAction< void > >, "old and new action class templates are identical" );
|
||||
|
||||
if constexpr( std::is_constructible_v< NewState, const ParseInput&, States... > ) {
|
||||
NewState s( static_cast< const ParseInput& >( in ), st... );
|
||||
if( Control< Rule >::template match< A, M, NewAction, Control >( in, s ) ) {
|
||||
if constexpr( A == apply_mode::action ) {
|
||||
Action< Rule >::success( static_cast< const ParseInput& >( in ), s, st... );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if constexpr( std::is_default_constructible_v< NewState > ) {
|
||||
NewState s;
|
||||
if( Control< Rule >::template match< A, M, NewAction, Control >( in, s ) ) {
|
||||
if constexpr( A == apply_mode::action ) {
|
||||
Action< Rule >::success( static_cast< const ParseInput& >( in ), s, st... );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
static_assert( internal::dependent_false< NewState >, "unable to instantiate new state" );
|
||||
}
|
||||
}
|
||||
|
||||
template< typename ParseInput,
|
||||
typename... States >
|
||||
static void success( const ParseInput& in, NewState& s, States&&... st ) noexcept( noexcept( s.success( in, st... ) ) )
|
||||
{
|
||||
s.success( in, st... );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,63 @@
|
|||
// Copyright (c) 2019-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CHANGE_ACTION_AND_STATES_HPP
|
||||
#define TAO_PEGTL_CHANGE_ACTION_AND_STATES_HPP
|
||||
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include "apply_mode.hpp"
|
||||
#include "config.hpp"
|
||||
#include "match.hpp"
|
||||
#include "nothing.hpp"
|
||||
#include "rewind_mode.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
template< template< typename... > class NewAction, typename... NewStates >
|
||||
struct change_action_and_states
|
||||
: maybe_nothing
|
||||
{
|
||||
template< typename Rule,
|
||||
apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
std::size_t... Ns,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( std::index_sequence< Ns... > /*unused*/, ParseInput& in, States&&... st )
|
||||
{
|
||||
auto t = std::tie( st... );
|
||||
if( Control< Rule >::template match< A, M, NewAction, Control >( in, std::get< Ns >( t )... ) ) {
|
||||
if constexpr( A == apply_mode::action ) {
|
||||
Action< Rule >::success( static_cast< const ParseInput& >( in ), st... );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template< typename Rule,
|
||||
apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, States&&... st )
|
||||
{
|
||||
static_assert( !std::is_same_v< Action< void >, NewAction< void > >, "old and new action class templates are identical" );
|
||||
return match< Rule, A, M, Action, Control >( std::index_sequence_for< NewStates... >(), in, NewStates()..., st... );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright (c) 2019-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CHANGE_CONTROL_HPP
|
||||
#define TAO_PEGTL_CHANGE_CONTROL_HPP
|
||||
|
||||
#include "apply_mode.hpp"
|
||||
#include "config.hpp"
|
||||
#include "match.hpp"
|
||||
#include "nothing.hpp"
|
||||
#include "rewind_mode.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
template< template< typename... > class NewControl >
|
||||
struct change_control
|
||||
: maybe_nothing
|
||||
{
|
||||
template< typename Rule,
|
||||
apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, States&&... st )
|
||||
{
|
||||
return TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, NewControl >( in, st... );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,70 @@
|
|||
// Copyright (c) 2019-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CHANGE_STATE_HPP
|
||||
#define TAO_PEGTL_CHANGE_STATE_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "apply_mode.hpp"
|
||||
#include "config.hpp"
|
||||
#include "match.hpp"
|
||||
#include "nothing.hpp"
|
||||
#include "rewind_mode.hpp"
|
||||
|
||||
#include "internal/dependent_false.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
template< typename NewState >
|
||||
struct change_state
|
||||
: maybe_nothing
|
||||
{
|
||||
template< typename Rule,
|
||||
apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, States&&... st )
|
||||
{
|
||||
if constexpr( std::is_constructible_v< NewState, const ParseInput&, States... > ) {
|
||||
NewState s( static_cast< const ParseInput& >( in ), st... );
|
||||
if( TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, s ) ) {
|
||||
if constexpr( A == apply_mode::action ) {
|
||||
Action< Rule >::success( static_cast< const ParseInput& >( in ), s, st... );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if constexpr( std::is_default_constructible_v< NewState > ) {
|
||||
NewState s;
|
||||
if( TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, s ) ) {
|
||||
if constexpr( A == apply_mode::action ) {
|
||||
Action< Rule >::success( static_cast< const ParseInput& >( in ), s, st... );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
static_assert( internal::dependent_false< NewState >, "unable to instantiate new state" );
|
||||
}
|
||||
}
|
||||
|
||||
template< typename ParseInput,
|
||||
typename... States >
|
||||
static void success( const ParseInput& in, NewState& s, States&&... st ) noexcept( noexcept( s.success( in, st... ) ) )
|
||||
{
|
||||
s.success( in, st... );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,62 @@
|
|||
// Copyright (c) 2019-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CHANGE_STATES_HPP
|
||||
#define TAO_PEGTL_CHANGE_STATES_HPP
|
||||
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include "apply_mode.hpp"
|
||||
#include "config.hpp"
|
||||
#include "match.hpp"
|
||||
#include "nothing.hpp"
|
||||
#include "rewind_mode.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
template< typename... NewStates >
|
||||
struct change_states
|
||||
: maybe_nothing
|
||||
{
|
||||
template< typename Rule,
|
||||
apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
std::size_t... Ns,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( std::index_sequence< Ns... > /*unused*/, ParseInput& in, States&&... st )
|
||||
{
|
||||
auto t = std::tie( st... );
|
||||
if( TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, std::get< Ns >( t )... ) ) {
|
||||
if constexpr( A == apply_mode::action ) {
|
||||
Action< Rule >::success( static_cast< const ParseInput& >( in ), st... );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template< typename Rule,
|
||||
apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, States&&... st )
|
||||
{
|
||||
return match< Rule, A, M, Action, Control >( std::index_sequence_for< NewStates... >(), in, NewStates()..., st... );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright (c) 2017-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONFIG_HPP
|
||||
#define TAO_PEGTL_CONFIG_HPP
|
||||
|
||||
#if defined( TAO_PEGTL_NAMESPACE )
|
||||
#pragma message( "TAO_PEGTL_NAMESPACE is deprecated" )
|
||||
#else
|
||||
#define TAO_PEGTL_NAMESPACE tao::pegtl
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) 2014-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_ABNF_HPP
|
||||
#define TAO_PEGTL_CONTRIB_ABNF_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "../internal/rules.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::abnf
|
||||
{
|
||||
// Core ABNF rules according to RFC 5234, Appendix B
|
||||
|
||||
// clang-format off
|
||||
struct ALPHA : internal::ranges< internal::peek_char, 'a', 'z', 'A', 'Z' > {};
|
||||
struct BIT : internal::one< internal::result_on_found::success, internal::peek_char, '0', '1' > {};
|
||||
struct CHAR : internal::range< internal::result_on_found::success, internal::peek_char, char( 1 ), char( 127 ) > {};
|
||||
struct CR : internal::one< internal::result_on_found::success, internal::peek_char, '\r' > {};
|
||||
struct CRLF : internal::string< '\r', '\n' > {};
|
||||
struct CTL : internal::ranges< internal::peek_char, char( 0 ), char( 31 ), char( 127 ) > {};
|
||||
struct DIGIT : internal::range< internal::result_on_found::success, internal::peek_char, '0', '9' > {};
|
||||
struct DQUOTE : internal::one< internal::result_on_found::success, internal::peek_char, '"' > {};
|
||||
struct HEXDIG : internal::ranges< internal::peek_char, '0', '9', 'a', 'f', 'A', 'F' > {};
|
||||
struct HTAB : internal::one< internal::result_on_found::success, internal::peek_char, '\t' > {};
|
||||
struct LF : internal::one< internal::result_on_found::success, internal::peek_char, '\n' > {};
|
||||
struct LWSP : internal::star< internal::sor< internal::string< '\r', '\n' >, internal::one< internal::result_on_found::success, internal::peek_char, ' ', '\t' > >, internal::one< internal::result_on_found::success, internal::peek_char, ' ', '\t' > > {};
|
||||
struct OCTET : internal::any< internal::peek_char > {};
|
||||
struct SP : internal::one< internal::result_on_found::success, internal::peek_char, ' ' > {};
|
||||
struct VCHAR : internal::range< internal::result_on_found::success, internal::peek_char, char( 33 ), char( 126 ) > {};
|
||||
struct WSP : internal::one< internal::result_on_found::success, internal::peek_char, ' ', '\t' > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::abnf
|
||||
|
||||
#endif
|
|
@ -0,0 +1,70 @@
|
|||
// Copyright (c) 2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_ADD_STATE_HPP
|
||||
#define TAO_PEGTL_CONTRIB_ADD_STATE_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "../apply_mode.hpp"
|
||||
#include "../config.hpp"
|
||||
#include "../match.hpp"
|
||||
#include "../nothing.hpp"
|
||||
#include "../rewind_mode.hpp"
|
||||
|
||||
#include "../internal/dependent_false.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
template< typename AddState >
|
||||
struct add_state
|
||||
: maybe_nothing
|
||||
{
|
||||
template< typename Rule,
|
||||
apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, States&&... st )
|
||||
{
|
||||
if constexpr( std::is_constructible_v< AddState, const ParseInput&, States... > ) {
|
||||
AddState s( static_cast< const ParseInput& >( in ), st... );
|
||||
if( TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, s, st... ) ) {
|
||||
if constexpr( A == apply_mode::action ) {
|
||||
Action< Rule >::success( static_cast< const ParseInput& >( in ), s, st... );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if constexpr( std::is_default_constructible_v< AddState > ) {
|
||||
AddState s;
|
||||
if( TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, s, st... ) ) {
|
||||
if constexpr( A == apply_mode::action ) {
|
||||
Action< Rule >::success( static_cast< const ParseInput& >( in ), s, st... );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
static_assert( internal::dependent_false< AddState >, "unable to instantiate new state" );
|
||||
}
|
||||
}
|
||||
|
||||
template< typename ParseInput,
|
||||
typename... States >
|
||||
static void success( const ParseInput& in, AddState& s, States&&... st ) noexcept( noexcept( s.success( in, st... ) ) )
|
||||
{
|
||||
s.success( in, st... );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,68 @@
|
|||
// Copyright (c) 2015-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_ALPHABET_HPP
|
||||
#define TAO_PEGTL_CONTRIB_ALPHABET_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::alphabet
|
||||
{
|
||||
static const char a = 'a';
|
||||
static const char b = 'b';
|
||||
static const char c = 'c';
|
||||
static const char d = 'd';
|
||||
static const char e = 'e';
|
||||
static const char f = 'f';
|
||||
static const char g = 'g';
|
||||
static const char h = 'h';
|
||||
static const char i = 'i';
|
||||
static const char j = 'j';
|
||||
static const char k = 'k';
|
||||
static const char l = 'l';
|
||||
static const char m = 'm';
|
||||
static const char n = 'n';
|
||||
static const char o = 'o';
|
||||
static const char p = 'p';
|
||||
static const char q = 'q';
|
||||
static const char r = 'r';
|
||||
static const char s = 's';
|
||||
static const char t = 't';
|
||||
static const char u = 'u';
|
||||
static const char v = 'v';
|
||||
static const char w = 'w';
|
||||
static const char x = 'x';
|
||||
static const char y = 'y';
|
||||
static const char z = 'z';
|
||||
|
||||
static const char A = 'A'; // NOLINT(readability-identifier-naming)
|
||||
static const char B = 'B'; // NOLINT(readability-identifier-naming)
|
||||
static const char C = 'C'; // NOLINT(readability-identifier-naming)
|
||||
static const char D = 'D'; // NOLINT(readability-identifier-naming)
|
||||
static const char E = 'E'; // NOLINT(readability-identifier-naming)
|
||||
static const char F = 'F'; // NOLINT(readability-identifier-naming)
|
||||
static const char G = 'G'; // NOLINT(readability-identifier-naming)
|
||||
static const char H = 'H'; // NOLINT(readability-identifier-naming)
|
||||
static const char I = 'I'; // NOLINT(readability-identifier-naming)
|
||||
static const char J = 'J'; // NOLINT(readability-identifier-naming)
|
||||
static const char K = 'K'; // NOLINT(readability-identifier-naming)
|
||||
static const char L = 'L'; // NOLINT(readability-identifier-naming)
|
||||
static const char M = 'M'; // NOLINT(readability-identifier-naming)
|
||||
static const char N = 'N'; // NOLINT(readability-identifier-naming)
|
||||
static const char O = 'O'; // NOLINT(readability-identifier-naming)
|
||||
static const char P = 'P'; // NOLINT(readability-identifier-naming)
|
||||
static const char Q = 'Q'; // NOLINT(readability-identifier-naming)
|
||||
static const char R = 'R'; // NOLINT(readability-identifier-naming)
|
||||
static const char S = 'S'; // NOLINT(readability-identifier-naming)
|
||||
static const char T = 'T'; // NOLINT(readability-identifier-naming)
|
||||
static const char U = 'U'; // NOLINT(readability-identifier-naming)
|
||||
static const char V = 'V'; // NOLINT(readability-identifier-naming)
|
||||
static const char W = 'W'; // NOLINT(readability-identifier-naming)
|
||||
static const char X = 'X'; // NOLINT(readability-identifier-naming)
|
||||
static const char Y = 'Y'; // NOLINT(readability-identifier-naming)
|
||||
static const char Z = 'Z'; // NOLINT(readability-identifier-naming)
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::alphabet
|
||||
|
||||
#endif
|
|
@ -0,0 +1,190 @@
|
|||
// Copyright (c) 2020-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_ANALYZE_HPP
|
||||
#define TAO_PEGTL_CONTRIB_ANALYZE_HPP
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <stdexcept>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "../demangle.hpp"
|
||||
|
||||
#include "analyze_traits.hpp"
|
||||
|
||||
#include "internal/set_stack_guard.hpp"
|
||||
#include "internal/vector_stack_guard.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
struct analyze_entry
|
||||
{
|
||||
explicit analyze_entry( const analyze_type in_type ) noexcept
|
||||
: type( in_type )
|
||||
{}
|
||||
|
||||
const analyze_type type;
|
||||
std::vector< std::string_view > subs;
|
||||
};
|
||||
|
||||
class analyze_cycles_impl
|
||||
{
|
||||
public:
|
||||
analyze_cycles_impl( analyze_cycles_impl&& ) = delete;
|
||||
analyze_cycles_impl( const analyze_cycles_impl& ) = delete;
|
||||
|
||||
~analyze_cycles_impl() = default;
|
||||
|
||||
analyze_cycles_impl& operator=( analyze_cycles_impl&& ) = delete;
|
||||
analyze_cycles_impl& operator=( const analyze_cycles_impl& ) = delete;
|
||||
|
||||
[[nodiscard]] std::size_t problems()
|
||||
{
|
||||
for( auto& i : m_entries ) {
|
||||
assert( m_trace.empty() );
|
||||
assert( m_stack.empty() );
|
||||
m_results[ i.first ] = work( i, false );
|
||||
}
|
||||
// The number of problems returned is not very informative as some problems will be found multiple times.
|
||||
return m_problems;
|
||||
}
|
||||
|
||||
template< typename Rule >
|
||||
[[nodiscard]] bool consumes() const
|
||||
{
|
||||
// The name "consumes" is a shortcut for "the analyze cycles algorithm could prove that this rule always consumes when it succeeds".
|
||||
return m_results.at( demangle< Rule >() );
|
||||
}
|
||||
|
||||
protected:
|
||||
explicit analyze_cycles_impl( const int verbose ) noexcept
|
||||
: m_verbose( verbose ),
|
||||
m_problems( 0 )
|
||||
{}
|
||||
|
||||
[[nodiscard]] const std::pair< const std::string_view, analyze_entry >& find( const std::string_view name ) const noexcept
|
||||
{
|
||||
const auto iter = m_entries.find( name );
|
||||
assert( iter != m_entries.end() );
|
||||
return *iter;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool work( const std::pair< const std::string_view, analyze_entry >& entry, const bool accum )
|
||||
{
|
||||
if( const auto g = set_stack_guard( m_stack, entry.first ) ) {
|
||||
const auto v = vector_stack_guard( m_trace, entry.first );
|
||||
switch( entry.second.type ) {
|
||||
case analyze_type::any: {
|
||||
bool a = false;
|
||||
for( const auto& r : entry.second.subs ) {
|
||||
a = a || work( find( r ), accum || a );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case analyze_type::opt: {
|
||||
bool a = false;
|
||||
for( const auto& r : entry.second.subs ) {
|
||||
a = a || work( find( r ), accum || a );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case analyze_type::seq: {
|
||||
bool a = false;
|
||||
for( const auto& r : entry.second.subs ) {
|
||||
a = a || work( find( r ), accum || a );
|
||||
}
|
||||
return a;
|
||||
}
|
||||
case analyze_type::sor: {
|
||||
bool a = true;
|
||||
for( const auto& r : entry.second.subs ) {
|
||||
a = a && work( find( r ), accum );
|
||||
}
|
||||
return a;
|
||||
}
|
||||
}
|
||||
assert( false ); // LCOV_EXCL_LINE
|
||||
}
|
||||
assert( !m_trace.empty() );
|
||||
|
||||
if( !accum ) {
|
||||
++m_problems;
|
||||
// LCOV_EXCL_START
|
||||
if( ( m_verbose >= 0 ) && ( m_trace.front() == entry.first ) ) {
|
||||
for( const auto& r : m_trace ) {
|
||||
if( r < entry.first ) {
|
||||
return accum;
|
||||
}
|
||||
}
|
||||
std::cerr << "WARNING: Possible cycle without progress at rule " << entry.first << std::endl;
|
||||
if( m_verbose > 0 ) {
|
||||
for( const auto& r : m_trace ) {
|
||||
std::cerr << "- involved (transformed) rule: " << r << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
const int m_verbose;
|
||||
|
||||
std::size_t m_problems;
|
||||
|
||||
std::set< std::string_view > m_stack;
|
||||
std::vector< std::string_view > m_trace;
|
||||
std::map< std::string_view, bool > m_results;
|
||||
std::map< std::string_view, analyze_entry > m_entries;
|
||||
};
|
||||
|
||||
template< typename Name >
|
||||
std::string_view analyze_insert( std::map< std::string_view, analyze_entry >& entry )
|
||||
{
|
||||
using Traits = analyze_traits< Name, typename Name::rule_t >;
|
||||
|
||||
const auto [ i, b ] = entry.try_emplace( demangle< Name >(), Traits::type_v );
|
||||
if( b ) {
|
||||
analyze_insert_impl( typename Traits::subs_t(), i->second.subs, entry );
|
||||
}
|
||||
return i->first;
|
||||
}
|
||||
|
||||
template< typename... Subs >
|
||||
void analyze_insert_impl( type_list< Subs... > /*unused*/, std::vector< std::string_view >& subs, std::map< std::string_view, analyze_entry >& entry )
|
||||
{
|
||||
( subs.emplace_back( analyze_insert< Subs >( entry ) ), ... );
|
||||
}
|
||||
|
||||
template< typename Grammar >
|
||||
struct analyze_cycles
|
||||
: analyze_cycles_impl
|
||||
{
|
||||
explicit analyze_cycles( const int verbose )
|
||||
: analyze_cycles_impl( verbose )
|
||||
{
|
||||
analyze_insert< Grammar >( m_entries );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template< typename Grammar >
|
||||
[[nodiscard]] std::size_t analyze( const int verbose = 1 )
|
||||
{
|
||||
return internal::analyze_cycles< Grammar >( verbose ).problems();
|
||||
}
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,278 @@
|
|||
// Copyright (c) 2020-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_ANALYZE_TRAITS_HPP
|
||||
#define TAO_PEGTL_CONTRIB_ANALYZE_TRAITS_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "../ascii.hpp"
|
||||
#include "../config.hpp"
|
||||
#include "../rules.hpp"
|
||||
#include "../type_list.hpp"
|
||||
|
||||
#include "forward.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
enum class analyze_type
|
||||
{
|
||||
any, // Consumption-on-success is always true; assumes bounded repetition of conjunction of sub-rules.
|
||||
opt, // Consumption-on-success not necessarily true; assumes bounded repetition of conjunction of sub-rules.
|
||||
seq, // Consumption-on-success depends on consumption of (non-zero bounded repetition of) conjunction of sub-rules.
|
||||
sor // Consumption-on-success depends on consumption of (non-zero bounded repetition of) disjunction of sub-rules.
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template< typename... Rules >
|
||||
struct analyze_any_traits
|
||||
{
|
||||
static constexpr internal::analyze_type type_v = internal::analyze_type::any;
|
||||
using subs_t = type_list< Rules... >;
|
||||
};
|
||||
|
||||
template< typename... Rules >
|
||||
struct analyze_opt_traits
|
||||
{
|
||||
static constexpr internal::analyze_type type_v = internal::analyze_type::opt;
|
||||
using subs_t = type_list< Rules... >;
|
||||
};
|
||||
|
||||
template< typename... Rules >
|
||||
struct analyze_seq_traits
|
||||
{
|
||||
static constexpr internal::analyze_type type_v = internal::analyze_type::seq;
|
||||
using subs_t = type_list< Rules... >;
|
||||
};
|
||||
|
||||
template< typename... Rules >
|
||||
struct analyze_sor_traits
|
||||
{
|
||||
static constexpr internal::analyze_type type_v = internal::analyze_type::sor;
|
||||
using subs_t = type_list< Rules... >;
|
||||
};
|
||||
|
||||
template< typename Name, template< typename... > class Action, typename... Rules >
|
||||
struct analyze_traits< Name, internal::action< Action, Rules... > >
|
||||
: analyze_traits< Name, typename seq< Rules... >::rule_t >
|
||||
{};
|
||||
|
||||
template< typename Name, typename Peek >
|
||||
struct analyze_traits< Name, internal::any< Peek > >
|
||||
: analyze_any_traits<>
|
||||
{};
|
||||
|
||||
template< typename Name, typename... Actions >
|
||||
struct analyze_traits< Name, internal::apply< Actions... > >
|
||||
: analyze_opt_traits<>
|
||||
{};
|
||||
|
||||
template< typename Name, typename... Actions >
|
||||
struct analyze_traits< Name, internal::apply0< Actions... > >
|
||||
: analyze_opt_traits<>
|
||||
{};
|
||||
|
||||
template< typename Name, typename... Rules >
|
||||
struct analyze_traits< Name, internal::at< Rules... > >
|
||||
: analyze_traits< Name, typename opt< Rules... >::rule_t >
|
||||
{};
|
||||
|
||||
template< typename Name >
|
||||
struct analyze_traits< Name, internal::bof >
|
||||
: analyze_opt_traits<>
|
||||
{};
|
||||
|
||||
template< typename Name >
|
||||
struct analyze_traits< Name, internal::bol >
|
||||
: analyze_opt_traits<>
|
||||
{};
|
||||
|
||||
template< typename Name, unsigned Cnt >
|
||||
struct analyze_traits< Name, internal::bytes< Cnt > >
|
||||
: std::conditional_t< ( Cnt != 0 ), analyze_any_traits<>, analyze_opt_traits<> >
|
||||
{};
|
||||
|
||||
template< typename Name, template< typename... > class Control, typename... Rules >
|
||||
struct analyze_traits< Name, internal::control< Control, Rules... > >
|
||||
: analyze_traits< Name, typename seq< Rules... >::rule_t >
|
||||
{};
|
||||
|
||||
template< typename Name, typename... Rules >
|
||||
struct analyze_traits< Name, internal::disable< Rules... > >
|
||||
: analyze_traits< Name, typename seq< Rules... >::rule_t >
|
||||
{};
|
||||
|
||||
template< typename Name >
|
||||
struct analyze_traits< Name, internal::discard >
|
||||
: analyze_opt_traits<>
|
||||
{};
|
||||
|
||||
template< typename Name, typename... Rules >
|
||||
struct analyze_traits< Name, internal::enable< Rules... > >
|
||||
: analyze_traits< Name, typename seq< Rules... >::rule_t >
|
||||
{};
|
||||
|
||||
template< typename Name >
|
||||
struct analyze_traits< Name, internal::eof >
|
||||
: analyze_opt_traits<>
|
||||
{};
|
||||
|
||||
template< typename Name >
|
||||
struct analyze_traits< Name, internal::eol >
|
||||
: analyze_any_traits<>
|
||||
{};
|
||||
|
||||
template< typename Name >
|
||||
struct analyze_traits< Name, internal::eolf >
|
||||
: analyze_opt_traits<>
|
||||
{};
|
||||
|
||||
template< typename Name >
|
||||
struct analyze_traits< Name, internal::failure >
|
||||
: analyze_any_traits<>
|
||||
{};
|
||||
|
||||
template< typename Name, typename Rule, typename... Actions >
|
||||
struct analyze_traits< Name, internal::if_apply< Rule, Actions... > >
|
||||
: analyze_traits< Name, typename Rule::rule_t >
|
||||
{};
|
||||
|
||||
template< typename Name, typename Cond, typename Then, typename Else >
|
||||
struct analyze_traits< Name, internal::if_then_else< Cond, Then, Else > >
|
||||
: analyze_traits< Name, typename sor< seq< Cond, Then >, Else >::rule_t >
|
||||
{};
|
||||
|
||||
template< typename Name, char... Cs >
|
||||
struct analyze_traits< Name, internal::istring< Cs... > >
|
||||
: std::conditional_t< ( sizeof...( Cs ) != 0 ), analyze_any_traits<>, analyze_opt_traits<> >
|
||||
{};
|
||||
|
||||
template< typename Name, typename... Rules >
|
||||
struct analyze_traits< Name, internal::not_at< Rules... > >
|
||||
: analyze_traits< Name, typename opt< Rules... >::rule_t >
|
||||
{};
|
||||
|
||||
template< typename Name, internal::result_on_found R, typename Peek, typename Peek::data_t... Cs >
|
||||
struct analyze_traits< Name, internal::one< R, Peek, Cs... > >
|
||||
: analyze_any_traits<>
|
||||
{};
|
||||
|
||||
template< typename Name, typename Rule, typename... Rules >
|
||||
struct analyze_traits< Name, internal::opt< Rule, Rules... > >
|
||||
: analyze_opt_traits< Rule, Rules... >
|
||||
{};
|
||||
|
||||
template< typename Name, typename... Rules >
|
||||
struct analyze_traits< Name, internal::plus< Rules... > >
|
||||
: analyze_traits< Name, typename seq< Rules..., opt< Name > >::rule_t >
|
||||
{};
|
||||
|
||||
template< typename Name, internal::result_on_found R, typename Peek, typename Peek::data_t Lo, typename Peek::data_t Hi >
|
||||
struct analyze_traits< Name, internal::range< R, Peek, Lo, Hi > >
|
||||
: analyze_any_traits<>
|
||||
{};
|
||||
|
||||
template< typename Name, typename Peek, typename Peek::data_t... Cs >
|
||||
struct analyze_traits< Name, internal::ranges< Peek, Cs... > >
|
||||
: analyze_any_traits<>
|
||||
{};
|
||||
|
||||
template< typename Name, typename Head, typename... Rules >
|
||||
struct analyze_traits< Name, internal::rematch< Head, Rules... > >
|
||||
: analyze_traits< Name, typename sor< Head, sor< seq< Rules, any >... > >::rule_t > // TODO: Correct (enough)?
|
||||
{};
|
||||
|
||||
template< typename Name, unsigned Cnt, typename... Rules >
|
||||
struct analyze_traits< Name, internal::rep< Cnt, Rules... > >
|
||||
: analyze_traits< Name, std::conditional_t< ( Cnt != 0 ), typename seq< Rules... >::rule_t, typename opt< Rules... >::rule_t > >
|
||||
{};
|
||||
|
||||
template< typename Name, unsigned Min, unsigned Max, typename... Rules >
|
||||
struct analyze_traits< Name, internal::rep_min_max< Min, Max, Rules... > >
|
||||
: analyze_traits< Name, std::conditional_t< ( Min != 0 ), typename seq< Rules... >::rule_t, typename opt< Rules... >::rule_t > >
|
||||
{};
|
||||
|
||||
template< typename Name, unsigned Max, typename... Rules >
|
||||
struct analyze_traits< Name, internal::rep_opt< Max, Rules... > >
|
||||
: analyze_traits< Name, typename opt< Rules... >::rule_t >
|
||||
{};
|
||||
|
||||
template< typename Name, unsigned Amount >
|
||||
struct analyze_traits< Name, internal::require< Amount > >
|
||||
: analyze_opt_traits<>
|
||||
{};
|
||||
|
||||
template< typename Name, typename Rule, typename... Rules >
|
||||
struct analyze_traits< Name, internal::seq< Rule, Rules... > >
|
||||
: analyze_seq_traits< Rule, Rules... >
|
||||
{};
|
||||
|
||||
template< typename Name, typename Rule, typename... Rules >
|
||||
struct analyze_traits< Name, internal::sor< Rule, Rules... > >
|
||||
: analyze_sor_traits< Rule, Rules... >
|
||||
{};
|
||||
|
||||
template< typename Name, typename... Rules >
|
||||
struct analyze_traits< Name, internal::star< Rules... > >
|
||||
: analyze_traits< Name, typename opt< Rules..., Name >::rule_t >
|
||||
{};
|
||||
|
||||
template< typename Name, typename State, typename... Rules >
|
||||
struct analyze_traits< Name, internal::state< State, Rules... > >
|
||||
: analyze_traits< Name, typename seq< Rules... >::rule_t >
|
||||
{};
|
||||
|
||||
template< typename Name, char... Cs >
|
||||
struct analyze_traits< Name, internal::string< Cs... > >
|
||||
: std::conditional_t< ( sizeof...( Cs ) != 0 ), analyze_any_traits<>, analyze_opt_traits<> >
|
||||
{};
|
||||
|
||||
template< typename Name >
|
||||
struct analyze_traits< Name, internal::success >
|
||||
: analyze_opt_traits<>
|
||||
{};
|
||||
|
||||
template< typename Name, typename Cond >
|
||||
struct analyze_traits< Name, internal::until< Cond > >
|
||||
: analyze_traits< Name, typename Cond::rule_t >
|
||||
{};
|
||||
|
||||
template< typename Name, typename Cond, typename... Rules >
|
||||
struct analyze_traits< Name, internal::until< Cond, Rules... > >
|
||||
: analyze_traits< Name, typename seq< star< Rules... >, Cond >::rule_t >
|
||||
{};
|
||||
|
||||
#if defined( __cpp_exceptions )
|
||||
template< typename Name, typename Cond, typename... Rules >
|
||||
struct analyze_traits< Name, internal::if_must< true, Cond, Rules... > >
|
||||
: analyze_traits< Name, typename opt< Cond, Rules... >::rule_t >
|
||||
{};
|
||||
|
||||
template< typename Name, typename Cond, typename... Rules >
|
||||
struct analyze_traits< Name, internal::if_must< false, Cond, Rules... > >
|
||||
: analyze_traits< Name, typename seq< Cond, Rules... >::rule_t >
|
||||
{};
|
||||
|
||||
template< typename Name, typename... Rules >
|
||||
struct analyze_traits< Name, internal::must< Rules... > >
|
||||
: analyze_traits< Name, typename seq< Rules... >::rule_t >
|
||||
{};
|
||||
|
||||
template< typename Name, typename T >
|
||||
struct analyze_traits< Name, internal::raise< T > >
|
||||
: analyze_any_traits<>
|
||||
{};
|
||||
|
||||
template< typename Name, typename Exception, typename... Rules >
|
||||
struct analyze_traits< Name, internal::try_catch_type< Exception, Rules... > >
|
||||
: analyze_traits< Name, typename seq< Rules... >::rule_t >
|
||||
{};
|
||||
#endif
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,56 @@
|
|||
// Copyright (c) 2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_CHECK_BYTES_HPP
|
||||
#define TAO_PEGTL_CONTRIB_CHECK_BYTES_HPP
|
||||
|
||||
#include "../apply_mode.hpp"
|
||||
#include "../config.hpp"
|
||||
#include "../match.hpp"
|
||||
#include "../nothing.hpp"
|
||||
#include "../rewind_mode.hpp"
|
||||
|
||||
#if defined( __cpp_exceptions )
|
||||
#include "../parse_error.hpp"
|
||||
#else
|
||||
#include <cstdio>
|
||||
#include <exception>
|
||||
#endif
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
template< std::size_t Maximum >
|
||||
struct check_bytes
|
||||
: maybe_nothing
|
||||
{
|
||||
template< typename Rule,
|
||||
apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
static bool match( ParseInput& in, States&&... st )
|
||||
{
|
||||
const auto* start = in.current();
|
||||
if( TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, st... ) ) {
|
||||
if( std::size_t( in.current() - start ) > Maximum ) {
|
||||
#if defined( __cpp_exceptions )
|
||||
throw TAO_PEGTL_NAMESPACE::parse_error( "maximum allowed rule consumption exceeded", in );
|
||||
#else
|
||||
std::fputs( "maximum allowed rule consumption exceeded\n", stderr );
|
||||
std::terminate();
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,94 @@
|
|||
// Copyright (c) 2020-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_CONTROL_ACTION_HPP
|
||||
#define TAO_PEGTL_CONTRIB_CONTROL_ACTION_HPP
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "../match.hpp"
|
||||
#include "../nothing.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
template< typename, typename Rule, template< typename... > class Action, typename ParseInput, typename... States >
|
||||
inline constexpr bool action_has_unwind = false;
|
||||
|
||||
template< typename Rule, template< typename... > class Action, typename ParseInput, typename... States >
|
||||
inline constexpr bool action_has_unwind< decltype( (void)Action< Rule >::unwind( std::declval< const ParseInput& >(), std::declval< States&& >()... ) ), Rule, Action, ParseInput, States... > = true;
|
||||
|
||||
} // namespace internal
|
||||
|
||||
struct control_action
|
||||
: maybe_nothing
|
||||
{
|
||||
template< typename Rule,
|
||||
apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, States&&... st )
|
||||
{
|
||||
#if defined( __cpp_exceptions )
|
||||
if constexpr( internal::action_has_unwind< void, Rule, Action, ParseInput, States... > ) {
|
||||
try {
|
||||
return control_action::match_impl< Rule, A, M, Action, Control >( in, st... );
|
||||
}
|
||||
catch( ... ) {
|
||||
Action< Rule >::unwind( const_cast< const ParseInput& >( in ), st... );
|
||||
throw;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return control_action::match_impl< Rule, A, M, Action, Control >( in, st... );
|
||||
}
|
||||
#else
|
||||
return control_action::match_impl< Rule, A, M, Action, Control >( in, st... );
|
||||
#endif
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename... States >
|
||||
static void start( const ParseInput& /*unused*/, States&&... /*unused*/ ) noexcept
|
||||
{}
|
||||
|
||||
template< typename ParseInput, typename... States >
|
||||
static void success( const ParseInput& /*unused*/, States&&... /*unused*/ ) noexcept
|
||||
{}
|
||||
|
||||
template< typename ParseInput, typename... States >
|
||||
static void failure( const ParseInput& /*unused*/, States&&... /*unused*/ ) noexcept
|
||||
{}
|
||||
|
||||
private:
|
||||
template< typename Rule,
|
||||
apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match_impl( ParseInput& in, States&&... st )
|
||||
{
|
||||
Action< Rule >::start( const_cast< const ParseInput& >( in ), st... );
|
||||
if( TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, st... ) ) {
|
||||
Action< Rule >::success( const_cast< const ParseInput& >( in ), st... );
|
||||
return true;
|
||||
}
|
||||
Action< Rule >::failure( const_cast< const ParseInput& >( in ), st... );
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,152 @@
|
|||
// Copyright (c) 2020-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_COVERAGE_HPP
|
||||
#define TAO_PEGTL_CONTRIB_COVERAGE_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <map>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "state_control.hpp"
|
||||
|
||||
#include "../apply_mode.hpp"
|
||||
#include "../config.hpp"
|
||||
#include "../demangle.hpp"
|
||||
#include "../normal.hpp"
|
||||
#include "../nothing.hpp"
|
||||
#include "../parse.hpp"
|
||||
#include "../rewind_mode.hpp"
|
||||
#include "../type_list.hpp"
|
||||
#include "../visit.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
struct coverage_info
|
||||
{
|
||||
std::size_t start = 0;
|
||||
std::size_t success = 0;
|
||||
std::size_t failure = 0;
|
||||
std::size_t unwind = 0;
|
||||
std::size_t raise = 0;
|
||||
};
|
||||
|
||||
struct coverage_entry
|
||||
: coverage_info
|
||||
{
|
||||
std::map< std::string_view, coverage_info > branches;
|
||||
};
|
||||
|
||||
using coverage_result = std::map< std::string_view, coverage_entry >;
|
||||
|
||||
namespace internal
|
||||
{
|
||||
template< typename Rule >
|
||||
struct coverage_insert
|
||||
{
|
||||
static void visit( std::map< std::string_view, coverage_entry >& map )
|
||||
{
|
||||
visit_branches( map.try_emplace( demangle< Rule >() ).first->second.branches, typename Rule::subs_t() );
|
||||
}
|
||||
|
||||
template< typename... Ts >
|
||||
static void visit_branches( std::map< std::string_view, coverage_info >& branches, type_list< Ts... > /*unused*/ )
|
||||
{
|
||||
( branches.try_emplace( demangle< Ts >() ), ... );
|
||||
}
|
||||
};
|
||||
|
||||
struct coverage_state
|
||||
{
|
||||
template< typename Rule >
|
||||
static constexpr bool enable = true;
|
||||
|
||||
explicit coverage_state( coverage_result& in_result )
|
||||
: result( in_result )
|
||||
{}
|
||||
|
||||
coverage_result& result;
|
||||
std::vector< std::string_view > stack;
|
||||
|
||||
template< typename Rule, typename ParseInput, typename... States >
|
||||
void start( const ParseInput& /*unused*/, States&&... /*unused*/ )
|
||||
{
|
||||
const auto name = demangle< Rule >();
|
||||
++result.at( name ).start;
|
||||
if( !stack.empty() ) {
|
||||
++result.at( stack.back() ).branches.at( name ).start;
|
||||
}
|
||||
stack.push_back( name );
|
||||
}
|
||||
|
||||
template< typename Rule, typename ParseInput, typename... States >
|
||||
void success( const ParseInput& /*unused*/, States&&... /*unused*/ )
|
||||
{
|
||||
stack.pop_back();
|
||||
const auto name = demangle< Rule >();
|
||||
++result.at( name ).success;
|
||||
if( !stack.empty() ) {
|
||||
++result.at( stack.back() ).branches.at( name ).success;
|
||||
}
|
||||
}
|
||||
|
||||
template< typename Rule, typename ParseInput, typename... States >
|
||||
void failure( const ParseInput& /*unused*/, States&&... /*unused*/ )
|
||||
{
|
||||
stack.pop_back();
|
||||
const auto name = demangle< Rule >();
|
||||
++result.at( name ).failure;
|
||||
if( !stack.empty() ) {
|
||||
++result.at( stack.back() ).branches.at( name ).failure;
|
||||
}
|
||||
}
|
||||
|
||||
template< typename Rule, typename ParseInput, typename... States >
|
||||
void raise( const ParseInput& /*unused*/, States&&... /*unused*/ )
|
||||
{
|
||||
const auto name = demangle< Rule >();
|
||||
++result.at( name ).raise;
|
||||
if( !stack.empty() ) {
|
||||
++result.at( stack.back() ).branches.at( name ).raise;
|
||||
}
|
||||
}
|
||||
|
||||
template< typename Rule, typename ParseInput, typename... States >
|
||||
void unwind( const ParseInput& /*unused*/, States&&... /*unused*/ )
|
||||
{
|
||||
stack.pop_back();
|
||||
const auto name = demangle< Rule >();
|
||||
++result.at( name ).unwind;
|
||||
if( !stack.empty() ) {
|
||||
++result.at( stack.back() ).branches.at( name ).unwind;
|
||||
}
|
||||
}
|
||||
|
||||
template< typename Rule, typename ParseInput, typename... States >
|
||||
void apply( const ParseInput& /*unused*/, States&&... /*unused*/ ) noexcept
|
||||
{}
|
||||
|
||||
template< typename Rule, typename ParseInput, typename... States >
|
||||
void apply0( const ParseInput& /*unused*/, States&&... /*unused*/ ) noexcept
|
||||
{}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template< typename Rule,
|
||||
template< typename... > class Action = nothing,
|
||||
template< typename... > class Control = normal,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
bool coverage( ParseInput&& in, coverage_result& result, States&&... st )
|
||||
{
|
||||
internal::coverage_state state( result );
|
||||
visit< Rule, internal::coverage_insert >( state.result ); // Fill map with all sub-rules of the grammar.
|
||||
return parse< Rule, Action, state_control< Control >::template type >( in, st..., state );
|
||||
}
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (c) 2020-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_FORWARD_HPP
|
||||
#define TAO_PEGTL_CONTRIB_FORWARD_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
template< typename Name, typename Rule, typename = void >
|
||||
struct analyze_traits;
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,53 @@
|
|||
// Copyright (c) 2020-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_FUNCTION_HPP
|
||||
#define TAO_PEGTL_CONTRIB_FUNCTION_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
|
||||
#include "../apply_mode.hpp"
|
||||
#include "../rewind_mode.hpp"
|
||||
#include "../type_list.hpp"
|
||||
|
||||
#include "../internal/enable_control.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
template< typename F, F U >
|
||||
struct function;
|
||||
|
||||
template< typename ParseInput, typename... States, bool ( *U )( ParseInput&, States... ) >
|
||||
struct function< bool ( * )( ParseInput&, States... ), U >
|
||||
{
|
||||
using rule_t = function;
|
||||
using subs_t = empty_list;
|
||||
|
||||
template< apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control >
|
||||
[[nodiscard]] static bool match( ParseInput& in, States... st ) noexcept( noexcept( U( in, st... ) ) )
|
||||
{
|
||||
return U( in, st... );
|
||||
}
|
||||
};
|
||||
|
||||
template< typename F, F U >
|
||||
inline constexpr bool enable_control< function< F, U > > = false;
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template< auto F >
|
||||
struct function
|
||||
: internal::function< decltype( F ), F >
|
||||
{};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,278 @@
|
|||
// Copyright (c) 2014-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_HTTP_HPP
|
||||
#define TAO_PEGTL_CONTRIB_HTTP_HPP
|
||||
|
||||
#if !defined( __cpp_exceptions )
|
||||
#error "Exception support required for tao/pegtl/contrib/http.hpp"
|
||||
#else
|
||||
|
||||
#include "../ascii.hpp"
|
||||
#include "../config.hpp"
|
||||
#include "../nothing.hpp"
|
||||
#include "../rules.hpp"
|
||||
#include "../utf8.hpp"
|
||||
|
||||
#include "abnf.hpp"
|
||||
#include "forward.hpp"
|
||||
#include "remove_first_state.hpp"
|
||||
#include "uri.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::http
|
||||
{
|
||||
// HTTP 1.1 grammar according to RFC 7230.
|
||||
|
||||
// This grammar is a direct PEG translation of the original HTTP grammar.
|
||||
// It should be considered experimental -- in case of any issues, in particular
|
||||
// missing rules for attached actions, please contact the developers.
|
||||
|
||||
using OWS = star< abnf::WSP >; // optional whitespace
|
||||
using RWS = plus< abnf::WSP >; // required whitespace
|
||||
using BWS = OWS; // "bad" whitespace
|
||||
|
||||
using obs_text = not_range< 0x00, 0x7F >;
|
||||
using obs_fold = seq< abnf::CRLF, plus< abnf::WSP > >;
|
||||
|
||||
// clang-format off
|
||||
struct tchar : sor< abnf::ALPHA, abnf::DIGIT, one< '!', '#', '$', '%', '&', '\'', '*', '+', '-', '.', '^', '_', '`', '|', '~' > > {};
|
||||
struct token : plus< tchar > {};
|
||||
|
||||
struct field_name : token {};
|
||||
|
||||
struct field_vchar : sor< abnf::VCHAR, obs_text > {};
|
||||
struct field_content : list< field_vchar, plus< abnf::WSP > > {};
|
||||
struct field_value : star< sor< field_content, obs_fold > > {};
|
||||
|
||||
struct header_field : seq< field_name, one< ':' >, OWS, field_value, OWS > {};
|
||||
|
||||
struct method : token {};
|
||||
|
||||
struct absolute_path : plus< one< '/' >, uri::segment > {};
|
||||
|
||||
struct origin_form : seq< absolute_path, uri::opt_query > {};
|
||||
struct absolute_form : uri::absolute_URI {};
|
||||
struct authority_form : uri::authority {};
|
||||
struct asterisk_form : one< '*' > {};
|
||||
|
||||
struct request_target : sor< origin_form, absolute_form, authority_form, asterisk_form > {};
|
||||
|
||||
struct status_code : rep< 3, abnf::DIGIT > {};
|
||||
struct reason_phrase : star< sor< abnf::VCHAR, obs_text, abnf::WSP > > {};
|
||||
|
||||
struct HTTP_version : if_must< string< 'H', 'T', 'T', 'P', '/' >, abnf::DIGIT, one< '.' >, abnf::DIGIT > {};
|
||||
|
||||
struct request_line : if_must< method, abnf::SP, request_target, abnf::SP, HTTP_version, abnf::CRLF > {};
|
||||
struct status_line : if_must< HTTP_version, abnf::SP, status_code, abnf::SP, reason_phrase, abnf::CRLF > {};
|
||||
struct start_line : sor< status_line, request_line > {};
|
||||
|
||||
struct message_body : star< abnf::OCTET > {};
|
||||
struct HTTP_message : seq< start_line, star< header_field, abnf::CRLF >, abnf::CRLF, opt< message_body > > {};
|
||||
|
||||
struct Content_Length : plus< abnf::DIGIT > {};
|
||||
|
||||
struct uri_host : uri::host {};
|
||||
struct port : uri::port {};
|
||||
|
||||
struct Host : seq< uri_host, opt< one< ':' >, port > > {};
|
||||
|
||||
// PEG are different from CFGs! (this replaces ctext and qdtext)
|
||||
using text = sor< abnf::HTAB, range< 0x20, 0x7E >, obs_text >;
|
||||
|
||||
struct quoted_pair : if_must< one< '\\' >, sor< abnf::VCHAR, obs_text, abnf::WSP > > {};
|
||||
struct quoted_string : if_must< abnf::DQUOTE, until< abnf::DQUOTE, sor< quoted_pair, text > > > {};
|
||||
|
||||
struct transfer_parameter : seq< token, BWS, one< '=' >, BWS, sor< token, quoted_string > > {};
|
||||
struct transfer_extension : seq< token, star< OWS, one< ';' >, OWS, transfer_parameter > > {};
|
||||
struct transfer_coding : sor< istring< 'c', 'h', 'u', 'n', 'k', 'e', 'd' >,
|
||||
istring< 'c', 'o', 'm', 'p', 'r', 'e', 's', 's' >,
|
||||
istring< 'd', 'e', 'f', 'l', 'a', 't', 'e' >,
|
||||
istring< 'g', 'z', 'i', 'p' >,
|
||||
transfer_extension > {};
|
||||
|
||||
struct rank : sor< seq< one< '0' >, opt< one< '.' >, rep_opt< 3, abnf::DIGIT > > >,
|
||||
seq< one< '1' >, opt< one< '.' >, rep_opt< 3, one< '0' > > > > > {};
|
||||
|
||||
struct t_ranking : seq< OWS, one< ';' >, OWS, one< 'q', 'Q' >, one< '=' >, rank > {};
|
||||
struct t_codings : sor< istring< 't', 'r', 'a', 'i', 'l', 'e', 'r', 's' >, seq< transfer_coding, opt< t_ranking > > > {};
|
||||
|
||||
struct TE : opt< sor< one< ',' >, t_codings >, star< OWS, one< ',' >, opt< OWS, t_codings > > > {};
|
||||
|
||||
template< typename T >
|
||||
using make_comma_list = seq< star< one< ',' >, OWS >, T, star< OWS, one< ',' >, opt< OWS, T > > >;
|
||||
|
||||
struct connection_option : token {};
|
||||
struct Connection : make_comma_list< connection_option > {};
|
||||
|
||||
struct Trailer : make_comma_list< field_name > {};
|
||||
|
||||
struct Transfer_Encoding : make_comma_list< transfer_coding > {};
|
||||
|
||||
struct protocol_name : token {};
|
||||
struct protocol_version : token {};
|
||||
struct protocol : seq< protocol_name, opt< one< '/' >, protocol_version > > {};
|
||||
struct Upgrade : make_comma_list< protocol > {};
|
||||
|
||||
struct pseudonym : token {};
|
||||
|
||||
struct received_protocol : seq< opt< protocol_name, one< '/' > >, protocol_version > {};
|
||||
struct received_by : sor< seq< uri_host, opt< one< ':' >, port > >, pseudonym > {};
|
||||
|
||||
struct comment : if_must< one< '(' >, until< one< ')' >, sor< comment, quoted_pair, text > > > {};
|
||||
|
||||
struct Via : make_comma_list< seq< received_protocol, RWS, received_by, opt< RWS, comment > > > {};
|
||||
|
||||
struct http_URI : if_must< istring< 'h', 't', 't', 'p', ':', '/', '/' >, uri::authority, uri::path_abempty, uri::opt_query, uri::opt_fragment > {};
|
||||
struct https_URI : if_must< istring< 'h', 't', 't', 'p', 's', ':', '/', '/' >, uri::authority, uri::path_abempty, uri::opt_query, uri::opt_fragment > {};
|
||||
|
||||
struct partial_URI : seq< uri::relative_part, uri::opt_query > {};
|
||||
// clang-format on
|
||||
|
||||
struct chunk_size
|
||||
{
|
||||
using rule_t = plus< abnf::HEXDIG >::rule_t;
|
||||
|
||||
template< apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, std::size_t& size, States&&... /*unused*/ )
|
||||
{
|
||||
size = 0;
|
||||
std::size_t i = 0;
|
||||
while( in.size( i + 1 ) >= i + 1 ) {
|
||||
const auto c = in.peek_char( i );
|
||||
if( ( '0' <= c ) && ( c <= '9' ) ) {
|
||||
size <<= 4;
|
||||
size |= std::size_t( c - '0' );
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
if( ( 'a' <= c ) && ( c <= 'f' ) ) {
|
||||
size <<= 4;
|
||||
size |= std::size_t( c - 'a' + 10 );
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
if( ( 'A' <= c ) && ( c <= 'F' ) ) {
|
||||
size <<= 4;
|
||||
size |= std::size_t( c - 'A' + 10 );
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
in.bump_in_this_line( i );
|
||||
return i > 0;
|
||||
}
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
struct chunk_ext_name : token {};
|
||||
struct chunk_ext_val : sor< quoted_string, token > {};
|
||||
struct chunk_ext : star_must< one< ';' >, chunk_ext_name, if_must< one< '=' >, chunk_ext_val > > {};
|
||||
// clang-format on
|
||||
|
||||
struct chunk_data
|
||||
{
|
||||
using rule_t = star< abnf::OCTET >::rule_t;
|
||||
|
||||
template< apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, const std::size_t size, States&&... /*unused*/ )
|
||||
{
|
||||
if( in.size( size ) >= size ) {
|
||||
in.bump( size );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
namespace internal::chunk_helper
|
||||
{
|
||||
template< typename Base >
|
||||
struct control;
|
||||
|
||||
template< template< typename... > class Control, typename Rule >
|
||||
struct control< Control< Rule > >
|
||||
: Control< Rule >
|
||||
{
|
||||
template< apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class,
|
||||
typename ParseInput,
|
||||
typename State,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, State&& /*unused*/, States&&... st )
|
||||
{
|
||||
return Control< Rule >::template match< A, M, Action, Control >( in, st... );
|
||||
}
|
||||
};
|
||||
|
||||
template< template< typename... > class Control >
|
||||
struct control< Control< chunk_size > >
|
||||
: remove_first_state< Control< chunk_size > >
|
||||
{};
|
||||
|
||||
template< template< typename... > class Control >
|
||||
struct control< Control< chunk_data > >
|
||||
: remove_first_state< Control< chunk_data > >
|
||||
{};
|
||||
|
||||
template< template< typename... > class Control >
|
||||
struct bind
|
||||
{
|
||||
template< typename Rule >
|
||||
using type = control< Control< Rule > >;
|
||||
};
|
||||
|
||||
} // namespace internal::chunk_helper
|
||||
|
||||
struct chunk
|
||||
{
|
||||
using impl = seq< chunk_size, chunk_ext, abnf::CRLF, chunk_data, abnf::CRLF >;
|
||||
|
||||
using rule_t = impl::rule_t;
|
||||
|
||||
template< apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, States&&... st )
|
||||
{
|
||||
std::size_t size{};
|
||||
return impl::template match< A, M, Action, internal::chunk_helper::bind< Control >::template type >( in, size, st... );
|
||||
}
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
struct last_chunk : seq< plus< one< '0' > >, not_at< digit >, chunk_ext, abnf::CRLF > {};
|
||||
|
||||
struct trailer_part : star< header_field, abnf::CRLF > {};
|
||||
|
||||
struct chunked_body : seq< until< last_chunk, chunk >, trailer_part, abnf::CRLF > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::http
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,99 @@
|
|||
// Copyright (c) 2018-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_ICU_INTERNAL_HPP
|
||||
#define TAO_PEGTL_CONTRIB_ICU_INTERNAL_HPP
|
||||
|
||||
#include <unicode/uchar.h>
|
||||
|
||||
#include "../analyze_traits.hpp"
|
||||
|
||||
#include "../../config.hpp"
|
||||
#include "../../type_list.hpp"
|
||||
|
||||
#include "../../internal/enable_control.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
namespace icu
|
||||
{
|
||||
template< typename Peek, UProperty P, bool V = true >
|
||||
struct binary_property
|
||||
{
|
||||
using peek_t = Peek;
|
||||
using data_t = typename Peek::data_t;
|
||||
|
||||
using rule_t = binary_property;
|
||||
using subs_t = empty_list;
|
||||
|
||||
[[nodiscard]] static bool test( const data_t c ) noexcept
|
||||
{
|
||||
return u_hasBinaryProperty( c, P ) == V;
|
||||
}
|
||||
|
||||
template< typename ParseInput >
|
||||
[[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( Peek::peek( in ) ) )
|
||||
{
|
||||
if( const auto t = Peek::peek( in ) ) {
|
||||
if( test( t.data ) ) {
|
||||
in.bump( t.size );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Peek, UProperty P, int V >
|
||||
struct property_value
|
||||
{
|
||||
using peek_t = Peek;
|
||||
using data_t = typename Peek::data_t;
|
||||
|
||||
using rule_t = property_value;
|
||||
using subs_t = empty_list;
|
||||
|
||||
[[nodiscard]] static bool test( const data_t c ) noexcept
|
||||
{
|
||||
return u_getIntPropertyValue( c, P ) == V;
|
||||
}
|
||||
|
||||
template< typename ParseInput >
|
||||
[[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( Peek::peek( in ) ) )
|
||||
{
|
||||
if( const auto t = Peek::peek( in ) ) {
|
||||
if( test( t.data ) ) {
|
||||
in.bump( t.size );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace icu
|
||||
|
||||
template< typename Peek, UProperty P, bool V >
|
||||
inline constexpr bool enable_control< icu::binary_property< Peek, P, V > > = false;
|
||||
|
||||
template< typename Peek, UProperty P, int V >
|
||||
inline constexpr bool enable_control< icu::property_value< Peek, P, V > > = false;
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template< typename Name, typename Peek, UProperty P, bool V >
|
||||
struct analyze_traits< Name, internal::icu::binary_property< Peek, P, V > >
|
||||
: analyze_any_traits<>
|
||||
{};
|
||||
|
||||
template< typename Name, typename Peek, UProperty P, int V >
|
||||
struct analyze_traits< Name, internal::icu::property_value< Peek, P, V > >
|
||||
: analyze_any_traits<>
|
||||
{};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,197 @@
|
|||
// Copyright (c) 2018-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_ICU_UTF16_HPP
|
||||
#define TAO_PEGTL_CONTRIB_ICU_UTF16_HPP
|
||||
|
||||
#include "internal.hpp"
|
||||
|
||||
#include "../../config.hpp"
|
||||
#include "../utf16.hpp"
|
||||
|
||||
#include "../internal/peek_utf16.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
namespace utf16_be::icu
|
||||
{
|
||||
template< UProperty P, bool V = true >
|
||||
struct binary_property
|
||||
: internal::icu::binary_property< internal::peek_utf16_be, P, V >
|
||||
{};
|
||||
|
||||
template< UProperty P, int V >
|
||||
struct property_value
|
||||
: internal::icu::property_value< internal::peek_utf16_be, P, V >
|
||||
{};
|
||||
|
||||
// clang-format off
|
||||
struct alphabetic : binary_property< UCHAR_ALPHABETIC > {};
|
||||
struct ascii_hex_digit : binary_property< UCHAR_ASCII_HEX_DIGIT > {};
|
||||
struct bidi_control : binary_property< UCHAR_BIDI_CONTROL > {};
|
||||
struct bidi_mirrored : binary_property< UCHAR_BIDI_MIRRORED > {};
|
||||
struct case_sensitive : binary_property< UCHAR_CASE_SENSITIVE > {};
|
||||
struct dash : binary_property< UCHAR_DASH > {};
|
||||
struct default_ignorable_code_point : binary_property< UCHAR_DEFAULT_IGNORABLE_CODE_POINT > {};
|
||||
struct deprecated : binary_property< UCHAR_DEPRECATED > {};
|
||||
struct diacritic : binary_property< UCHAR_DIACRITIC > {};
|
||||
struct extender : binary_property< UCHAR_EXTENDER > {};
|
||||
struct full_composition_exclusion : binary_property< UCHAR_FULL_COMPOSITION_EXCLUSION > {};
|
||||
struct grapheme_base : binary_property< UCHAR_GRAPHEME_BASE > {};
|
||||
struct grapheme_extend : binary_property< UCHAR_GRAPHEME_EXTEND > {};
|
||||
struct grapheme_link : binary_property< UCHAR_GRAPHEME_LINK > {};
|
||||
struct hex_digit : binary_property< UCHAR_HEX_DIGIT > {};
|
||||
struct hyphen : binary_property< UCHAR_HYPHEN > {};
|
||||
struct id_continue : binary_property< UCHAR_ID_CONTINUE > {};
|
||||
struct id_start : binary_property< UCHAR_ID_START > {};
|
||||
struct ideographic : binary_property< UCHAR_IDEOGRAPHIC > {};
|
||||
struct ids_binary_operator : binary_property< UCHAR_IDS_BINARY_OPERATOR > {};
|
||||
struct ids_trinary_operator : binary_property< UCHAR_IDS_TRINARY_OPERATOR > {};
|
||||
struct join_control : binary_property< UCHAR_JOIN_CONTROL > {};
|
||||
struct logical_order_exception : binary_property< UCHAR_LOGICAL_ORDER_EXCEPTION > {};
|
||||
struct lowercase : binary_property< UCHAR_LOWERCASE > {};
|
||||
struct math : binary_property< UCHAR_MATH > {};
|
||||
struct nfc_inert : binary_property< UCHAR_NFC_INERT > {};
|
||||
struct nfd_inert : binary_property< UCHAR_NFD_INERT > {};
|
||||
struct nfkc_inert : binary_property< UCHAR_NFKC_INERT > {};
|
||||
struct nfkd_inert : binary_property< UCHAR_NFKD_INERT > {};
|
||||
struct noncharacter_code_point : binary_property< UCHAR_NONCHARACTER_CODE_POINT > {};
|
||||
struct pattern_syntax : binary_property< UCHAR_PATTERN_SYNTAX > {};
|
||||
struct pattern_white_space : binary_property< UCHAR_PATTERN_WHITE_SPACE > {};
|
||||
struct posix_alnum : binary_property< UCHAR_POSIX_ALNUM > {};
|
||||
struct posix_blank : binary_property< UCHAR_POSIX_BLANK > {};
|
||||
struct posix_graph : binary_property< UCHAR_POSIX_GRAPH > {};
|
||||
struct posix_print : binary_property< UCHAR_POSIX_PRINT > {};
|
||||
struct posix_xdigit : binary_property< UCHAR_POSIX_XDIGIT > {};
|
||||
struct quotation_mark : binary_property< UCHAR_QUOTATION_MARK > {};
|
||||
struct radical : binary_property< UCHAR_RADICAL > {};
|
||||
struct s_term : binary_property< UCHAR_S_TERM > {};
|
||||
struct segment_starter : binary_property< UCHAR_SEGMENT_STARTER > {};
|
||||
struct soft_dotted : binary_property< UCHAR_SOFT_DOTTED > {};
|
||||
struct terminal_punctuation : binary_property< UCHAR_TERMINAL_PUNCTUATION > {};
|
||||
struct unified_ideograph : binary_property< UCHAR_UNIFIED_IDEOGRAPH > {};
|
||||
struct uppercase : binary_property< UCHAR_UPPERCASE > {};
|
||||
struct variation_selector : binary_property< UCHAR_VARIATION_SELECTOR > {};
|
||||
struct white_space : binary_property< UCHAR_WHITE_SPACE > {};
|
||||
struct xid_continue : binary_property< UCHAR_XID_CONTINUE > {};
|
||||
struct xid_start : binary_property< UCHAR_XID_START > {};
|
||||
|
||||
template< UCharDirection V > struct bidi_class : property_value< UCHAR_BIDI_CLASS, V > {};
|
||||
template< UBlockCode V > struct block : property_value< UCHAR_BLOCK, V > {};
|
||||
template< UDecompositionType V > struct decomposition_type : property_value< UCHAR_DECOMPOSITION_TYPE, V > {};
|
||||
template< UEastAsianWidth V > struct east_asian_width : property_value< UCHAR_EAST_ASIAN_WIDTH, V > {};
|
||||
template< UCharCategory V > struct general_category : property_value< UCHAR_GENERAL_CATEGORY, V > {};
|
||||
template< UGraphemeClusterBreak V > struct grapheme_cluster_break : property_value< UCHAR_GRAPHEME_CLUSTER_BREAK, V > {};
|
||||
template< UHangulSyllableType V > struct hangul_syllable_type : property_value< UCHAR_HANGUL_SYLLABLE_TYPE, V > {};
|
||||
template< UJoiningGroup V > struct joining_group : property_value< UCHAR_JOINING_GROUP, V > {};
|
||||
template< UJoiningType V > struct joining_type : property_value< UCHAR_JOINING_TYPE, V > {};
|
||||
template< ULineBreak V > struct line_break : property_value< UCHAR_LINE_BREAK, V > {};
|
||||
// UNormalizationCheckResult requires an additional header <unicode/unorm2.h>:
|
||||
// template< UNormalizationCheckResult V > struct nfc_quick_check : property_value< UCHAR_NFC_QUICK_CHECK, V > {};
|
||||
// template< UNormalizationCheckResult V > struct nfd_quick_check : property_value< UCHAR_NFD_QUICK_CHECK, V > {};
|
||||
// template< UNormalizationCheckResult V > struct nfkc_quick_check : property_value< UCHAR_NFKC_QUICK_CHECK, V > {};
|
||||
// template< UNormalizationCheckResult V > struct nfkd_quick_check : property_value< UCHAR_NFKD_QUICK_CHECK, V > {};
|
||||
template< UNumericType V > struct numeric_type : property_value< UCHAR_NUMERIC_TYPE, V > {};
|
||||
template< USentenceBreak V > struct sentence_break : property_value< UCHAR_SENTENCE_BREAK, V > {};
|
||||
template< UWordBreakValues V > struct word_break : property_value< UCHAR_WORD_BREAK, V > {};
|
||||
|
||||
template< std::uint8_t V > struct canonical_combining_class : property_value< UCHAR_CANONICAL_COMBINING_CLASS, V > {};
|
||||
template< std::uint8_t V > struct lead_canonical_combining_class : property_value< UCHAR_LEAD_CANONICAL_COMBINING_CLASS, V > {};
|
||||
template< std::uint8_t V > struct trail_canonical_combining_class : property_value< UCHAR_TRAIL_CANONICAL_COMBINING_CLASS, V > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace utf16_be::icu
|
||||
|
||||
namespace utf16_le::icu
|
||||
{
|
||||
template< UProperty P, bool V = true >
|
||||
struct binary_property
|
||||
: internal::icu::binary_property< internal::peek_utf16_le, P, V >
|
||||
{};
|
||||
|
||||
template< UProperty P, int V >
|
||||
struct property_value
|
||||
: internal::icu::property_value< internal::peek_utf16_le, P, V >
|
||||
{};
|
||||
|
||||
// clang-format off
|
||||
struct alphabetic : binary_property< UCHAR_ALPHABETIC > {};
|
||||
struct ascii_hex_digit : binary_property< UCHAR_ASCII_HEX_DIGIT > {};
|
||||
struct bidi_control : binary_property< UCHAR_BIDI_CONTROL > {};
|
||||
struct bidi_mirrored : binary_property< UCHAR_BIDI_MIRRORED > {};
|
||||
struct case_sensitive : binary_property< UCHAR_CASE_SENSITIVE > {};
|
||||
struct dash : binary_property< UCHAR_DASH > {};
|
||||
struct default_ignorable_code_point : binary_property< UCHAR_DEFAULT_IGNORABLE_CODE_POINT > {};
|
||||
struct deprecated : binary_property< UCHAR_DEPRECATED > {};
|
||||
struct diacritic : binary_property< UCHAR_DIACRITIC > {};
|
||||
struct extender : binary_property< UCHAR_EXTENDER > {};
|
||||
struct full_composition_exclusion : binary_property< UCHAR_FULL_COMPOSITION_EXCLUSION > {};
|
||||
struct grapheme_base : binary_property< UCHAR_GRAPHEME_BASE > {};
|
||||
struct grapheme_extend : binary_property< UCHAR_GRAPHEME_EXTEND > {};
|
||||
struct grapheme_link : binary_property< UCHAR_GRAPHEME_LINK > {};
|
||||
struct hex_digit : binary_property< UCHAR_HEX_DIGIT > {};
|
||||
struct hyphen : binary_property< UCHAR_HYPHEN > {};
|
||||
struct id_continue : binary_property< UCHAR_ID_CONTINUE > {};
|
||||
struct id_start : binary_property< UCHAR_ID_START > {};
|
||||
struct ideographic : binary_property< UCHAR_IDEOGRAPHIC > {};
|
||||
struct ids_binary_operator : binary_property< UCHAR_IDS_BINARY_OPERATOR > {};
|
||||
struct ids_trinary_operator : binary_property< UCHAR_IDS_TRINARY_OPERATOR > {};
|
||||
struct join_control : binary_property< UCHAR_JOIN_CONTROL > {};
|
||||
struct logical_order_exception : binary_property< UCHAR_LOGICAL_ORDER_EXCEPTION > {};
|
||||
struct lowercase : binary_property< UCHAR_LOWERCASE > {};
|
||||
struct math : binary_property< UCHAR_MATH > {};
|
||||
struct nfc_inert : binary_property< UCHAR_NFC_INERT > {};
|
||||
struct nfd_inert : binary_property< UCHAR_NFD_INERT > {};
|
||||
struct nfkc_inert : binary_property< UCHAR_NFKC_INERT > {};
|
||||
struct nfkd_inert : binary_property< UCHAR_NFKD_INERT > {};
|
||||
struct noncharacter_code_point : binary_property< UCHAR_NONCHARACTER_CODE_POINT > {};
|
||||
struct pattern_syntax : binary_property< UCHAR_PATTERN_SYNTAX > {};
|
||||
struct pattern_white_space : binary_property< UCHAR_PATTERN_WHITE_SPACE > {};
|
||||
struct posix_alnum : binary_property< UCHAR_POSIX_ALNUM > {};
|
||||
struct posix_blank : binary_property< UCHAR_POSIX_BLANK > {};
|
||||
struct posix_graph : binary_property< UCHAR_POSIX_GRAPH > {};
|
||||
struct posix_print : binary_property< UCHAR_POSIX_PRINT > {};
|
||||
struct posix_xdigit : binary_property< UCHAR_POSIX_XDIGIT > {};
|
||||
struct quotation_mark : binary_property< UCHAR_QUOTATION_MARK > {};
|
||||
struct radical : binary_property< UCHAR_RADICAL > {};
|
||||
struct s_term : binary_property< UCHAR_S_TERM > {};
|
||||
struct segment_starter : binary_property< UCHAR_SEGMENT_STARTER > {};
|
||||
struct soft_dotted : binary_property< UCHAR_SOFT_DOTTED > {};
|
||||
struct terminal_punctuation : binary_property< UCHAR_TERMINAL_PUNCTUATION > {};
|
||||
struct unified_ideograph : binary_property< UCHAR_UNIFIED_IDEOGRAPH > {};
|
||||
struct uppercase : binary_property< UCHAR_UPPERCASE > {};
|
||||
struct variation_selector : binary_property< UCHAR_VARIATION_SELECTOR > {};
|
||||
struct white_space : binary_property< UCHAR_WHITE_SPACE > {};
|
||||
struct xid_continue : binary_property< UCHAR_XID_CONTINUE > {};
|
||||
struct xid_start : binary_property< UCHAR_XID_START > {};
|
||||
|
||||
template< UCharDirection V > struct bidi_class : property_value< UCHAR_BIDI_CLASS, V > {};
|
||||
template< UBlockCode V > struct block : property_value< UCHAR_BLOCK, V > {};
|
||||
template< UDecompositionType V > struct decomposition_type : property_value< UCHAR_DECOMPOSITION_TYPE, V > {};
|
||||
template< UEastAsianWidth V > struct east_asian_width : property_value< UCHAR_EAST_ASIAN_WIDTH, V > {};
|
||||
template< UCharCategory V > struct general_category : property_value< UCHAR_GENERAL_CATEGORY, V > {};
|
||||
template< UGraphemeClusterBreak V > struct grapheme_cluster_break : property_value< UCHAR_GRAPHEME_CLUSTER_BREAK, V > {};
|
||||
template< UHangulSyllableType V > struct hangul_syllable_type : property_value< UCHAR_HANGUL_SYLLABLE_TYPE, V > {};
|
||||
template< UJoiningGroup V > struct joining_group : property_value< UCHAR_JOINING_GROUP, V > {};
|
||||
template< UJoiningType V > struct joining_type : property_value< UCHAR_JOINING_TYPE, V > {};
|
||||
template< ULineBreak V > struct line_break : property_value< UCHAR_LINE_BREAK, V > {};
|
||||
// UNormalizationCheckResult requires an additional header <unicode/unorm2.h>:
|
||||
// template< UNormalizationCheckResult V > struct nfc_quick_check : property_value< UCHAR_NFC_QUICK_CHECK, V > {};
|
||||
// template< UNormalizationCheckResult V > struct nfd_quick_check : property_value< UCHAR_NFD_QUICK_CHECK, V > {};
|
||||
// template< UNormalizationCheckResult V > struct nfkc_quick_check : property_value< UCHAR_NFKC_QUICK_CHECK, V > {};
|
||||
// template< UNormalizationCheckResult V > struct nfkd_quick_check : property_value< UCHAR_NFKD_QUICK_CHECK, V > {};
|
||||
template< UNumericType V > struct numeric_type : property_value< UCHAR_NUMERIC_TYPE, V > {};
|
||||
template< USentenceBreak V > struct sentence_break : property_value< UCHAR_SENTENCE_BREAK, V > {};
|
||||
template< UWordBreakValues V > struct word_break : property_value< UCHAR_WORD_BREAK, V > {};
|
||||
|
||||
template< std::uint8_t V > struct canonical_combining_class : property_value< UCHAR_CANONICAL_COMBINING_CLASS, V > {};
|
||||
template< std::uint8_t V > struct lead_canonical_combining_class : property_value< UCHAR_LEAD_CANONICAL_COMBINING_CLASS, V > {};
|
||||
template< std::uint8_t V > struct trail_canonical_combining_class : property_value< UCHAR_TRAIL_CANONICAL_COMBINING_CLASS, V > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace utf16_le::icu
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,197 @@
|
|||
// Copyright (c) 2018-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_ICU_UTF32_HPP
|
||||
#define TAO_PEGTL_CONTRIB_ICU_UTF32_HPP
|
||||
|
||||
#include "internal.hpp"
|
||||
|
||||
#include "../../config.hpp"
|
||||
#include "../utf32.hpp"
|
||||
|
||||
#include "../internal/peek_utf32.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
namespace utf32_be::icu
|
||||
{
|
||||
template< UProperty P, bool V = true >
|
||||
struct binary_property
|
||||
: internal::icu::binary_property< internal::peek_utf32_be, P, V >
|
||||
{};
|
||||
|
||||
template< UProperty P, int V >
|
||||
struct property_value
|
||||
: internal::icu::property_value< internal::peek_utf32_be, P, V >
|
||||
{};
|
||||
|
||||
// clang-format off
|
||||
struct alphabetic : binary_property< UCHAR_ALPHABETIC > {};
|
||||
struct ascii_hex_digit : binary_property< UCHAR_ASCII_HEX_DIGIT > {};
|
||||
struct bidi_control : binary_property< UCHAR_BIDI_CONTROL > {};
|
||||
struct bidi_mirrored : binary_property< UCHAR_BIDI_MIRRORED > {};
|
||||
struct case_sensitive : binary_property< UCHAR_CASE_SENSITIVE > {};
|
||||
struct dash : binary_property< UCHAR_DASH > {};
|
||||
struct default_ignorable_code_point : binary_property< UCHAR_DEFAULT_IGNORABLE_CODE_POINT > {};
|
||||
struct deprecated : binary_property< UCHAR_DEPRECATED > {};
|
||||
struct diacritic : binary_property< UCHAR_DIACRITIC > {};
|
||||
struct extender : binary_property< UCHAR_EXTENDER > {};
|
||||
struct full_composition_exclusion : binary_property< UCHAR_FULL_COMPOSITION_EXCLUSION > {};
|
||||
struct grapheme_base : binary_property< UCHAR_GRAPHEME_BASE > {};
|
||||
struct grapheme_extend : binary_property< UCHAR_GRAPHEME_EXTEND > {};
|
||||
struct grapheme_link : binary_property< UCHAR_GRAPHEME_LINK > {};
|
||||
struct hex_digit : binary_property< UCHAR_HEX_DIGIT > {};
|
||||
struct hyphen : binary_property< UCHAR_HYPHEN > {};
|
||||
struct id_continue : binary_property< UCHAR_ID_CONTINUE > {};
|
||||
struct id_start : binary_property< UCHAR_ID_START > {};
|
||||
struct ideographic : binary_property< UCHAR_IDEOGRAPHIC > {};
|
||||
struct ids_binary_operator : binary_property< UCHAR_IDS_BINARY_OPERATOR > {};
|
||||
struct ids_trinary_operator : binary_property< UCHAR_IDS_TRINARY_OPERATOR > {};
|
||||
struct join_control : binary_property< UCHAR_JOIN_CONTROL > {};
|
||||
struct logical_order_exception : binary_property< UCHAR_LOGICAL_ORDER_EXCEPTION > {};
|
||||
struct lowercase : binary_property< UCHAR_LOWERCASE > {};
|
||||
struct math : binary_property< UCHAR_MATH > {};
|
||||
struct nfc_inert : binary_property< UCHAR_NFC_INERT > {};
|
||||
struct nfd_inert : binary_property< UCHAR_NFD_INERT > {};
|
||||
struct nfkc_inert : binary_property< UCHAR_NFKC_INERT > {};
|
||||
struct nfkd_inert : binary_property< UCHAR_NFKD_INERT > {};
|
||||
struct noncharacter_code_point : binary_property< UCHAR_NONCHARACTER_CODE_POINT > {};
|
||||
struct pattern_syntax : binary_property< UCHAR_PATTERN_SYNTAX > {};
|
||||
struct pattern_white_space : binary_property< UCHAR_PATTERN_WHITE_SPACE > {};
|
||||
struct posix_alnum : binary_property< UCHAR_POSIX_ALNUM > {};
|
||||
struct posix_blank : binary_property< UCHAR_POSIX_BLANK > {};
|
||||
struct posix_graph : binary_property< UCHAR_POSIX_GRAPH > {};
|
||||
struct posix_print : binary_property< UCHAR_POSIX_PRINT > {};
|
||||
struct posix_xdigit : binary_property< UCHAR_POSIX_XDIGIT > {};
|
||||
struct quotation_mark : binary_property< UCHAR_QUOTATION_MARK > {};
|
||||
struct radical : binary_property< UCHAR_RADICAL > {};
|
||||
struct s_term : binary_property< UCHAR_S_TERM > {};
|
||||
struct segment_starter : binary_property< UCHAR_SEGMENT_STARTER > {};
|
||||
struct soft_dotted : binary_property< UCHAR_SOFT_DOTTED > {};
|
||||
struct terminal_punctuation : binary_property< UCHAR_TERMINAL_PUNCTUATION > {};
|
||||
struct unified_ideograph : binary_property< UCHAR_UNIFIED_IDEOGRAPH > {};
|
||||
struct uppercase : binary_property< UCHAR_UPPERCASE > {};
|
||||
struct variation_selector : binary_property< UCHAR_VARIATION_SELECTOR > {};
|
||||
struct white_space : binary_property< UCHAR_WHITE_SPACE > {};
|
||||
struct xid_continue : binary_property< UCHAR_XID_CONTINUE > {};
|
||||
struct xid_start : binary_property< UCHAR_XID_START > {};
|
||||
|
||||
template< UCharDirection V > struct bidi_class : property_value< UCHAR_BIDI_CLASS, V > {};
|
||||
template< UBlockCode V > struct block : property_value< UCHAR_BLOCK, V > {};
|
||||
template< UDecompositionType V > struct decomposition_type : property_value< UCHAR_DECOMPOSITION_TYPE, V > {};
|
||||
template< UEastAsianWidth V > struct east_asian_width : property_value< UCHAR_EAST_ASIAN_WIDTH, V > {};
|
||||
template< UCharCategory V > struct general_category : property_value< UCHAR_GENERAL_CATEGORY, V > {};
|
||||
template< UGraphemeClusterBreak V > struct grapheme_cluster_break : property_value< UCHAR_GRAPHEME_CLUSTER_BREAK, V > {};
|
||||
template< UHangulSyllableType V > struct hangul_syllable_type : property_value< UCHAR_HANGUL_SYLLABLE_TYPE, V > {};
|
||||
template< UJoiningGroup V > struct joining_group : property_value< UCHAR_JOINING_GROUP, V > {};
|
||||
template< UJoiningType V > struct joining_type : property_value< UCHAR_JOINING_TYPE, V > {};
|
||||
template< ULineBreak V > struct line_break : property_value< UCHAR_LINE_BREAK, V > {};
|
||||
// UNormalizationCheckResult requires an additional header <unicode/unorm2.h>:
|
||||
// template< UNormalizationCheckResult V > struct nfc_quick_check : property_value< UCHAR_NFC_QUICK_CHECK, V > {};
|
||||
// template< UNormalizationCheckResult V > struct nfd_quick_check : property_value< UCHAR_NFD_QUICK_CHECK, V > {};
|
||||
// template< UNormalizationCheckResult V > struct nfkc_quick_check : property_value< UCHAR_NFKC_QUICK_CHECK, V > {};
|
||||
// template< UNormalizationCheckResult V > struct nfkd_quick_check : property_value< UCHAR_NFKD_QUICK_CHECK, V > {};
|
||||
template< UNumericType V > struct numeric_type : property_value< UCHAR_NUMERIC_TYPE, V > {};
|
||||
template< USentenceBreak V > struct sentence_break : property_value< UCHAR_SENTENCE_BREAK, V > {};
|
||||
template< UWordBreakValues V > struct word_break : property_value< UCHAR_WORD_BREAK, V > {};
|
||||
|
||||
template< std::uint8_t V > struct canonical_combining_class : property_value< UCHAR_CANONICAL_COMBINING_CLASS, V > {};
|
||||
template< std::uint8_t V > struct lead_canonical_combining_class : property_value< UCHAR_LEAD_CANONICAL_COMBINING_CLASS, V > {};
|
||||
template< std::uint8_t V > struct trail_canonical_combining_class : property_value< UCHAR_TRAIL_CANONICAL_COMBINING_CLASS, V > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace utf32_be::icu
|
||||
|
||||
namespace utf32_le::icu
|
||||
{
|
||||
template< UProperty P, bool V = true >
|
||||
struct binary_property
|
||||
: internal::icu::binary_property< internal::peek_utf32_le, P, V >
|
||||
{};
|
||||
|
||||
template< UProperty P, int V >
|
||||
struct property_value
|
||||
: internal::icu::property_value< internal::peek_utf32_le, P, V >
|
||||
{};
|
||||
|
||||
// clang-format off
|
||||
struct alphabetic : binary_property< UCHAR_ALPHABETIC > {};
|
||||
struct ascii_hex_digit : binary_property< UCHAR_ASCII_HEX_DIGIT > {};
|
||||
struct bidi_control : binary_property< UCHAR_BIDI_CONTROL > {};
|
||||
struct bidi_mirrored : binary_property< UCHAR_BIDI_MIRRORED > {};
|
||||
struct case_sensitive : binary_property< UCHAR_CASE_SENSITIVE > {};
|
||||
struct dash : binary_property< UCHAR_DASH > {};
|
||||
struct default_ignorable_code_point : binary_property< UCHAR_DEFAULT_IGNORABLE_CODE_POINT > {};
|
||||
struct deprecated : binary_property< UCHAR_DEPRECATED > {};
|
||||
struct diacritic : binary_property< UCHAR_DIACRITIC > {};
|
||||
struct extender : binary_property< UCHAR_EXTENDER > {};
|
||||
struct full_composition_exclusion : binary_property< UCHAR_FULL_COMPOSITION_EXCLUSION > {};
|
||||
struct grapheme_base : binary_property< UCHAR_GRAPHEME_BASE > {};
|
||||
struct grapheme_extend : binary_property< UCHAR_GRAPHEME_EXTEND > {};
|
||||
struct grapheme_link : binary_property< UCHAR_GRAPHEME_LINK > {};
|
||||
struct hex_digit : binary_property< UCHAR_HEX_DIGIT > {};
|
||||
struct hyphen : binary_property< UCHAR_HYPHEN > {};
|
||||
struct id_continue : binary_property< UCHAR_ID_CONTINUE > {};
|
||||
struct id_start : binary_property< UCHAR_ID_START > {};
|
||||
struct ideographic : binary_property< UCHAR_IDEOGRAPHIC > {};
|
||||
struct ids_binary_operator : binary_property< UCHAR_IDS_BINARY_OPERATOR > {};
|
||||
struct ids_trinary_operator : binary_property< UCHAR_IDS_TRINARY_OPERATOR > {};
|
||||
struct join_control : binary_property< UCHAR_JOIN_CONTROL > {};
|
||||
struct logical_order_exception : binary_property< UCHAR_LOGICAL_ORDER_EXCEPTION > {};
|
||||
struct lowercase : binary_property< UCHAR_LOWERCASE > {};
|
||||
struct math : binary_property< UCHAR_MATH > {};
|
||||
struct nfc_inert : binary_property< UCHAR_NFC_INERT > {};
|
||||
struct nfd_inert : binary_property< UCHAR_NFD_INERT > {};
|
||||
struct nfkc_inert : binary_property< UCHAR_NFKC_INERT > {};
|
||||
struct nfkd_inert : binary_property< UCHAR_NFKD_INERT > {};
|
||||
struct noncharacter_code_point : binary_property< UCHAR_NONCHARACTER_CODE_POINT > {};
|
||||
struct pattern_syntax : binary_property< UCHAR_PATTERN_SYNTAX > {};
|
||||
struct pattern_white_space : binary_property< UCHAR_PATTERN_WHITE_SPACE > {};
|
||||
struct posix_alnum : binary_property< UCHAR_POSIX_ALNUM > {};
|
||||
struct posix_blank : binary_property< UCHAR_POSIX_BLANK > {};
|
||||
struct posix_graph : binary_property< UCHAR_POSIX_GRAPH > {};
|
||||
struct posix_print : binary_property< UCHAR_POSIX_PRINT > {};
|
||||
struct posix_xdigit : binary_property< UCHAR_POSIX_XDIGIT > {};
|
||||
struct quotation_mark : binary_property< UCHAR_QUOTATION_MARK > {};
|
||||
struct radical : binary_property< UCHAR_RADICAL > {};
|
||||
struct s_term : binary_property< UCHAR_S_TERM > {};
|
||||
struct segment_starter : binary_property< UCHAR_SEGMENT_STARTER > {};
|
||||
struct soft_dotted : binary_property< UCHAR_SOFT_DOTTED > {};
|
||||
struct terminal_punctuation : binary_property< UCHAR_TERMINAL_PUNCTUATION > {};
|
||||
struct unified_ideograph : binary_property< UCHAR_UNIFIED_IDEOGRAPH > {};
|
||||
struct uppercase : binary_property< UCHAR_UPPERCASE > {};
|
||||
struct variation_selector : binary_property< UCHAR_VARIATION_SELECTOR > {};
|
||||
struct white_space : binary_property< UCHAR_WHITE_SPACE > {};
|
||||
struct xid_continue : binary_property< UCHAR_XID_CONTINUE > {};
|
||||
struct xid_start : binary_property< UCHAR_XID_START > {};
|
||||
|
||||
template< UCharDirection V > struct bidi_class : property_value< UCHAR_BIDI_CLASS, V > {};
|
||||
template< UBlockCode V > struct block : property_value< UCHAR_BLOCK, V > {};
|
||||
template< UDecompositionType V > struct decomposition_type : property_value< UCHAR_DECOMPOSITION_TYPE, V > {};
|
||||
template< UEastAsianWidth V > struct east_asian_width : property_value< UCHAR_EAST_ASIAN_WIDTH, V > {};
|
||||
template< UCharCategory V > struct general_category : property_value< UCHAR_GENERAL_CATEGORY, V > {};
|
||||
template< UGraphemeClusterBreak V > struct grapheme_cluster_break : property_value< UCHAR_GRAPHEME_CLUSTER_BREAK, V > {};
|
||||
template< UHangulSyllableType V > struct hangul_syllable_type : property_value< UCHAR_HANGUL_SYLLABLE_TYPE, V > {};
|
||||
template< UJoiningGroup V > struct joining_group : property_value< UCHAR_JOINING_GROUP, V > {};
|
||||
template< UJoiningType V > struct joining_type : property_value< UCHAR_JOINING_TYPE, V > {};
|
||||
template< ULineBreak V > struct line_break : property_value< UCHAR_LINE_BREAK, V > {};
|
||||
// UNormalizationCheckResult requires an additional header <unicode/unorm2.h>:
|
||||
// template< UNormalizationCheckResult V > struct nfc_quick_check : property_value< UCHAR_NFC_QUICK_CHECK, V > {};
|
||||
// template< UNormalizationCheckResult V > struct nfd_quick_check : property_value< UCHAR_NFD_QUICK_CHECK, V > {};
|
||||
// template< UNormalizationCheckResult V > struct nfkc_quick_check : property_value< UCHAR_NFKC_QUICK_CHECK, V > {};
|
||||
// template< UNormalizationCheckResult V > struct nfkd_quick_check : property_value< UCHAR_NFKD_QUICK_CHECK, V > {};
|
||||
template< UNumericType V > struct numeric_type : property_value< UCHAR_NUMERIC_TYPE, V > {};
|
||||
template< USentenceBreak V > struct sentence_break : property_value< UCHAR_SENTENCE_BREAK, V > {};
|
||||
template< UWordBreakValues V > struct word_break : property_value< UCHAR_WORD_BREAK, V > {};
|
||||
|
||||
template< std::uint8_t V > struct canonical_combining_class : property_value< UCHAR_CANONICAL_COMBINING_CLASS, V > {};
|
||||
template< std::uint8_t V > struct lead_canonical_combining_class : property_value< UCHAR_LEAD_CANONICAL_COMBINING_CLASS, V > {};
|
||||
template< std::uint8_t V > struct trail_canonical_combining_class : property_value< UCHAR_TRAIL_CANONICAL_COMBINING_CLASS, V > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace utf32_le::icu
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,104 @@
|
|||
// Copyright (c) 2018-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_ICU_UTF8_HPP
|
||||
#define TAO_PEGTL_CONTRIB_ICU_UTF8_HPP
|
||||
|
||||
#include "internal.hpp"
|
||||
|
||||
#include "../../config.hpp"
|
||||
#include "../../utf8.hpp"
|
||||
|
||||
#include "../../internal/peek_utf8.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::utf8::icu
|
||||
{
|
||||
template< UProperty P, bool V = true >
|
||||
struct binary_property
|
||||
: internal::icu::binary_property< internal::peek_utf8, P, V >
|
||||
{};
|
||||
|
||||
template< UProperty P, int V >
|
||||
struct property_value
|
||||
: internal::icu::property_value< internal::peek_utf8, P, V >
|
||||
{};
|
||||
|
||||
// clang-format off
|
||||
struct alphabetic : binary_property< UCHAR_ALPHABETIC > {};
|
||||
struct ascii_hex_digit : binary_property< UCHAR_ASCII_HEX_DIGIT > {};
|
||||
struct bidi_control : binary_property< UCHAR_BIDI_CONTROL > {};
|
||||
struct bidi_mirrored : binary_property< UCHAR_BIDI_MIRRORED > {};
|
||||
struct case_sensitive : binary_property< UCHAR_CASE_SENSITIVE > {};
|
||||
struct dash : binary_property< UCHAR_DASH > {};
|
||||
struct default_ignorable_code_point : binary_property< UCHAR_DEFAULT_IGNORABLE_CODE_POINT > {};
|
||||
struct deprecated : binary_property< UCHAR_DEPRECATED > {};
|
||||
struct diacritic : binary_property< UCHAR_DIACRITIC > {};
|
||||
struct extender : binary_property< UCHAR_EXTENDER > {};
|
||||
struct full_composition_exclusion : binary_property< UCHAR_FULL_COMPOSITION_EXCLUSION > {};
|
||||
struct grapheme_base : binary_property< UCHAR_GRAPHEME_BASE > {};
|
||||
struct grapheme_extend : binary_property< UCHAR_GRAPHEME_EXTEND > {};
|
||||
struct grapheme_link : binary_property< UCHAR_GRAPHEME_LINK > {};
|
||||
struct hex_digit : binary_property< UCHAR_HEX_DIGIT > {};
|
||||
struct hyphen : binary_property< UCHAR_HYPHEN > {};
|
||||
struct id_continue : binary_property< UCHAR_ID_CONTINUE > {};
|
||||
struct id_start : binary_property< UCHAR_ID_START > {};
|
||||
struct ideographic : binary_property< UCHAR_IDEOGRAPHIC > {};
|
||||
struct ids_binary_operator : binary_property< UCHAR_IDS_BINARY_OPERATOR > {};
|
||||
struct ids_trinary_operator : binary_property< UCHAR_IDS_TRINARY_OPERATOR > {};
|
||||
struct join_control : binary_property< UCHAR_JOIN_CONTROL > {};
|
||||
struct logical_order_exception : binary_property< UCHAR_LOGICAL_ORDER_EXCEPTION > {};
|
||||
struct lowercase : binary_property< UCHAR_LOWERCASE > {};
|
||||
struct math : binary_property< UCHAR_MATH > {};
|
||||
struct nfc_inert : binary_property< UCHAR_NFC_INERT > {};
|
||||
struct nfd_inert : binary_property< UCHAR_NFD_INERT > {};
|
||||
struct nfkc_inert : binary_property< UCHAR_NFKC_INERT > {};
|
||||
struct nfkd_inert : binary_property< UCHAR_NFKD_INERT > {};
|
||||
struct noncharacter_code_point : binary_property< UCHAR_NONCHARACTER_CODE_POINT > {};
|
||||
struct pattern_syntax : binary_property< UCHAR_PATTERN_SYNTAX > {};
|
||||
struct pattern_white_space : binary_property< UCHAR_PATTERN_WHITE_SPACE > {};
|
||||
struct posix_alnum : binary_property< UCHAR_POSIX_ALNUM > {};
|
||||
struct posix_blank : binary_property< UCHAR_POSIX_BLANK > {};
|
||||
struct posix_graph : binary_property< UCHAR_POSIX_GRAPH > {};
|
||||
struct posix_print : binary_property< UCHAR_POSIX_PRINT > {};
|
||||
struct posix_xdigit : binary_property< UCHAR_POSIX_XDIGIT > {};
|
||||
struct quotation_mark : binary_property< UCHAR_QUOTATION_MARK > {};
|
||||
struct radical : binary_property< UCHAR_RADICAL > {};
|
||||
struct s_term : binary_property< UCHAR_S_TERM > {};
|
||||
struct segment_starter : binary_property< UCHAR_SEGMENT_STARTER > {};
|
||||
struct soft_dotted : binary_property< UCHAR_SOFT_DOTTED > {};
|
||||
struct terminal_punctuation : binary_property< UCHAR_TERMINAL_PUNCTUATION > {};
|
||||
struct unified_ideograph : binary_property< UCHAR_UNIFIED_IDEOGRAPH > {};
|
||||
struct uppercase : binary_property< UCHAR_UPPERCASE > {};
|
||||
struct variation_selector : binary_property< UCHAR_VARIATION_SELECTOR > {};
|
||||
struct white_space : binary_property< UCHAR_WHITE_SPACE > {};
|
||||
struct xid_continue : binary_property< UCHAR_XID_CONTINUE > {};
|
||||
struct xid_start : binary_property< UCHAR_XID_START > {};
|
||||
|
||||
template< UCharDirection V > struct bidi_class : property_value< UCHAR_BIDI_CLASS, V > {};
|
||||
template< UBlockCode V > struct block : property_value< UCHAR_BLOCK, V > {};
|
||||
template< UDecompositionType V > struct decomposition_type : property_value< UCHAR_DECOMPOSITION_TYPE, V > {};
|
||||
template< UEastAsianWidth V > struct east_asian_width : property_value< UCHAR_EAST_ASIAN_WIDTH, V > {};
|
||||
template< UCharCategory V > struct general_category : property_value< UCHAR_GENERAL_CATEGORY, V > {};
|
||||
template< UGraphemeClusterBreak V > struct grapheme_cluster_break : property_value< UCHAR_GRAPHEME_CLUSTER_BREAK, V > {};
|
||||
template< UHangulSyllableType V > struct hangul_syllable_type : property_value< UCHAR_HANGUL_SYLLABLE_TYPE, V > {};
|
||||
template< UJoiningGroup V > struct joining_group : property_value< UCHAR_JOINING_GROUP, V > {};
|
||||
template< UJoiningType V > struct joining_type : property_value< UCHAR_JOINING_TYPE, V > {};
|
||||
template< ULineBreak V > struct line_break : property_value< UCHAR_LINE_BREAK, V > {};
|
||||
// UNormalizationCheckResult requires an additional header <unicode/unorm2.h>:
|
||||
// template< UNormalizationCheckResult V > struct nfc_quick_check : property_value< UCHAR_NFC_QUICK_CHECK, V > {};
|
||||
// template< UNormalizationCheckResult V > struct nfd_quick_check : property_value< UCHAR_NFD_QUICK_CHECK, V > {};
|
||||
// template< UNormalizationCheckResult V > struct nfkc_quick_check : property_value< UCHAR_NFKC_QUICK_CHECK, V > {};
|
||||
// template< UNormalizationCheckResult V > struct nfkd_quick_check : property_value< UCHAR_NFKD_QUICK_CHECK, V > {};
|
||||
template< UNumericType V > struct numeric_type : property_value< UCHAR_NUMERIC_TYPE, V > {};
|
||||
template< USentenceBreak V > struct sentence_break : property_value< UCHAR_SENTENCE_BREAK, V > {};
|
||||
template< UWordBreakValues V > struct word_break : property_value< UCHAR_WORD_BREAK, V > {};
|
||||
|
||||
template< std::uint8_t V > struct canonical_combining_class : property_value< UCHAR_CANONICAL_COMBINING_CLASS, V > {};
|
||||
template< std::uint8_t V > struct lead_canonical_combining_class : property_value< UCHAR_LEAD_CANONICAL_COMBINING_CLASS, V > {};
|
||||
template< std::uint8_t V > struct trail_canonical_combining_class : property_value< UCHAR_TRAIL_CANONICAL_COMBINING_CLASS, V > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::utf8::icu
|
||||
|
||||
#endif
|
|
@ -0,0 +1,57 @@
|
|||
// Copyright (c) 2018-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_IF_THEN_HPP
|
||||
#define TAO_PEGTL_CONTRIB_IF_THEN_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "../config.hpp"
|
||||
|
||||
#include "../internal/enable_control.hpp"
|
||||
#include "../internal/failure.hpp"
|
||||
#include "../internal/if_then_else.hpp"
|
||||
#include "../internal/seq.hpp"
|
||||
#include "../internal/success.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
template< typename Cond, typename Then >
|
||||
struct if_pair
|
||||
{};
|
||||
|
||||
template< typename... Pairs >
|
||||
struct if_then;
|
||||
|
||||
template< typename Cond, typename Then, typename... Pairs >
|
||||
struct if_then< if_pair< Cond, Then >, Pairs... >
|
||||
: if_then_else< Cond, Then, if_then< Pairs... > >
|
||||
{
|
||||
template< typename ElseCond, typename... Thens >
|
||||
using else_if_then = if_then< if_pair< Cond, Then >, Pairs..., if_pair< ElseCond, seq< Thens... > > >;
|
||||
|
||||
template< typename... Thens >
|
||||
using else_then = if_then_else< Cond, Then, if_then< Pairs..., if_pair< success, seq< Thens... > > > >;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct if_then<>
|
||||
: failure
|
||||
{};
|
||||
|
||||
template< typename... Pairs >
|
||||
inline constexpr bool enable_control< if_then< Pairs... > > = false;
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template< typename Cond, typename... Thens >
|
||||
struct if_then
|
||||
: internal::if_then< internal::if_pair< Cond, internal::seq< Thens... > > >
|
||||
{};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright (c) 2020-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_INSTANTIATE_HPP
|
||||
#define TAO_PEGTL_CONTRIB_INSTANTIATE_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
|
||||
#include "../apply_mode.hpp"
|
||||
#include "../match.hpp"
|
||||
#include "../nothing.hpp"
|
||||
#include "../rewind_mode.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
template< typename T >
|
||||
struct instantiate
|
||||
: maybe_nothing
|
||||
{
|
||||
template< typename Rule,
|
||||
apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, States&&... st )
|
||||
{
|
||||
const T t( static_cast< const ParseInput& >( in ), st... );
|
||||
return TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, st... );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,469 @@
|
|||
// Copyright (c) 2019-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_INTEGER_HPP
|
||||
#define TAO_PEGTL_CONTRIB_INTEGER_HPP
|
||||
|
||||
#if !defined( __cpp_exceptions )
|
||||
#error "Exception support required for tao/pegtl/contrib/integer.hpp"
|
||||
#else
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <limits>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
|
||||
#include "../ascii.hpp"
|
||||
#include "../parse.hpp"
|
||||
#include "../parse_error.hpp"
|
||||
#include "../rules.hpp"
|
||||
|
||||
#include "analyze_traits.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
struct unsigned_rule_old
|
||||
: plus< digit >
|
||||
{
|
||||
// Pre-3.0 version of this rule.
|
||||
};
|
||||
|
||||
struct unsigned_rule_new
|
||||
: if_then_else< one< '0' >, not_at< digit >, plus< digit > >
|
||||
{
|
||||
// New version that does not allow leading zeros.
|
||||
};
|
||||
|
||||
struct signed_rule_old
|
||||
: seq< opt< one< '-', '+' > >, plus< digit > >
|
||||
{
|
||||
// Pre-3.0 version of this rule.
|
||||
};
|
||||
|
||||
struct signed_rule_new
|
||||
: seq< opt< one< '-', '+' > >, if_then_else< one< '0' >, not_at< digit >, plus< digit > > >
|
||||
{
|
||||
// New version that does not allow leading zeros.
|
||||
};
|
||||
|
||||
struct signed_rule_bis
|
||||
: seq< opt< one< '-' > >, if_then_else< one< '0' >, not_at< digit >, plus< digit > > >
|
||||
{};
|
||||
|
||||
struct signed_rule_ter
|
||||
: seq< one< '-', '+' >, if_then_else< one< '0' >, not_at< digit >, plus< digit > > >
|
||||
{};
|
||||
|
||||
namespace internal
|
||||
{
|
||||
[[nodiscard]] constexpr bool is_digit( const char c ) noexcept
|
||||
{
|
||||
// We don't use std::isdigit() because it might
|
||||
// return true for other values on MS platforms.
|
||||
|
||||
return ( '0' <= c ) && ( c <= '9' );
|
||||
}
|
||||
|
||||
template< typename Integer, Integer Maximum = ( std::numeric_limits< Integer >::max )() >
|
||||
[[nodiscard]] constexpr bool accumulate_digit( Integer& result, const char digit ) noexcept
|
||||
{
|
||||
// Assumes that digit is a digit as per is_digit(); returns false on overflow.
|
||||
|
||||
static_assert( std::is_integral_v< Integer > );
|
||||
|
||||
constexpr Integer cutoff = Maximum / 10;
|
||||
constexpr Integer cutlim = Maximum % 10;
|
||||
|
||||
const Integer c = digit - '0';
|
||||
|
||||
if( ( result > cutoff ) || ( ( result == cutoff ) && ( c > cutlim ) ) ) {
|
||||
return false;
|
||||
}
|
||||
result *= 10;
|
||||
result += c;
|
||||
return true;
|
||||
}
|
||||
|
||||
template< typename Integer, Integer Maximum = ( std::numeric_limits< Integer >::max )() >
|
||||
[[nodiscard]] constexpr bool accumulate_digits( Integer& result, const std::string_view input ) noexcept
|
||||
{
|
||||
// Assumes input is a non-empty sequence of digits; returns false on overflow.
|
||||
|
||||
for( char c : input ) {
|
||||
if( !accumulate_digit< Integer, Maximum >( result, c ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template< typename Integer, Integer Maximum = ( std::numeric_limits< Integer >::max )() >
|
||||
[[nodiscard]] constexpr bool convert_positive( Integer& result, const std::string_view input ) noexcept
|
||||
{
|
||||
// Assumes result == 0 and that input is a non-empty sequence of digits; returns false on overflow.
|
||||
|
||||
static_assert( std::is_integral_v< Integer > );
|
||||
return accumulate_digits< Integer, Maximum >( result, input );
|
||||
}
|
||||
|
||||
template< typename Signed >
|
||||
[[nodiscard]] constexpr bool convert_negative( Signed& result, const std::string_view input ) noexcept
|
||||
{
|
||||
// Assumes result == 0 and that input is a non-empty sequence of digits; returns false on overflow.
|
||||
|
||||
static_assert( std::is_signed_v< Signed > );
|
||||
using Unsigned = std::make_unsigned_t< Signed >;
|
||||
constexpr Unsigned maximum = static_cast< Unsigned >( ( std::numeric_limits< Signed >::max )() ) + 1;
|
||||
Unsigned temporary = 0;
|
||||
if( accumulate_digits< Unsigned, maximum >( temporary, input ) ) {
|
||||
result = static_cast< Signed >( ~temporary ) + 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template< typename Unsigned, Unsigned Maximum = ( std::numeric_limits< Unsigned >::max )() >
|
||||
[[nodiscard]] constexpr bool convert_unsigned( Unsigned& result, const std::string_view input ) noexcept
|
||||
{
|
||||
// Assumes result == 0 and that input is a non-empty sequence of digits; returns false on overflow.
|
||||
|
||||
static_assert( std::is_unsigned_v< Unsigned > );
|
||||
return accumulate_digits< Unsigned, Maximum >( result, input );
|
||||
}
|
||||
|
||||
template< typename Signed >
|
||||
[[nodiscard]] constexpr bool convert_signed( Signed& result, const std::string_view input ) noexcept
|
||||
{
|
||||
// Assumes result == 0 and that input is an optional sign followed by a non-empty sequence of digits; returns false on overflow.
|
||||
|
||||
static_assert( std::is_signed_v< Signed > );
|
||||
if( input[ 0 ] == '-' ) {
|
||||
return convert_negative< Signed >( result, std::string_view( input.data() + 1, input.size() - 1 ) );
|
||||
}
|
||||
const auto offset = unsigned( input[ 0 ] == '+' );
|
||||
return convert_positive< Signed >( result, std::string_view( input.data() + offset, input.size() - offset ) );
|
||||
}
|
||||
|
||||
template< typename ParseInput >
|
||||
[[nodiscard]] bool match_unsigned( ParseInput& in ) noexcept( noexcept( in.empty() ) )
|
||||
{
|
||||
if( !in.empty() ) {
|
||||
const char c = in.peek_char();
|
||||
if( is_digit( c ) ) {
|
||||
in.bump_in_this_line();
|
||||
if( c == '0' ) {
|
||||
return in.empty() || ( !is_digit( in.peek_char() ) );
|
||||
}
|
||||
while( ( !in.empty() ) && is_digit( in.peek_char() ) ) {
|
||||
in.bump_in_this_line();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template< typename ParseInput,
|
||||
typename Unsigned,
|
||||
Unsigned Maximum = ( std::numeric_limits< Unsigned >::max )() >
|
||||
[[nodiscard]] bool match_and_convert_unsigned_with_maximum_throws( ParseInput& in, Unsigned& st )
|
||||
{
|
||||
// Assumes st == 0.
|
||||
|
||||
if( !in.empty() ) {
|
||||
char c = in.peek_char();
|
||||
if( is_digit( c ) ) {
|
||||
if( c == '0' ) {
|
||||
in.bump_in_this_line();
|
||||
return in.empty() || ( !is_digit( in.peek_char() ) );
|
||||
}
|
||||
do {
|
||||
if( !accumulate_digit< Unsigned, Maximum >( st, c ) ) {
|
||||
throw TAO_PEGTL_NAMESPACE::parse_error( "integer overflow", in );
|
||||
}
|
||||
in.bump_in_this_line();
|
||||
} while( ( !in.empty() ) && is_digit( c = in.peek_char() ) );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template< typename ParseInput,
|
||||
typename Unsigned,
|
||||
Unsigned Maximum = ( std::numeric_limits< Unsigned >::max )() >
|
||||
[[nodiscard]] bool match_and_convert_unsigned_with_maximum_nothrow( ParseInput& in, Unsigned& st )
|
||||
{
|
||||
// Assumes st == 0.
|
||||
|
||||
if( !in.empty() ) {
|
||||
char c = in.peek_char();
|
||||
if( c == '0' ) {
|
||||
if( ( in.size( 2 ) < 2 ) || ( !is_digit( in.peek_char( 1 ) ) ) ) {
|
||||
in.bump_in_this_line();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if( is_digit( c ) ) {
|
||||
unsigned b = 0;
|
||||
|
||||
do {
|
||||
if( !accumulate_digit< Unsigned, Maximum >( st, c ) ) {
|
||||
return false;
|
||||
}
|
||||
++b;
|
||||
} while( ( !in.empty() ) && is_digit( c = in.peek_char( b ) ) );
|
||||
in.bump_in_this_line( b );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
struct unsigned_action
|
||||
{
|
||||
// Assumes that 'in' contains a non-empty sequence of ASCII digits.
|
||||
|
||||
template< typename ActionInput, typename Unsigned >
|
||||
static void apply( const ActionInput& in, Unsigned& st )
|
||||
{
|
||||
// This function "only" offers basic exception safety.
|
||||
st = 0;
|
||||
if( !internal::convert_unsigned( st, in.string_view() ) ) {
|
||||
throw parse_error( "unsigned integer overflow", in );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct unsigned_rule
|
||||
{
|
||||
using rule_t = unsigned_rule;
|
||||
using subs_t = empty_list;
|
||||
|
||||
template< typename ParseInput >
|
||||
[[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( in.empty() ) )
|
||||
{
|
||||
return internal::match_unsigned( in ); // Does not check for any overflow.
|
||||
}
|
||||
};
|
||||
|
||||
struct unsigned_rule_with_action
|
||||
{
|
||||
using rule_t = unsigned_rule_with_action;
|
||||
using subs_t = empty_list;
|
||||
|
||||
template< apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static auto match( ParseInput& in, States&&... /*unused*/ ) noexcept( noexcept( in.empty() ) ) -> std::enable_if_t< A == apply_mode::nothing, bool >
|
||||
{
|
||||
return internal::match_unsigned( in ); // Does not check for any overflow.
|
||||
}
|
||||
|
||||
template< apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename Unsigned >
|
||||
[[nodiscard]] static auto match( ParseInput& in, Unsigned& st ) -> std::enable_if_t< ( A == apply_mode::action ) && std::is_unsigned_v< Unsigned >, bool >
|
||||
{
|
||||
// This function "only" offers basic exception safety.
|
||||
st = 0;
|
||||
return internal::match_and_convert_unsigned_with_maximum_throws( in, st ); // Throws on overflow.
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Unsigned, Unsigned Maximum >
|
||||
struct maximum_action
|
||||
{
|
||||
// Assumes that 'in' contains a non-empty sequence of ASCII digits.
|
||||
|
||||
static_assert( std::is_unsigned_v< Unsigned > );
|
||||
|
||||
template< typename ActionInput, typename Unsigned2 >
|
||||
static void apply( const ActionInput& in, Unsigned2& st )
|
||||
{
|
||||
// This function "only" offers basic exception safety.
|
||||
st = 0;
|
||||
if( !internal::convert_unsigned< Unsigned, Maximum >( st, in.string_view() ) ) {
|
||||
throw parse_error( "unsigned integer overflow", in );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Unsigned, Unsigned Maximum = ( std::numeric_limits< Unsigned >::max )() >
|
||||
struct maximum_rule
|
||||
{
|
||||
using rule_t = maximum_rule;
|
||||
using subs_t = empty_list;
|
||||
|
||||
static_assert( std::is_unsigned_v< Unsigned > );
|
||||
|
||||
template< typename ParseInput >
|
||||
[[nodiscard]] static bool match( ParseInput& in )
|
||||
{
|
||||
Unsigned st = 0;
|
||||
return internal::match_and_convert_unsigned_with_maximum_nothrow< ParseInput, Unsigned, Maximum >( in, st );
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Unsigned, Unsigned Maximum = ( std::numeric_limits< Unsigned >::max )() >
|
||||
struct maximum_rule_with_action
|
||||
{
|
||||
using rule_t = maximum_rule_with_action;
|
||||
using subs_t = empty_list;
|
||||
|
||||
static_assert( std::is_unsigned_v< Unsigned > );
|
||||
|
||||
template< apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static auto match( ParseInput& in, States&&... /*unused*/ ) -> std::enable_if_t< A == apply_mode::nothing, bool >
|
||||
{
|
||||
Unsigned st = 0;
|
||||
return internal::match_and_convert_unsigned_with_maximum_throws< ParseInput, Unsigned, Maximum >( in, st );
|
||||
}
|
||||
|
||||
template< apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename Unsigned2 >
|
||||
[[nodiscard]] static auto match( ParseInput& in, Unsigned2& st ) -> std::enable_if_t< ( A == apply_mode::action ) && std::is_same_v< Unsigned, Unsigned2 >, bool >
|
||||
{
|
||||
// This function "only" offers basic exception safety.
|
||||
st = 0;
|
||||
return internal::match_and_convert_unsigned_with_maximum_throws< ParseInput, Unsigned, Maximum >( in, st );
|
||||
}
|
||||
};
|
||||
|
||||
struct signed_action
|
||||
{
|
||||
// Assumes that 'in' contains a non-empty sequence of ASCII digits,
|
||||
// with optional leading sign; with sign, in.size() must be >= 2.
|
||||
|
||||
template< typename ActionInput, typename Signed >
|
||||
static void apply( const ActionInput& in, Signed& st )
|
||||
{
|
||||
// This function "only" offers basic exception safety.
|
||||
st = 0;
|
||||
if( !internal::convert_signed( st, in.string_view() ) ) {
|
||||
throw parse_error( "signed integer overflow", in );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct signed_rule
|
||||
{
|
||||
using rule_t = signed_rule;
|
||||
using subs_t = empty_list;
|
||||
|
||||
template< typename ParseInput >
|
||||
[[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( in.empty() ) )
|
||||
{
|
||||
return TAO_PEGTL_NAMESPACE::parse< signed_rule_new >( in ); // Does not check for any overflow.
|
||||
}
|
||||
};
|
||||
|
||||
namespace internal
|
||||
{
|
||||
template< typename Rule >
|
||||
struct signed_action_action
|
||||
: nothing< Rule >
|
||||
{};
|
||||
|
||||
template<>
|
||||
struct signed_action_action< signed_rule_new >
|
||||
: signed_action
|
||||
{};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
struct signed_rule_with_action
|
||||
{
|
||||
using rule_t = signed_rule_with_action;
|
||||
using subs_t = empty_list;
|
||||
|
||||
template< apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static auto match( ParseInput& in, States&&... /*unused*/ ) noexcept( noexcept( in.empty() ) ) -> std::enable_if_t< A == apply_mode::nothing, bool >
|
||||
{
|
||||
return TAO_PEGTL_NAMESPACE::parse< signed_rule_new >( in ); // Does not check for any overflow.
|
||||
}
|
||||
|
||||
template< apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename Signed >
|
||||
[[nodiscard]] static auto match( ParseInput& in, Signed& st ) -> std::enable_if_t< ( A == apply_mode::action ) && std::is_signed_v< Signed >, bool >
|
||||
{
|
||||
return TAO_PEGTL_NAMESPACE::parse< signed_rule_new, internal::signed_action_action >( in, st ); // Throws on overflow.
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Name >
|
||||
struct analyze_traits< Name, unsigned_rule >
|
||||
: analyze_any_traits<>
|
||||
{};
|
||||
|
||||
template< typename Name >
|
||||
struct analyze_traits< Name, unsigned_rule_with_action >
|
||||
: analyze_any_traits<>
|
||||
{};
|
||||
|
||||
template< typename Name, typename Integer, Integer Maximum >
|
||||
struct analyze_traits< Name, maximum_rule< Integer, Maximum > >
|
||||
: analyze_any_traits<>
|
||||
{};
|
||||
|
||||
template< typename Name, typename Integer, Integer Maximum >
|
||||
struct analyze_traits< Name, maximum_rule_with_action< Integer, Maximum > >
|
||||
: analyze_any_traits<>
|
||||
{};
|
||||
|
||||
template< typename Name >
|
||||
struct analyze_traits< Name, signed_rule >
|
||||
: analyze_any_traits<>
|
||||
{};
|
||||
|
||||
template< typename Name >
|
||||
struct analyze_traits< Name, signed_rule_with_action >
|
||||
: analyze_any_traits<>
|
||||
{};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,78 @@
|
|||
// Copyright (c) 2017-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_INTERNAL_ENDIAN_HPP
|
||||
#define TAO_PEGTL_CONTRIB_INTERNAL_ENDIAN_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
#include "../../config.hpp"
|
||||
|
||||
#if defined( _WIN32 ) && !defined( __MINGW32__ ) && !defined( __CYGWIN__ )
|
||||
#include "endian_win.hpp"
|
||||
#else
|
||||
#include "endian_gcc.hpp"
|
||||
#endif
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
enum class endian
|
||||
{
|
||||
#if defined( _WIN32 )
|
||||
little = 0,
|
||||
big = 1,
|
||||
native = little
|
||||
#elif defined( __BYTE_ORDER__ )
|
||||
little = __ORDER_LITTLE_ENDIAN__,
|
||||
big = __ORDER_BIG_ENDIAN__,
|
||||
native = __BYTE_ORDER__
|
||||
#else
|
||||
#error Unknown endianness.
|
||||
#endif
|
||||
};
|
||||
|
||||
template< typename N >
|
||||
[[nodiscard]] N h_to_be( const N n ) noexcept
|
||||
{
|
||||
return N( to_and_from_be< sizeof( N ) >::convert( n ) );
|
||||
}
|
||||
|
||||
template< typename N >
|
||||
[[nodiscard]] N be_to_h( const N n ) noexcept
|
||||
{
|
||||
return h_to_be( n );
|
||||
}
|
||||
|
||||
template< typename N >
|
||||
[[nodiscard]] N be_to_h( const void* p ) noexcept
|
||||
{
|
||||
N n;
|
||||
std::memcpy( &n, p, sizeof( n ) );
|
||||
return internal::be_to_h( n );
|
||||
}
|
||||
|
||||
template< typename N >
|
||||
[[nodiscard]] N h_to_le( const N n ) noexcept
|
||||
{
|
||||
return N( to_and_from_le< sizeof( N ) >::convert( n ) );
|
||||
}
|
||||
|
||||
template< typename N >
|
||||
[[nodiscard]] N le_to_h( const N n ) noexcept
|
||||
{
|
||||
return h_to_le( n );
|
||||
}
|
||||
|
||||
template< typename N >
|
||||
[[nodiscard]] N le_to_h( const void* p ) noexcept
|
||||
{
|
||||
N n;
|
||||
std::memcpy( &n, p, sizeof( n ) );
|
||||
return internal::le_to_h( n );
|
||||
}
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,199 @@
|
|||
// Copyright (c) 2017-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_INTERNAL_ENDIAN_GCC_HPP
|
||||
#define TAO_PEGTL_CONTRIB_INTERNAL_ENDIAN_GCC_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
#if !defined( __BYTE_ORDER__ )
|
||||
#error No byte order defined!
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
|
||||
template< std::size_t S >
|
||||
struct to_and_from_be
|
||||
{
|
||||
template< typename T >
|
||||
[[nodiscard]] static T convert( const T n ) noexcept
|
||||
{
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
template< std::size_t S >
|
||||
struct to_and_from_le;
|
||||
|
||||
template<>
|
||||
struct to_and_from_le< 1 >
|
||||
{
|
||||
[[nodiscard]] static std::uint8_t convert( const std::uint8_t n ) noexcept
|
||||
{
|
||||
return n;
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::int8_t convert( const std::int8_t n ) noexcept
|
||||
{
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct to_and_from_le< 2 >
|
||||
{
|
||||
[[nodiscard]] static std::int16_t convert( const std::int16_t n ) noexcept
|
||||
{
|
||||
return static_cast< std::int16_t >( __builtin_bswap16( static_cast< std::uint16_t >( n ) ) );
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::uint16_t convert( const std::uint16_t n ) noexcept
|
||||
{
|
||||
return __builtin_bswap16( n );
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct to_and_from_le< 4 >
|
||||
{
|
||||
[[nodiscard]] static float convert( float n ) noexcept
|
||||
{
|
||||
std::uint32_t u;
|
||||
std::memcpy( &u, &n, 4 );
|
||||
u = convert( u );
|
||||
std::memcpy( &n, &u, 4 );
|
||||
return n;
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::int32_t convert( const std::int32_t n ) noexcept
|
||||
{
|
||||
return static_cast< std::int32_t >( __builtin_bswap32( static_cast< std::uint32_t >( n ) ) );
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::uint32_t convert( const std::uint32_t n ) noexcept
|
||||
{
|
||||
return __builtin_bswap32( n );
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct to_and_from_le< 8 >
|
||||
{
|
||||
[[nodiscard]] static double convert( double n ) noexcept
|
||||
{
|
||||
std::uint64_t u;
|
||||
std::memcpy( &u, &n, 8 );
|
||||
u = convert( u );
|
||||
std::memcpy( &n, &u, 8 );
|
||||
return n;
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::int64_t convert( const std::int64_t n ) noexcept
|
||||
{
|
||||
return static_cast< std::int64_t >( __builtin_bswap64( static_cast< std::uint64_t >( n ) ) );
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::uint64_t convert( const std::uint64_t n ) noexcept
|
||||
{
|
||||
return __builtin_bswap64( n );
|
||||
}
|
||||
};
|
||||
|
||||
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
|
||||
template< std::size_t S >
|
||||
struct to_and_from_le
|
||||
{
|
||||
template< typename T >
|
||||
[[nodiscard]] static T convert( const T n ) noexcept
|
||||
{
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
template< std::size_t S >
|
||||
struct to_and_from_be;
|
||||
|
||||
template<>
|
||||
struct to_and_from_be< 1 >
|
||||
{
|
||||
[[nodiscard]] static std::int8_t convert( const std::int8_t n ) noexcept
|
||||
{
|
||||
return n;
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::uint8_t convert( const std::uint8_t n ) noexcept
|
||||
{
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct to_and_from_be< 2 >
|
||||
{
|
||||
[[nodiscard]] static std::int16_t convert( const std::int16_t n ) noexcept
|
||||
{
|
||||
return static_cast< std::int16_t >( __builtin_bswap16( static_cast< std::uint16_t >( n ) ) );
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::uint16_t convert( const std::uint16_t n ) noexcept
|
||||
{
|
||||
return __builtin_bswap16( n );
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct to_and_from_be< 4 >
|
||||
{
|
||||
[[nodiscard]] static float convert( float n ) noexcept
|
||||
{
|
||||
std::uint32_t u;
|
||||
std::memcpy( &u, &n, 4 );
|
||||
u = convert( u );
|
||||
std::memcpy( &n, &u, 4 );
|
||||
return n;
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::int32_t convert( const std::int32_t n ) noexcept
|
||||
{
|
||||
return static_cast< std::int32_t >( __builtin_bswap32( static_cast< std::uint32_t >( n ) ) );
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::uint32_t convert( const std::uint32_t n ) noexcept
|
||||
{
|
||||
return __builtin_bswap32( n );
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct to_and_from_be< 8 >
|
||||
{
|
||||
[[nodiscard]] static double convert( double n ) noexcept
|
||||
{
|
||||
std::uint64_t u;
|
||||
std::memcpy( &u, &n, 8 );
|
||||
u = convert( u );
|
||||
std::memcpy( &n, &u, 8 );
|
||||
return n;
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::int64_t convert( const std::int64_t n ) noexcept
|
||||
{
|
||||
return static_cast< std::int64_t >( __builtin_bswap64( static_cast< std::uint64_t >( n ) ) );
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::uint64_t convert( const std::uint64_t n ) noexcept
|
||||
{
|
||||
return __builtin_bswap64( n );
|
||||
}
|
||||
};
|
||||
|
||||
#else
|
||||
#error Unknown host byte order!
|
||||
#endif
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,103 @@
|
|||
// Copyright (c) 2017-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_INTERNAL_ENDIAN_WIN_HPP
|
||||
#define TAO_PEGTL_CONTRIB_INTERNAL_ENDIAN_WIN_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
template< std::size_t S >
|
||||
struct to_and_from_le
|
||||
{
|
||||
template< typename T >
|
||||
[[nodiscard]] static T convert( const T t ) noexcept
|
||||
{
|
||||
return t;
|
||||
}
|
||||
};
|
||||
|
||||
template< std::size_t S >
|
||||
struct to_and_from_be;
|
||||
|
||||
template<>
|
||||
struct to_and_from_be< 1 >
|
||||
{
|
||||
[[nodiscard]] static std::int8_t convert( const std::int8_t n ) noexcept
|
||||
{
|
||||
return n;
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::uint8_t convert( const std::uint8_t n ) noexcept
|
||||
{
|
||||
return n;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct to_and_from_be< 2 >
|
||||
{
|
||||
[[nodiscard]] static std::int16_t convert( const std::int16_t n ) noexcept
|
||||
{
|
||||
return std::int16_t( _byteswap_ushort( std::uint16_t( n ) ) );
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::uint16_t convert( const std::uint16_t n ) noexcept
|
||||
{
|
||||
return _byteswap_ushort( n );
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct to_and_from_be< 4 >
|
||||
{
|
||||
[[nodiscard]] static float convert( float n ) noexcept
|
||||
{
|
||||
std::uint32_t u;
|
||||
std::memcpy( &u, &n, 4 );
|
||||
u = convert( u );
|
||||
std::memcpy( &n, &u, 4 );
|
||||
return n;
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::int32_t convert( const std::int32_t n ) noexcept
|
||||
{
|
||||
return std::int32_t( _byteswap_ulong( std::uint32_t( n ) ) );
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::uint32_t convert( const std::uint32_t n ) noexcept
|
||||
{
|
||||
return _byteswap_ulong( n );
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct to_and_from_be< 8 >
|
||||
{
|
||||
[[nodiscard]] static double convert( double n ) noexcept
|
||||
{
|
||||
std::uint64_t u;
|
||||
std::memcpy( &u, &n, 8 );
|
||||
u = convert( u );
|
||||
std::memcpy( &n, &u, 8 );
|
||||
return n;
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::int64_t convert( const std::int64_t n ) noexcept
|
||||
{
|
||||
return std::int64_t( _byteswap_uint64( std::uint64_t( n ) ) );
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::uint64_t convert( const std::uint64_t n ) noexcept
|
||||
{
|
||||
return _byteswap_uint64( n );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,55 @@
|
|||
// Copyright (c) 2018-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_INTERNAL_PEEK_MASK_UINT_HPP
|
||||
#define TAO_PEGTL_CONTRIB_INTERNAL_PEEK_MASK_UINT_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#include "../../config.hpp"
|
||||
#include "../../internal/input_pair.hpp"
|
||||
|
||||
#include "read_uint.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
template< typename R, typename R::type M >
|
||||
struct peek_mask_uint_impl
|
||||
{
|
||||
using data_t = typename R::type;
|
||||
using pair_t = input_pair< data_t >;
|
||||
|
||||
template< typename ParseInput >
|
||||
[[nodiscard]] static pair_t peek( ParseInput& in ) noexcept( noexcept( in.size( sizeof( data_t ) ) ) )
|
||||
{
|
||||
if( in.size( sizeof( data_t ) ) < sizeof( data_t ) ) {
|
||||
return { 0, 0 };
|
||||
}
|
||||
const data_t data = R::read( in.current() ) & M;
|
||||
return { data, sizeof( data_t ) };
|
||||
}
|
||||
};
|
||||
|
||||
template< std::uint16_t M >
|
||||
using peek_mask_uint16_be = peek_mask_uint_impl< read_uint16_be, M >;
|
||||
|
||||
template< std::uint16_t M >
|
||||
using peek_mask_uint16_le = peek_mask_uint_impl< read_uint16_le, M >;
|
||||
|
||||
template< std::uint32_t M >
|
||||
using peek_mask_uint32_be = peek_mask_uint_impl< read_uint32_be, M >;
|
||||
|
||||
template< std::uint32_t M >
|
||||
using peek_mask_uint32_le = peek_mask_uint_impl< read_uint32_le, M >;
|
||||
|
||||
template< std::uint64_t M >
|
||||
using peek_mask_uint64_be = peek_mask_uint_impl< read_uint64_be, M >;
|
||||
|
||||
template< std::uint64_t M >
|
||||
using peek_mask_uint64_le = peek_mask_uint_impl< read_uint64_le, M >;
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) 2018-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_INTERNAL_PEEK_MASK_UINT8_HPP
|
||||
#define TAO_PEGTL_CONTRIB_INTERNAL_PEEK_MASK_UINT8_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#include "../../config.hpp"
|
||||
#include "../../internal/input_pair.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
template< std::uint8_t M >
|
||||
struct peek_mask_uint8
|
||||
{
|
||||
using data_t = std::uint8_t;
|
||||
using pair_t = input_pair< std::uint8_t >;
|
||||
|
||||
template< typename ParseInput >
|
||||
[[nodiscard]] static pair_t peek( ParseInput& in ) noexcept( noexcept( in.empty() ) )
|
||||
{
|
||||
if( in.empty() ) {
|
||||
return { 0, 0 };
|
||||
}
|
||||
return { std::uint8_t( in.peek_uint8() & M ), 1 };
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright (c) 2018-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_INTERNAL_PEEK_UINT_HPP
|
||||
#define TAO_PEGTL_CONTRIB_INTERNAL_PEEK_UINT_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#include "../../config.hpp"
|
||||
#include "../../internal/input_pair.hpp"
|
||||
|
||||
#include "read_uint.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
template< typename R >
|
||||
struct peek_uint_impl
|
||||
{
|
||||
using data_t = typename R::type;
|
||||
using pair_t = input_pair< data_t >;
|
||||
|
||||
template< typename ParseInput >
|
||||
[[nodiscard]] static pair_t peek( ParseInput& in ) noexcept( noexcept( in.size( sizeof( data_t ) ) ) )
|
||||
{
|
||||
if( in.size( sizeof( data_t ) ) < sizeof( data_t ) ) {
|
||||
return { 0, 0 };
|
||||
}
|
||||
const data_t data = R::read( in.current() );
|
||||
return { data, sizeof( data_t ) };
|
||||
}
|
||||
};
|
||||
|
||||
using peek_uint16_be = peek_uint_impl< read_uint16_be >;
|
||||
using peek_uint16_le = peek_uint_impl< read_uint16_le >;
|
||||
|
||||
using peek_uint32_be = peek_uint_impl< read_uint32_be >;
|
||||
using peek_uint32_le = peek_uint_impl< read_uint32_le >;
|
||||
|
||||
using peek_uint64_be = peek_uint_impl< read_uint64_be >;
|
||||
using peek_uint64_le = peek_uint_impl< read_uint64_le >;
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) 2018-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_INTERNAL_PEEK_UINT8_HPP
|
||||
#define TAO_PEGTL_CONTRIB_INTERNAL_PEEK_UINT8_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#include "../../config.hpp"
|
||||
#include "../../internal/input_pair.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
struct peek_uint8
|
||||
{
|
||||
using data_t = std::uint8_t;
|
||||
using pair_t = input_pair< std::uint8_t >;
|
||||
|
||||
template< typename ParseInput >
|
||||
[[nodiscard]] static pair_t peek( ParseInput& in ) noexcept( noexcept( in.empty() ) )
|
||||
{
|
||||
if( in.empty() ) {
|
||||
return { 0, 0 };
|
||||
}
|
||||
return { in.peek_uint8(), 1 };
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,55 @@
|
|||
// Copyright (c) 2014-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_INTERNAL_PEEK_UTF16_HPP
|
||||
#define TAO_PEGTL_CONTRIB_INTERNAL_PEEK_UTF16_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "../../config.hpp"
|
||||
#include "../../internal/input_pair.hpp"
|
||||
|
||||
#include "read_uint.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
template< typename R >
|
||||
struct peek_utf16_impl
|
||||
{
|
||||
using data_t = char32_t;
|
||||
using pair_t = input_pair< char32_t >;
|
||||
|
||||
using short_t = std::make_unsigned< char16_t >::type;
|
||||
|
||||
static_assert( sizeof( short_t ) == 2 );
|
||||
static_assert( sizeof( char16_t ) == 2 );
|
||||
|
||||
template< typename ParseInput >
|
||||
[[nodiscard]] static pair_t peek( ParseInput& in ) noexcept( noexcept( in.size( 4 ) ) )
|
||||
{
|
||||
if( in.size( 2 ) < 2 ) {
|
||||
return { 0, 0 };
|
||||
}
|
||||
const char32_t t = R::read( in.current() );
|
||||
if( ( t < 0xd800 ) || ( t > 0xdfff ) ) {
|
||||
return { t, 2 };
|
||||
}
|
||||
if( ( t >= 0xdc00 ) || ( in.size( 4 ) < 4 ) ) {
|
||||
return { 0, 0 };
|
||||
}
|
||||
const char32_t u = R::read( in.current() + 2 );
|
||||
if( ( u >= 0xdc00 ) && ( u <= 0xdfff ) ) {
|
||||
const auto cp = ( ( ( t & 0x03ff ) << 10 ) | ( u & 0x03ff ) ) + 0x10000;
|
||||
return { cp, 4 };
|
||||
}
|
||||
return { 0, 0 };
|
||||
}
|
||||
};
|
||||
|
||||
using peek_utf16_be = peek_utf16_impl< read_uint16_be >;
|
||||
using peek_utf16_le = peek_utf16_impl< read_uint16_le >;
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright (c) 2014-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_INTERNAL_PEEK_UTF32_HPP
|
||||
#define TAO_PEGTL_CONTRIB_INTERNAL_PEEK_UTF32_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include "../../config.hpp"
|
||||
#include "../../internal/input_pair.hpp"
|
||||
|
||||
#include "read_uint.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
template< typename R >
|
||||
struct peek_utf32_impl
|
||||
{
|
||||
using data_t = char32_t;
|
||||
using pair_t = input_pair< char32_t >;
|
||||
|
||||
static_assert( sizeof( char32_t ) == 4 );
|
||||
|
||||
template< typename ParseInput >
|
||||
[[nodiscard]] static pair_t peek( ParseInput& in ) noexcept( noexcept( in.size( 4 ) ) )
|
||||
{
|
||||
if( in.size( 4 ) < 4 ) {
|
||||
return { 0, 0 };
|
||||
}
|
||||
const char32_t t = R::read( in.current() );
|
||||
if( ( t <= 0x10ffff ) && !( t >= 0xd800 && t <= 0xdfff ) ) {
|
||||
return { t, 4 };
|
||||
}
|
||||
return { 0, 0 };
|
||||
}
|
||||
};
|
||||
|
||||
using peek_utf32_be = peek_utf32_impl< read_uint32_be >;
|
||||
using peek_utf32_le = peek_utf32_impl< read_uint32_le >;
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,78 @@
|
|||
// Copyright (c) 2018-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_INTERNAL_READ_UINT_HPP
|
||||
#define TAO_PEGTL_CONTRIB_INTERNAL_READ_UINT_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "../../config.hpp"
|
||||
|
||||
#include "endian.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
struct read_uint16_be
|
||||
{
|
||||
using type = std::uint16_t;
|
||||
|
||||
[[nodiscard]] static std::uint16_t read( const void* d ) noexcept
|
||||
{
|
||||
return be_to_h< std::uint16_t >( d );
|
||||
}
|
||||
};
|
||||
|
||||
struct read_uint16_le
|
||||
{
|
||||
using type = std::uint16_t;
|
||||
|
||||
[[nodiscard]] static std::uint16_t read( const void* d ) noexcept
|
||||
{
|
||||
return le_to_h< std::uint16_t >( d );
|
||||
}
|
||||
};
|
||||
|
||||
struct read_uint32_be
|
||||
{
|
||||
using type = std::uint32_t;
|
||||
|
||||
[[nodiscard]] static std::uint32_t read( const void* d ) noexcept
|
||||
{
|
||||
return be_to_h< std::uint32_t >( d );
|
||||
}
|
||||
};
|
||||
|
||||
struct read_uint32_le
|
||||
{
|
||||
using type = std::uint32_t;
|
||||
|
||||
[[nodiscard]] static std::uint32_t read( const void* d ) noexcept
|
||||
{
|
||||
return le_to_h< std::uint32_t >( d );
|
||||
}
|
||||
};
|
||||
|
||||
struct read_uint64_be
|
||||
{
|
||||
using type = std::uint64_t;
|
||||
|
||||
[[nodiscard]] static std::uint64_t read( const void* d ) noexcept
|
||||
{
|
||||
return be_to_h< std::uint64_t >( d );
|
||||
}
|
||||
};
|
||||
|
||||
struct read_uint64_le
|
||||
{
|
||||
using type = std::uint64_t;
|
||||
|
||||
[[nodiscard]] static std::uint64_t read( const void* d ) noexcept
|
||||
{
|
||||
return le_to_h< std::uint64_t >( d );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,53 @@
|
|||
// Copyright (c) 2020-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_INTERNAL_SET_STACK_GUARD_HPP
|
||||
#define TAO_PEGTL_CONTRIB_INTERNAL_SET_STACK_GUARD_HPP
|
||||
|
||||
#include <set>
|
||||
#include <utility>
|
||||
|
||||
#include "../../config.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
template< typename... Cs >
|
||||
class [[nodiscard]] set_stack_guard
|
||||
{
|
||||
public:
|
||||
template< typename... Ts >
|
||||
set_stack_guard( std::set< Cs... >& set, Ts&&... ts )
|
||||
: m_i( set.emplace( std::forward< Ts >( ts )... ) ),
|
||||
m_s( set )
|
||||
{}
|
||||
|
||||
set_stack_guard( set_stack_guard&& ) = delete;
|
||||
set_stack_guard( const set_stack_guard& ) = delete;
|
||||
|
||||
set_stack_guard& operator=( set_stack_guard&& ) = delete;
|
||||
set_stack_guard& operator=( const set_stack_guard& ) = delete;
|
||||
|
||||
~set_stack_guard()
|
||||
{
|
||||
if( m_i.second ) {
|
||||
m_s.erase( m_i.first );
|
||||
}
|
||||
}
|
||||
|
||||
explicit operator bool() const noexcept
|
||||
{
|
||||
return m_i.second;
|
||||
}
|
||||
|
||||
private:
|
||||
const std::pair< typename std::set< Cs... >::iterator, bool > m_i;
|
||||
std::set< Cs... >& m_s;
|
||||
};
|
||||
|
||||
template< typename... Cs >
|
||||
set_stack_guard( std::set< Cs... >&, const typename std::set< Cs... >::value_type& ) -> set_stack_guard< Cs... >;
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright (c) 2020-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_INTERNAL_VECTOR_STACK_GUARD_HPP
|
||||
#define TAO_PEGTL_CONTRIB_INTERNAL_VECTOR_STACK_GUARD_HPP
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "../../config.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
template< typename... Cs >
|
||||
class [[nodiscard]] vector_stack_guard
|
||||
{
|
||||
public:
|
||||
template< typename... Ts >
|
||||
vector_stack_guard( std::vector< Cs... >& vector, Ts&&... ts )
|
||||
: m_s( vector )
|
||||
{
|
||||
m_s.emplace_back( std::forward< Ts >( ts )... );
|
||||
}
|
||||
|
||||
vector_stack_guard( vector_stack_guard&& ) = delete;
|
||||
vector_stack_guard( const vector_stack_guard& ) = delete;
|
||||
|
||||
vector_stack_guard& operator=( vector_stack_guard&& ) = delete;
|
||||
vector_stack_guard& operator=( const vector_stack_guard& ) = delete;
|
||||
|
||||
~vector_stack_guard()
|
||||
{
|
||||
m_s.pop_back();
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector< Cs... >& m_s;
|
||||
};
|
||||
|
||||
template< typename... Cs >
|
||||
vector_stack_guard( std::vector< Cs... >&, const typename std::vector< Cs... >::value_type& ) -> vector_stack_guard< Cs... >;
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,107 @@
|
|||
// Copyright (c) 2021 Kelvin Hammond
|
||||
// Copyright (c) 2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_IRI_HPP
|
||||
#define TAO_PEGTL_CONTRIB_IRI_HPP
|
||||
|
||||
#if !defined( __cpp_exceptions )
|
||||
#error "Exception support required for tao/pegtl/contrib/iri.hpp"
|
||||
#else
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "../rules.hpp"
|
||||
#include "../utf8.hpp"
|
||||
|
||||
#include "abnf.hpp"
|
||||
#include "uri.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::iri
|
||||
{
|
||||
// IRI grammar according to RFC 3987.
|
||||
|
||||
// This grammar is a direct PEG translation of the original URI grammar.
|
||||
// It should be considered experimental -- in case of any issues, in particular
|
||||
// missing rules for attached actions, please contact the developers.
|
||||
|
||||
// Note that this grammar has multiple top-level rules.
|
||||
|
||||
using uri::scheme;
|
||||
using uri::port;
|
||||
using uri::dslash;
|
||||
using uri::IP_literal;
|
||||
using uri::IPv4address;
|
||||
using uri::pct_encoded;
|
||||
using uri::sub_delims;
|
||||
using uri::colon;
|
||||
|
||||
// clang-format off
|
||||
struct ucschar : utf8::ranges<
|
||||
0xA0, 0xD7FF,
|
||||
0xF900, 0xFDCF,
|
||||
0xFDF0, 0xFFEF,
|
||||
0x10000, 0x1FFFD,
|
||||
0x20000, 0x2FFFD,
|
||||
0x30000, 0x3FFFD,
|
||||
0x40000, 0x4FFFD,
|
||||
0x50000, 0x5FFFD,
|
||||
0x60000, 0x6FFFD,
|
||||
0x70000, 0x7FFFD,
|
||||
0x80000, 0x8FFFD,
|
||||
0x90000, 0x9FFFD,
|
||||
0xA0000, 0xAFFFD,
|
||||
0xB0000, 0xBFFFD,
|
||||
0xC0000, 0xCFFFD,
|
||||
0xD0000, 0xDFFFD,
|
||||
0xE1000, 0xEFFFD > {};
|
||||
|
||||
struct iprivate : utf8::ranges< 0xE000, 0xF8FF, 0xF0000, 0xFFFFD, 0x100000, 0x10FFFD > {};
|
||||
|
||||
struct iunreserved : sor< abnf::ALPHA, abnf::DIGIT, one< '-', '.', '_', '~' >, ucschar > {};
|
||||
|
||||
struct ipchar : sor< iunreserved, pct_encoded, sub_delims, one< ':', '@' > > {};
|
||||
|
||||
struct isegment : star< ipchar > {};
|
||||
struct isegment_nz : plus< ipchar > {};
|
||||
// non-zero-length segment without any colon ":"
|
||||
struct isegment_nz_nc : plus< sor< iunreserved, pct_encoded, sub_delims, one< '@' > > > {};
|
||||
|
||||
struct ipath_abempty : star< one< '/' >, isegment > {};
|
||||
struct ipath_absolute : seq< one< '/' >, opt< isegment_nz, star< one< '/' >, isegment > > > {};
|
||||
struct ipath_noscheme : seq< isegment_nz_nc, star< one< '/' >, isegment > > {};
|
||||
struct ipath_rootless : seq< isegment_nz, star< one< '/' >, isegment > > {};
|
||||
struct ipath_empty : success {};
|
||||
|
||||
struct ipath : sor< ipath_noscheme, // begins with a non-colon segment
|
||||
ipath_rootless, // begins with a segment
|
||||
ipath_absolute, // begins with "/" but not "//"
|
||||
ipath_abempty > // begins with "/" or is empty
|
||||
{};
|
||||
|
||||
struct ireg_name : star< sor< iunreserved, pct_encoded, sub_delims > > {};
|
||||
|
||||
struct ihost : sor< IP_literal, IPv4address, ireg_name > {};
|
||||
struct iuserinfo : star< sor< iunreserved, pct_encoded, sub_delims, colon > > {};
|
||||
struct opt_iuserinfo : opt< iuserinfo, one< '@' > > {};
|
||||
struct iauthority : seq< opt_iuserinfo, ihost, opt< colon, port > > {};
|
||||
|
||||
struct iquery : star< sor< ipchar, iprivate, one< '/', '?' > > > {};
|
||||
struct ifragment : star< sor< ipchar, one< '/', '?' > > > {};
|
||||
|
||||
struct opt_iquery : opt_must< one< '?' >, iquery > {};
|
||||
struct opt_ifragment : opt_must< one< '#' >, ifragment > {};
|
||||
|
||||
struct ihier_part : sor< if_must< dslash, iauthority, ipath_abempty >, ipath_rootless, ipath_absolute, ipath_empty > {};
|
||||
struct irelative_part : sor< if_must< dslash, iauthority, ipath_abempty >, ipath_noscheme, ipath_absolute, ipath_empty > {};
|
||||
struct irelative_ref : seq< irelative_part, opt_iquery, opt_ifragment > {};
|
||||
|
||||
struct IRI : seq< scheme, one< ':' >, ihier_part, opt_iquery, opt_ifragment > {};
|
||||
struct IRI_reference : sor< IRI, irelative_ref > {};
|
||||
struct absolute_IRI : seq< scheme, one< ':' >, ihier_part, opt_iquery > {};
|
||||
// clang-format off
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::iri
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,92 @@
|
|||
// Copyright (c) 2014-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_JSON_HPP
|
||||
#define TAO_PEGTL_CONTRIB_JSON_HPP
|
||||
|
||||
#include "../ascii.hpp"
|
||||
#include "../config.hpp"
|
||||
#include "../rules.hpp"
|
||||
#include "../utf8.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::json
|
||||
{
|
||||
// JSON grammar according to RFC 8259
|
||||
|
||||
// clang-format off
|
||||
struct ws : one< ' ', '\t', '\n', '\r' > {};
|
||||
|
||||
template< typename R, typename P = ws >
|
||||
struct padr : seq< R, star< P > > {};
|
||||
|
||||
struct begin_array : padr< one< '[' > > {};
|
||||
struct begin_object : padr< one< '{' > > {};
|
||||
struct end_array : one< ']' > {};
|
||||
struct end_object : one< '}' > {};
|
||||
struct name_separator : pad< one< ':' >, ws > {};
|
||||
struct value_separator : padr< one< ',' > > {};
|
||||
|
||||
struct false_ : string< 'f', 'a', 'l', 's', 'e' > {}; // NOLINT(readability-identifier-naming)
|
||||
struct null : string< 'n', 'u', 'l', 'l' > {};
|
||||
struct true_ : string< 't', 'r', 'u', 'e' > {}; // NOLINT(readability-identifier-naming)
|
||||
|
||||
struct digits : plus< digit > {};
|
||||
struct exp : seq< one< 'e', 'E' >, opt< one< '-', '+'> >, digits > {};
|
||||
struct frac : seq< one< '.' >, digits > {};
|
||||
struct int_ : sor< one< '0' >, plus< digit > > {}; // NOLINT(readability-identifier-naming)
|
||||
struct number : seq< opt< one< '-' > >, int_, opt< frac >, opt< exp > > {};
|
||||
|
||||
struct xdigit : TAO_PEGTL_NAMESPACE::xdigit {};
|
||||
struct unicode : list< seq< one< 'u' >, rep< 4, xdigit > >, one< '\\' > > {};
|
||||
struct escaped_char : one< '"', '\\', '/', 'b', 'f', 'n', 'r', 't' > {};
|
||||
struct escaped : sor< escaped_char, unicode > {};
|
||||
struct unescaped : utf8::range< 0x20, 0x10FFFF > {};
|
||||
struct char_ : if_then_else< one< '\\' >, escaped, unescaped > {}; // NOLINT(readability-identifier-naming)
|
||||
|
||||
struct string_content : until< at< one< '"' > >, char_ > {};
|
||||
struct string : seq< one< '"' >, string_content, any >
|
||||
{
|
||||
using content = string_content;
|
||||
};
|
||||
|
||||
struct key_content : until< at< one< '"' > >, char_ > {};
|
||||
struct key : seq< one< '"' >, key_content, any >
|
||||
{
|
||||
using content = key_content;
|
||||
};
|
||||
|
||||
struct value;
|
||||
|
||||
struct array_element;
|
||||
struct next_array_element : seq< array_element > {};
|
||||
struct array_content : opt< array_element, star< value_separator, next_array_element > > {};
|
||||
struct array : seq< begin_array, array_content, end_array >
|
||||
{
|
||||
using begin = begin_array;
|
||||
using end = end_array;
|
||||
using element = array_element;
|
||||
using content = array_content;
|
||||
};
|
||||
|
||||
struct member_value : padr< value > {};
|
||||
struct member : seq< key, name_separator, member_value > {};
|
||||
struct next_member : seq< member > {};
|
||||
struct object_content : opt< member, star< value_separator, next_member > > {};
|
||||
struct object : seq< begin_object, object_content, end_object >
|
||||
{
|
||||
using begin = begin_object;
|
||||
using end = end_object;
|
||||
using element = member;
|
||||
using content = object_content;
|
||||
};
|
||||
|
||||
struct value : sor< string, number, object, array, false_, true_, null > {};
|
||||
struct array_element : padr< value > {};
|
||||
|
||||
struct text : pad< value, ws > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::json
|
||||
|
||||
#endif
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) 2019-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_JSON_POINTER_HPP
|
||||
#define TAO_PEGTL_CONTRIB_JSON_POINTER_HPP
|
||||
|
||||
#include "../ascii.hpp"
|
||||
#include "../config.hpp"
|
||||
#include "../rules.hpp"
|
||||
#include "../utf8.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::json_pointer
|
||||
{
|
||||
// JSON pointer grammar according to RFC 6901
|
||||
|
||||
// clang-format off
|
||||
struct unescaped : utf8::ranges< 0x0, 0x2E, 0x30, 0x7D, 0x7F, 0x10FFFF > {};
|
||||
struct escaped : seq< one< '~' >, one< '0', '1' > > {};
|
||||
|
||||
struct reference_token : star< sor< unescaped, escaped > > {};
|
||||
struct json_pointer : star< one< '/' >, reference_token > {};
|
||||
// clang-format on
|
||||
|
||||
// relative JSON pointer, see ...
|
||||
|
||||
// clang-format off
|
||||
struct non_negative_integer : sor< one< '0' >, plus< digit > > {};
|
||||
struct relative_json_pointer : seq< non_negative_integer, sor< one< '#' >, json_pointer > > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::json_pointer
|
||||
|
||||
#endif
|
|
@ -0,0 +1,91 @@
|
|||
// Copyright (c) 2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_LIMIT_BYTES_HPP
|
||||
#define TAO_PEGTL_CONTRIB_LIMIT_BYTES_HPP
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "../apply_mode.hpp"
|
||||
#include "../config.hpp"
|
||||
#include "../match.hpp"
|
||||
#include "../nothing.hpp"
|
||||
#include "../rewind_mode.hpp"
|
||||
|
||||
#if defined( __cpp_exceptions )
|
||||
#include "../parse_error.hpp"
|
||||
#else
|
||||
#include <cstdio>
|
||||
#include <exception>
|
||||
#endif
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
template< std::size_t Maximum, typename MemoryInput >
|
||||
struct [[nodiscard]] bytes_guard
|
||||
{
|
||||
MemoryInput& m_in;
|
||||
const char* m_end;
|
||||
|
||||
explicit bytes_guard( MemoryInput& in_in ) noexcept
|
||||
: m_in( in_in ),
|
||||
m_end( in_in.end() )
|
||||
{
|
||||
m_in.private_set_end( m_in.begin() + std::min( m_in.size(), Maximum ) );
|
||||
}
|
||||
|
||||
bytes_guard( bytes_guard&& ) = delete;
|
||||
bytes_guard( const bytes_guard& ) = delete;
|
||||
|
||||
~bytes_guard()
|
||||
{
|
||||
m_in.private_set_end( m_end );
|
||||
}
|
||||
|
||||
bytes_guard& operator=( bytes_guard&& ) = delete;
|
||||
bytes_guard& operator=( const bytes_guard& ) = delete;
|
||||
};
|
||||
|
||||
// C++17 does not allow for partial deduction guides.
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template< std::size_t Maximum >
|
||||
struct limit_bytes
|
||||
: maybe_nothing
|
||||
{
|
||||
static constexpr const char* error_message = "maximum allowed rule consumption reached";
|
||||
|
||||
template< typename Rule,
|
||||
apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, States&&... st )
|
||||
{
|
||||
internal::bytes_guard< Maximum, ParseInput > bg( in );
|
||||
if( TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, st... ) ) {
|
||||
if( in.empty() && ( bg.m_end != in.current() ) ) {
|
||||
#if defined( __cpp_exceptions )
|
||||
Control< limit_bytes >::raise( in );
|
||||
#else
|
||||
std::fputs( "maximum allowed rule consumption reached\n", stderr );
|
||||
std::terminate();
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,86 @@
|
|||
// Copyright (c) 2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_LIMIT_DEPTH_HPP
|
||||
#define TAO_PEGTL_CONTRIB_LIMIT_DEPTH_HPP
|
||||
|
||||
#include "../apply_mode.hpp"
|
||||
#include "../config.hpp"
|
||||
#include "../match.hpp"
|
||||
#include "../nothing.hpp"
|
||||
#include "../rewind_mode.hpp"
|
||||
|
||||
#if defined( __cpp_exceptions )
|
||||
#include "../parse_error.hpp"
|
||||
#else
|
||||
#include <cstdio>
|
||||
#include <exception>
|
||||
#endif
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
struct [[nodiscard]] depth_guard
|
||||
{
|
||||
std::size_t& m_depth;
|
||||
|
||||
explicit depth_guard( std::size_t& depth ) noexcept
|
||||
: m_depth( depth )
|
||||
{
|
||||
++m_depth;
|
||||
}
|
||||
|
||||
depth_guard( depth_guard&& ) = delete;
|
||||
depth_guard( const depth_guard& ) = delete;
|
||||
|
||||
~depth_guard()
|
||||
{
|
||||
--m_depth;
|
||||
}
|
||||
|
||||
depth_guard& operator=( depth_guard&& ) = delete;
|
||||
depth_guard& operator=( const depth_guard& ) = delete;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template< std::size_t Maximum >
|
||||
struct limit_depth
|
||||
: maybe_nothing
|
||||
{
|
||||
static constexpr const char* error_message = "maximum parser rule nesting depth exceeded";
|
||||
|
||||
template< typename Rule,
|
||||
apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, States&&... st )
|
||||
{
|
||||
if constexpr( Control< Rule >::enable ) {
|
||||
const internal::depth_guard dg( in.private_depth );
|
||||
if( in.private_depth > Maximum ) {
|
||||
#if defined( __cpp_exceptions )
|
||||
Control< limit_depth >::raise( in );
|
||||
#else
|
||||
std::fputs( "maximum parser rule nesting depth exceeded\n", stderr );
|
||||
std::terminate();
|
||||
#endif
|
||||
}
|
||||
return TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, st... );
|
||||
}
|
||||
else {
|
||||
return TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, st... );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,444 @@
|
|||
// Copyright (c) 2017-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_PARSE_TREE_HPP
|
||||
#define TAO_PEGTL_CONTRIB_PARSE_TREE_HPP
|
||||
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <typeindex>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "remove_first_state.hpp"
|
||||
#include "shuffle_states.hpp"
|
||||
|
||||
#include "../apply_mode.hpp"
|
||||
#include "../config.hpp"
|
||||
#include "../demangle.hpp"
|
||||
#include "../memory_input.hpp"
|
||||
#include "../normal.hpp"
|
||||
#include "../nothing.hpp"
|
||||
#include "../parse.hpp"
|
||||
#include "../rewind_mode.hpp"
|
||||
|
||||
#include "../internal/enable_control.hpp"
|
||||
#include "../internal/has_unwind.hpp"
|
||||
#include "../internal/iterator.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::parse_tree
|
||||
{
|
||||
template< typename T, typename Source = std::string_view >
|
||||
struct basic_node
|
||||
{
|
||||
using node_t = T;
|
||||
using children_t = std::vector< std::unique_ptr< node_t > >;
|
||||
children_t children;
|
||||
|
||||
std::string_view type;
|
||||
Source source;
|
||||
|
||||
TAO_PEGTL_NAMESPACE::internal::iterator m_begin;
|
||||
TAO_PEGTL_NAMESPACE::internal::iterator m_end;
|
||||
|
||||
// each node will be default constructed
|
||||
basic_node() = default;
|
||||
|
||||
// no copy/move is necessary
|
||||
// (nodes are always owned/handled by a std::unique_ptr)
|
||||
basic_node( const basic_node& ) = delete;
|
||||
basic_node( basic_node&& ) = delete;
|
||||
|
||||
~basic_node() = default;
|
||||
|
||||
// no assignment either
|
||||
basic_node& operator=( const basic_node& ) = delete;
|
||||
basic_node& operator=( basic_node&& ) = delete;
|
||||
|
||||
[[nodiscard]] bool is_root() const noexcept
|
||||
{
|
||||
return type.empty();
|
||||
}
|
||||
|
||||
template< typename U >
|
||||
[[nodiscard]] bool is_type() const noexcept
|
||||
{
|
||||
const auto u = demangle< U >();
|
||||
return ( ( type.data() == u.data() ) && ( type.size() == u.size() ) ) || ( type == u );
|
||||
}
|
||||
|
||||
template< typename U >
|
||||
void set_type() noexcept
|
||||
{
|
||||
type = demangle< U >();
|
||||
}
|
||||
|
||||
[[nodiscard]] position begin() const
|
||||
{
|
||||
return position( m_begin, source );
|
||||
}
|
||||
|
||||
[[nodiscard]] position end() const
|
||||
{
|
||||
return position( m_end, source );
|
||||
}
|
||||
|
||||
[[nodiscard]] bool has_content() const noexcept
|
||||
{
|
||||
return m_end.data != nullptr;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string_view string_view() const noexcept
|
||||
{
|
||||
assert( has_content() );
|
||||
return std::string_view( m_begin.data, m_end.data - m_begin.data );
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string string() const
|
||||
{
|
||||
assert( has_content() );
|
||||
return std::string( m_begin.data, m_end.data );
|
||||
}
|
||||
|
||||
template< tracking_mode P = tracking_mode::eager, typename Eol = eol::lf_crlf >
|
||||
[[nodiscard]] memory_input< P, Eol > as_memory_input() const
|
||||
{
|
||||
assert( has_content() );
|
||||
return { m_begin.data, m_end.data, source, m_begin.byte, m_begin.line, m_begin.column };
|
||||
}
|
||||
|
||||
template< typename... States >
|
||||
void remove_content( States&&... /*unused*/ ) noexcept
|
||||
{
|
||||
m_end = TAO_PEGTL_NAMESPACE::internal::iterator();
|
||||
}
|
||||
|
||||
// all non-root nodes are initialized by calling this method
|
||||
template< typename Rule, typename ParseInput, typename... States >
|
||||
void start( const ParseInput& in, States&&... /*unused*/ )
|
||||
{
|
||||
set_type< Rule >();
|
||||
source = in.source();
|
||||
m_begin = TAO_PEGTL_NAMESPACE::internal::iterator( in.iterator() );
|
||||
}
|
||||
|
||||
// if parsing of the rule succeeded, this method is called
|
||||
template< typename Rule, typename ParseInput, typename... States >
|
||||
void success( const ParseInput& in, States&&... /*unused*/ ) noexcept
|
||||
{
|
||||
m_end = TAO_PEGTL_NAMESPACE::internal::iterator( in.iterator() );
|
||||
}
|
||||
|
||||
// if parsing of the rule failed, this method is called
|
||||
template< typename Rule, typename ParseInput, typename... States >
|
||||
void failure( const ParseInput& /*unused*/, States&&... /*unused*/ ) noexcept
|
||||
{}
|
||||
|
||||
// if parsing of the rule failed with an exception, this method is called
|
||||
template< typename Rule, typename ParseInput, typename... States >
|
||||
void unwind( const ParseInput& /*unused*/, States&&... /*unused*/ ) noexcept
|
||||
{}
|
||||
|
||||
// if parsing succeeded and the (optional) transform call
|
||||
// did not discard the node, it is appended to its parent.
|
||||
// note that "child" is the node whose Rule just succeeded
|
||||
// and "*this" is the parent where the node should be appended.
|
||||
template< typename... States >
|
||||
void emplace_back( std::unique_ptr< node_t >&& child, States&&... /*unused*/ )
|
||||
{
|
||||
assert( child );
|
||||
children.emplace_back( std::move( child ) );
|
||||
}
|
||||
};
|
||||
|
||||
struct node
|
||||
: basic_node< node >
|
||||
{};
|
||||
|
||||
namespace internal
|
||||
{
|
||||
template< typename Node >
|
||||
struct state
|
||||
{
|
||||
std::vector< std::unique_ptr< Node > > stack;
|
||||
|
||||
state()
|
||||
{
|
||||
emplace_back();
|
||||
}
|
||||
|
||||
void emplace_back()
|
||||
{
|
||||
stack.emplace_back( std::make_unique< Node >() );
|
||||
}
|
||||
|
||||
[[nodiscard]] std::unique_ptr< Node >& back() noexcept
|
||||
{
|
||||
assert( !stack.empty() );
|
||||
return stack.back();
|
||||
}
|
||||
|
||||
void pop_back() noexcept
|
||||
{
|
||||
assert( !stack.empty() );
|
||||
return stack.pop_back();
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Selector, typename... Parameters >
|
||||
void transform( Parameters&&... /*unused*/ ) noexcept
|
||||
{}
|
||||
|
||||
template< typename Selector, typename ParseInput, typename Node, typename... States >
|
||||
auto transform( const ParseInput& in, std::unique_ptr< Node >& n, States&&... st ) noexcept( noexcept( Selector::transform( in, n, st... ) ) )
|
||||
-> decltype( (void)Selector::transform( in, n, st... ) )
|
||||
{
|
||||
Selector::transform( in, n, st... );
|
||||
}
|
||||
|
||||
template< typename Selector, typename ParseInput, typename Node, typename... States >
|
||||
auto transform( const ParseInput& /*unused*/, std::unique_ptr< Node >& n, States&&... st ) noexcept( noexcept( Selector::transform( n, st... ) ) )
|
||||
-> decltype( (void)Selector::transform( n, st... ) )
|
||||
{
|
||||
Selector::transform( n, st... );
|
||||
}
|
||||
|
||||
template< typename Rule, template< typename... > class Selector >
|
||||
inline constexpr bool is_selected_node = ( TAO_PEGTL_NAMESPACE::internal::enable_control< Rule > && Selector< Rule >::value );
|
||||
|
||||
template< unsigned Level, typename Subs, template< typename... > class Selector >
|
||||
inline constexpr bool is_leaf{};
|
||||
|
||||
template< typename... Rules, template< typename... > class Selector >
|
||||
inline constexpr bool is_leaf< 0, type_list< Rules... >, Selector > = ( sizeof...( Rules ) == 0 );
|
||||
|
||||
template< unsigned Level, typename Rule, template< typename... > class Selector >
|
||||
inline constexpr bool is_unselected_branch = ( !is_selected_node< Rule, Selector > && is_leaf< Level, typename Rule::subs_t, Selector > );
|
||||
|
||||
template< unsigned Level, typename... Rules, template< typename... > class Selector >
|
||||
inline constexpr bool is_leaf< Level, type_list< Rules... >, Selector > = ( is_unselected_branch< Level - 1, Rules, Selector > && ... );
|
||||
|
||||
template< typename Node, template< typename... > class Selector, template< typename... > class Control >
|
||||
struct make_control
|
||||
{
|
||||
template< typename Rule, bool, bool >
|
||||
struct state_handler;
|
||||
|
||||
template< typename Rule >
|
||||
using type = rotate_states_right< state_handler< Rule, is_selected_node< Rule, Selector >, is_leaf< 8, typename Rule::subs_t, Selector > > >;
|
||||
};
|
||||
|
||||
template< typename Node, template< typename... > class Selector, template< typename... > class Control >
|
||||
template< typename Rule >
|
||||
struct make_control< Node, Selector, Control >::state_handler< Rule, false, true >
|
||||
: remove_first_state< Control< Rule > >
|
||||
{};
|
||||
|
||||
template< typename Node, template< typename... > class Selector, template< typename... > class Control >
|
||||
template< typename Rule >
|
||||
struct make_control< Node, Selector, Control >::state_handler< Rule, false, false >
|
||||
: remove_first_state< Control< Rule > >
|
||||
{
|
||||
static constexpr bool enable = true;
|
||||
|
||||
template< typename ParseInput, typename... States >
|
||||
static void start( const ParseInput& /*unused*/, state< Node >& state, States&&... /*unused*/ )
|
||||
{
|
||||
state.emplace_back();
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename... States >
|
||||
static void success( const ParseInput& /*unused*/, state< Node >& state, States&&... /*unused*/ )
|
||||
{
|
||||
auto n = std::move( state.back() );
|
||||
state.pop_back();
|
||||
for( auto& c : n->children ) {
|
||||
state.back()->children.emplace_back( std::move( c ) );
|
||||
}
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename... States >
|
||||
static void failure( const ParseInput& /*unused*/, state< Node >& state, States&&... /*unused*/ )
|
||||
{
|
||||
state.pop_back();
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename... States >
|
||||
static void unwind( const ParseInput& /*unused*/, state< Node >& state, States&&... /*unused*/ )
|
||||
{
|
||||
state.pop_back();
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Node, template< typename... > class Selector, template< typename... > class Control >
|
||||
template< typename Rule, bool B >
|
||||
struct make_control< Node, Selector, Control >::state_handler< Rule, true, B >
|
||||
: remove_first_state< Control< Rule > >
|
||||
{
|
||||
template< typename ParseInput, typename... States >
|
||||
static void start( const ParseInput& in, state< Node >& state, States&&... st )
|
||||
{
|
||||
Control< Rule >::start( in, st... );
|
||||
state.emplace_back();
|
||||
state.back()->template start< Rule >( in, st... );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename... States >
|
||||
static void success( const ParseInput& in, state< Node >& state, States&&... st )
|
||||
{
|
||||
auto n = std::move( state.back() );
|
||||
state.pop_back();
|
||||
n->template success< Rule >( in, st... );
|
||||
transform< Selector< Rule > >( in, n, st... );
|
||||
if( n ) {
|
||||
state.back()->emplace_back( std::move( n ), st... );
|
||||
}
|
||||
Control< Rule >::success( in, st... );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename... States >
|
||||
static void failure( const ParseInput& in, state< Node >& state, States&&... st )
|
||||
{
|
||||
state.back()->template failure< Rule >( in, st... );
|
||||
state.pop_back();
|
||||
Control< Rule >::failure( in, st... );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename... States >
|
||||
static void unwind( const ParseInput& in, state< Node >& state, States&&... st )
|
||||
{
|
||||
state.back()->template unwind< Rule >( in, st... );
|
||||
state.pop_back();
|
||||
if constexpr( TAO_PEGTL_NAMESPACE::internal::has_unwind< Control< Rule >, void, const ParseInput&, States... > ) {
|
||||
Control< Rule >::unwind( in, st... );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template< typename >
|
||||
using store_all = std::true_type;
|
||||
|
||||
template< typename >
|
||||
struct selector;
|
||||
|
||||
template< typename T >
|
||||
struct selector< std::tuple< T > >
|
||||
{
|
||||
using type = typename T::type;
|
||||
};
|
||||
|
||||
template< typename... Ts >
|
||||
struct selector< std::tuple< Ts... > >
|
||||
{
|
||||
static_assert( sizeof...( Ts ) == 0, "multiple matches found" );
|
||||
using type = std::false_type;
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
using selector_t = typename selector< T >::type;
|
||||
|
||||
template< typename Rule, typename Collection >
|
||||
using select_tuple = std::conditional_t< Collection::template contains< Rule >, std::tuple< Collection >, std::tuple<> >;
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template< typename Rule, typename... Collections >
|
||||
using selector = internal::selector_t< decltype( std::tuple_cat( std::declval< internal::select_tuple< Rule, Collections > >()... ) ) >;
|
||||
|
||||
template< typename Base >
|
||||
struct apply
|
||||
: std::true_type
|
||||
{
|
||||
template< typename... Rules >
|
||||
struct on
|
||||
{
|
||||
using type = Base;
|
||||
|
||||
template< typename Rule >
|
||||
static constexpr bool contains = ( std::is_same_v< Rule, Rules > || ... );
|
||||
};
|
||||
};
|
||||
|
||||
struct store_content
|
||||
: apply< store_content >
|
||||
{};
|
||||
|
||||
// some nodes don't need to store their content
|
||||
struct remove_content
|
||||
: apply< remove_content >
|
||||
{
|
||||
template< typename Node, typename... States >
|
||||
static void transform( std::unique_ptr< Node >& n, States&&... st ) noexcept( noexcept( n->Node::remove_content( st... ) ) )
|
||||
{
|
||||
n->remove_content( st... );
|
||||
}
|
||||
};
|
||||
|
||||
// if a node has only one child, replace the node with its child, otherwise remove content
|
||||
struct fold_one
|
||||
: apply< fold_one >
|
||||
{
|
||||
template< typename Node, typename... States >
|
||||
static void transform( std::unique_ptr< Node >& n, States&&... st ) noexcept( noexcept( n->children.size(), n->Node::remove_content( st... ) ) )
|
||||
{
|
||||
if( n->children.size() == 1 ) {
|
||||
n = std::move( n->children.front() );
|
||||
}
|
||||
else {
|
||||
n->remove_content( st... );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// if a node has no children, discard the node, otherwise remove content
|
||||
struct discard_empty
|
||||
: apply< discard_empty >
|
||||
{
|
||||
template< typename Node, typename... States >
|
||||
static void transform( std::unique_ptr< Node >& n, States&&... st ) noexcept( noexcept( (void)n->children.empty(), n->Node::remove_content( st... ) ) )
|
||||
{
|
||||
if( n->children.empty() ) {
|
||||
n.reset();
|
||||
}
|
||||
else {
|
||||
n->remove_content( st... );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Rule,
|
||||
typename Node,
|
||||
template< typename... > class Selector = internal::store_all,
|
||||
template< typename... > class Action = nothing,
|
||||
template< typename... > class Control = normal,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] std::unique_ptr< Node > parse( ParseInput&& in, States&&... st )
|
||||
{
|
||||
internal::state< Node > state;
|
||||
if( !TAO_PEGTL_NAMESPACE::parse< Rule, Action, internal::make_control< Node, Selector, Control >::template type >( in, st..., state ) ) {
|
||||
return nullptr;
|
||||
}
|
||||
assert( state.stack.size() == 1 );
|
||||
return std::move( state.back() );
|
||||
}
|
||||
|
||||
template< typename Rule,
|
||||
template< typename... > class Selector = internal::store_all,
|
||||
template< typename... > class Action = nothing,
|
||||
template< typename... > class Control = normal,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] std::unique_ptr< node > parse( ParseInput&& in, States&&... st )
|
||||
{
|
||||
return parse< Rule, node, Selector, Action, Control >( in, st... );
|
||||
}
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::parse_tree
|
||||
|
||||
#endif
|
|
@ -0,0 +1,112 @@
|
|||
// Copyright (c) 2019-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_PARSE_TREE_TO_DOT_HPP
|
||||
#define TAO_PEGTL_CONTRIB_PARSE_TREE_TO_DOT_HPP
|
||||
|
||||
#include <cassert>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
#include "parse_tree.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::parse_tree
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
inline void escape( std::ostream& os, const std::string_view s )
|
||||
{
|
||||
static const char* h = "0123456789abcdef";
|
||||
|
||||
const char* p = s.data();
|
||||
const char* l = p;
|
||||
const char* const e = s.data() + s.size();
|
||||
while( p != e ) {
|
||||
const unsigned char c = *p;
|
||||
if( c == '\\' ) {
|
||||
os.write( l, p - l );
|
||||
l = ++p;
|
||||
os << "\\\\\\\\";
|
||||
}
|
||||
else if( c == '"' ) {
|
||||
os.write( l, p - l );
|
||||
l = ++p;
|
||||
os << "\\\\\\\"";
|
||||
}
|
||||
else if( c < 32 ) {
|
||||
os.write( l, p - l );
|
||||
l = ++p;
|
||||
switch( c ) {
|
||||
case '\a':
|
||||
os << "\\\\a";
|
||||
break;
|
||||
case '\b':
|
||||
os << "\\\\b";
|
||||
break;
|
||||
case '\f':
|
||||
os << "\\\\f";
|
||||
break;
|
||||
case '\n':
|
||||
os << "\\\\n";
|
||||
break;
|
||||
case '\r':
|
||||
os << "\\\\r";
|
||||
break;
|
||||
case '\t':
|
||||
os << "\\\\t";
|
||||
break;
|
||||
case '\v':
|
||||
os << "\\\\v";
|
||||
break;
|
||||
default:
|
||||
os << "\\\\u00" << h[ ( c & 0xf0 ) >> 4 ] << h[ c & 0x0f ];
|
||||
}
|
||||
}
|
||||
else if( c == 127 ) {
|
||||
os.write( l, p - l );
|
||||
l = ++p;
|
||||
os << "\\\\u007f";
|
||||
}
|
||||
else {
|
||||
++p;
|
||||
}
|
||||
}
|
||||
os.write( l, p - l );
|
||||
}
|
||||
|
||||
template< typename Node >
|
||||
void print_dot_node( std::ostream& os, const Node& n, const std::string_view s )
|
||||
{
|
||||
os << " x" << &n << " [ label=\"";
|
||||
escape( os, s );
|
||||
if( n.has_content() ) {
|
||||
os << "\\n\\\"";
|
||||
escape( os, n.string_view() );
|
||||
os << "\\\"";
|
||||
}
|
||||
os << "\" ]\n";
|
||||
if( !n.children.empty() ) {
|
||||
os << " x" << &n << " -> { ";
|
||||
for( auto& up : n.children ) {
|
||||
os << "x" << up.get() << ( ( up == n.children.back() ) ? " }\n" : ", " );
|
||||
}
|
||||
for( auto& up : n.children ) {
|
||||
print_dot_node( os, *up, up->type );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template< typename Node >
|
||||
void print_dot( std::ostream& os, const Node& n )
|
||||
{
|
||||
os << "digraph parse_tree\n{\n";
|
||||
internal::print_dot_node( os, n, n.is_root() ? "ROOT" : n.type );
|
||||
os << "}\n";
|
||||
}
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::parse_tree
|
||||
|
||||
#endif
|
|
@ -0,0 +1,127 @@
|
|||
// Copyright (c) 2020-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_PREDICATES_HPP
|
||||
#define TAO_PEGTL_CONTRIB_PREDICATES_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "../type_list.hpp"
|
||||
|
||||
#include "../internal/bump_help.hpp"
|
||||
#include "../internal/dependent_false.hpp"
|
||||
#include "../internal/enable_control.hpp"
|
||||
#include "../internal/failure.hpp"
|
||||
#include "../internal/peek_char.hpp"
|
||||
#include "../internal/peek_utf8.hpp"
|
||||
|
||||
#include "analyze_traits.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
template< typename Peek, typename... Ps >
|
||||
struct predicates_and_test
|
||||
{
|
||||
using peek_t = Peek;
|
||||
using data_t = typename Peek::data_t;
|
||||
|
||||
[[nodiscard]] static constexpr bool test( const data_t c ) noexcept
|
||||
{
|
||||
return ( Ps::test( c ) && ... ); // TODO: Static assert that Ps::peek_t is the same as peek_t?!
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Peek, typename P >
|
||||
struct predicate_not_test
|
||||
{
|
||||
using peek_t = Peek;
|
||||
using data_t = typename Peek::data_t;
|
||||
|
||||
[[nodiscard]] static constexpr bool test( const data_t c ) noexcept
|
||||
{
|
||||
return !P::test( c ); // TODO: Static assert that P::peek_t is the same as peek_t?!
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Peek, typename... Ps >
|
||||
struct predicates_or_test
|
||||
{
|
||||
using peek_t = Peek;
|
||||
using data_t = typename Peek::data_t;
|
||||
|
||||
[[nodiscard]] static constexpr bool test( const data_t c ) noexcept
|
||||
{
|
||||
return ( Ps::test( c ) || ... ); // TODO: Static assert that Ps::peek_t is the same as peek_t?!
|
||||
}
|
||||
};
|
||||
|
||||
template< template< typename, typename... > class Test, typename Peek, typename... Ps >
|
||||
struct predicates
|
||||
: private Test< Peek, Ps... >
|
||||
{
|
||||
using peek_t = Peek;
|
||||
using data_t = typename Peek::data_t;
|
||||
|
||||
using rule_t = predicates;
|
||||
using subs_t = empty_list;
|
||||
|
||||
using base_t = Test< Peek, Ps... >;
|
||||
using base_t::test;
|
||||
|
||||
template< int Eol >
|
||||
static constexpr bool can_match_eol = test( Eol );
|
||||
|
||||
template< typename ParseInput >
|
||||
[[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( Peek::peek( in ) ) )
|
||||
{
|
||||
if( const auto t = Peek::peek( in ) ) {
|
||||
if( test( t.data ) ) {
|
||||
bump_help< predicates >( in, t.size );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template< template< typename, typename... > class Test, typename Peek >
|
||||
struct predicates< Test, Peek >
|
||||
{
|
||||
static_assert( dependent_false< Peek >, "Empty predicate list is not allowed!" );
|
||||
};
|
||||
|
||||
template< template< typename, typename... > class Test, typename Peek, typename... Ps >
|
||||
inline constexpr bool enable_control< predicates< Test, Peek, Ps... > > = false;
|
||||
|
||||
} // namespace internal
|
||||
|
||||
inline namespace ascii
|
||||
{
|
||||
// clang-format off
|
||||
template< typename... Ps > struct predicates_and : internal::predicates< internal::predicates_and_test, internal::peek_char, Ps... > {};
|
||||
template< typename P > struct predicate_not : internal::predicates< internal::predicate_not_test, internal::peek_char, P > {};
|
||||
template< typename... Ps > struct predicates_or : internal::predicates< internal::predicates_or_test, internal::peek_char, Ps... > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace ascii
|
||||
|
||||
namespace utf8
|
||||
{
|
||||
// clang-format off
|
||||
template< typename... Ps > struct predicates_and : internal::predicates< internal::predicates_and_test, internal::peek_utf8, Ps... > {};
|
||||
template< typename P > struct predicate_not : internal::predicates< internal::predicate_not_test, internal::peek_utf8, P > {};
|
||||
template< typename... Ps > struct predicates_or : internal::predicates< internal::predicates_or_test, internal::peek_utf8, Ps... > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace utf8
|
||||
|
||||
template< typename Name, template< typename, typename... > class Test, typename Peek, typename... Ps >
|
||||
struct analyze_traits< Name, internal::predicates< Test, Peek, Ps... > >
|
||||
: analyze_any_traits<>
|
||||
{};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,76 @@
|
|||
// Copyright (c) 2020-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_PRINT_HPP
|
||||
#define TAO_PEGTL_CONTRIB_PRINT_HPP
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "../demangle.hpp"
|
||||
#include "../type_list.hpp"
|
||||
#include "../visit.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
template< typename Name >
|
||||
struct print_names
|
||||
{
|
||||
static void visit( std::ostream& os )
|
||||
{
|
||||
os << demangle< Name >() << '\n';
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Name >
|
||||
struct print_debug
|
||||
{
|
||||
static void visit( std::ostream& os )
|
||||
{
|
||||
const auto first = demangle< Name >();
|
||||
os << first << '\n';
|
||||
|
||||
const auto second = demangle< typename Name::rule_t >();
|
||||
if( first != second ) {
|
||||
os << " (aka) " << second << '\n';
|
||||
}
|
||||
|
||||
print_subs( os, typename Name::subs_t() );
|
||||
|
||||
os << '\n';
|
||||
}
|
||||
|
||||
private:
|
||||
template< typename... Rules >
|
||||
static void print_subs( std::ostream& os, type_list< Rules... > /*unused*/ )
|
||||
{
|
||||
( print_sub< Rules >( os ), ... );
|
||||
}
|
||||
|
||||
template< typename Rule >
|
||||
static void print_sub( std::ostream& os )
|
||||
{
|
||||
os << " (sub) " << demangle< Rule >() << '\n';
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template< typename Grammar >
|
||||
void print_names( std::ostream& os )
|
||||
{
|
||||
visit< Grammar, internal::print_names >( os );
|
||||
}
|
||||
|
||||
template< typename Grammar >
|
||||
void print_debug( std::ostream& os )
|
||||
{
|
||||
visit< Grammar, internal::print_debug >( os );
|
||||
}
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,54 @@
|
|||
// Copyright (c) 2020-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_PRINT_COVERAGE_HPP
|
||||
#define TAO_PEGTL_CONTRIB_PRINT_COVERAGE_HPP
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include "coverage.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
inline std::ostream& operator<<( std::ostream& os, const coverage_result& result )
|
||||
{
|
||||
os << "[\n";
|
||||
bool f = true;
|
||||
for( const auto& [ k, v ] : result ) {
|
||||
if( f ) {
|
||||
f = false;
|
||||
}
|
||||
else {
|
||||
os << ",\n";
|
||||
}
|
||||
os << " {\n"
|
||||
<< " \"rule\": \"" << k << "\",\n"
|
||||
<< " \"start\": " << v.start << ", \"success\": " << v.success << ", \"failure\": " << v.failure << ", \"unwind\": " << v.unwind << ", \"raise\": " << v.raise << ",\n";
|
||||
if( v.branches.empty() ) {
|
||||
os << " \"branches\": []\n";
|
||||
}
|
||||
else {
|
||||
os << " \"branches\": [\n";
|
||||
bool f2 = true;
|
||||
for( const auto& [ k2, v2 ] : v.branches ) {
|
||||
if( f2 ) {
|
||||
f2 = false;
|
||||
}
|
||||
else {
|
||||
os << ",\n";
|
||||
}
|
||||
os << " { \"branch\": \"" << k2 << "\", \"start\": " << v2.start << ", \"success\": " << v2.success << ", \"failure\": " << v2.failure << ", \"unwind\": " << v2.unwind << ", \"raise\": " << v2.raise << " }";
|
||||
}
|
||||
os << "\n ]\n";
|
||||
}
|
||||
os << " }";
|
||||
}
|
||||
os << "\n";
|
||||
os << "]\n";
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,143 @@
|
|||
// Copyright (c) 2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_PROTO3_HPP
|
||||
#define TAO_PEGTL_CONTRIB_PROTO3_HPP
|
||||
|
||||
#include "../ascii.hpp"
|
||||
#include "../config.hpp"
|
||||
#include "../rules.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::proto3
|
||||
{
|
||||
// protocol buffer v3
|
||||
// https://developers.google.com/protocol-buffers/docs/reference/proto3-spec
|
||||
|
||||
// clang-format off
|
||||
struct comment_sl : seq< two< '/' >, until< eolf > > {};
|
||||
struct comment_ml : if_must< string< '/', '*' >, until< string< '*', '/' > > > {};
|
||||
struct sp : sor< space, comment_sl, comment_ml > {};
|
||||
struct sps : star< sp > {};
|
||||
|
||||
struct comma : one< ',' > {};
|
||||
struct dot : one< '.' > {};
|
||||
struct equ : one< '=' > {};
|
||||
struct semi : one< ';' > {};
|
||||
|
||||
struct option;
|
||||
struct message;
|
||||
struct extend;
|
||||
|
||||
struct ident_first : ranges< 'a', 'z', 'A', 'Z' > {}; // NOTE: Yes, no '_'.
|
||||
struct ident_other : ranges< 'a', 'z', 'A', 'Z', '0', '9', '_' > {};
|
||||
struct ident : seq< ident_first, star< ident_other > > {};
|
||||
struct full_ident : list_must< ident, dot > {};
|
||||
|
||||
struct hex_lit : seq< one< '0' >, one< 'x', 'X' >, plus< xdigit > > {};
|
||||
struct oct_lit : seq< one< '0' >, plus< odigit > > {};
|
||||
struct dec_lit : seq< range< '1', '9' >, star< digit > > {};
|
||||
struct int_lit : sor< hex_lit, oct_lit, dec_lit > {};
|
||||
|
||||
struct sign : one< '+', '-' > {};
|
||||
struct exp : seq< one< 'E', 'e' >, opt< sign >, plus< digit > > {};
|
||||
struct float_lit : sor<
|
||||
seq< plus< digit >, dot, exp >,
|
||||
seq< plus< digit >, dot, star< digit >, opt< exp > >,
|
||||
seq< dot, plus< digit >, opt< exp > >,
|
||||
keyword< 'i', 'n', 'f' >,
|
||||
keyword< 'n', 'a', 'n' > > {};
|
||||
|
||||
struct bool_lit : sor< keyword< 't', 'r', 'u', 'e' >,
|
||||
keyword< 'f', 'a', 'l', 's', 'e' > > {};
|
||||
|
||||
struct hex_escape : if_must< one< 'x', 'X' >, xdigit, xdigit > {};
|
||||
struct oct_escape : if_must< odigit, odigit, odigit > {};
|
||||
struct char_escape : one< 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', '\'', '"' > {};
|
||||
struct escape : if_must< one< '\\' >, hex_escape, oct_escape, char_escape > {};
|
||||
struct char_value : sor< escape, not_one< '\n', '\0' > > {}; // NOTE: No need to exclude '\' from not_one<>, see escape rule.
|
||||
template< char Q >
|
||||
struct str_impl : if_must< one< Q >, until< one< Q >, char_value > > {};
|
||||
struct str_lit : sor< str_impl< '\'' >, str_impl< '"' > > {};
|
||||
|
||||
struct constant : sor< bool_lit, seq< opt< sign >, float_lit >, seq< opt< sign >, int_lit >, str_lit, full_ident > {};
|
||||
|
||||
struct option_name : seq< sor< ident, if_must< one< '(' >, full_ident, one< ')' > > >, star_must< dot, ident > > {};
|
||||
struct option : if_must< keyword< 'o', 'p', 't', 'i', 'o', 'n' >, sps, option_name, sps, equ, sps, constant, sps, semi > {};
|
||||
|
||||
struct bool_type : keyword< 'b', 'o', 'o', 'l' > {};
|
||||
struct bytes_type : keyword< 'b', 'y', 't', 'e', 's' > {};
|
||||
struct double_type : keyword< 'd', 'o', 'u', 'b', 'l', 'e' > {};
|
||||
struct float_type : keyword< 'f', 'l', 'o', 'a', 't' > {};
|
||||
struct string_type : keyword< 's', 't', 'r', 'i', 'n', 'g' > {};
|
||||
|
||||
struct int32_type : keyword< 'i', 'n', 't', '3', '2' > {};
|
||||
struct int64_type : keyword< 'i', 'n', 't', '6', '4' > {};
|
||||
struct sint32_type : keyword< 's', 'i', 'n', 't', '3', '2' > {};
|
||||
struct sint64_type : keyword< 's', 'i', 'n', 't', '6', '4' > {};
|
||||
struct uint32_type : keyword< 'u', 'i', 'n', 't', '3', '2' > {};
|
||||
struct uint64_type : keyword< 'u', 'i', 'n', 't', '6', '4' > {};
|
||||
struct fixed32_type : keyword< 'f', 'i', 'x', 'e', 'd', '3', '2' > {};
|
||||
struct fixed64_type : keyword< 'f', 'i', 'x', 'e', 'd', '6', '4' > {};
|
||||
struct sfixed32_type : keyword< 's', 'f', 'i', 'x', 'e', 'd', '3', '2' > {};
|
||||
struct sfixed64_type : keyword< 's', 'f', 'i', 'x', 'e', 'd', '6', '4' > {};
|
||||
|
||||
struct builtin_type : sor< bool_type, bytes_type, double_type, float_type, string_type, int32_type, int64_type, sint32_type, sint64_type, uint32_type, uint64_type, fixed32_type, fixed64_type, sfixed32_type, sfixed64_type > {};
|
||||
|
||||
struct defined_type : seq< opt< dot >, full_ident > {}; // NOTE: This replaces both message_type and enum_type -- they have the same syntax.
|
||||
|
||||
struct type : sor< builtin_type, defined_type > {};
|
||||
|
||||
struct field_option : if_must< option_name, sps, equ, sps, constant > {};
|
||||
struct field_options : if_must< one< '[' >, sps, list< field_option, comma, sp >, sps, one< ']' > > {};
|
||||
struct field_name : ident {};
|
||||
struct field_number : int_lit {};
|
||||
struct field : seq< opt< sor< keyword< 'o', 'p', 't', 'i', 'o', 'n', 'a', 'l' >, keyword< 'r', 'e', 'p', 'e', 'a', 't', 'e', 'd' > >, sps >, type, sps, field_name, sps, equ, sps, field_number, sps, opt< field_options, sps >, semi > {};
|
||||
|
||||
struct oneof_name : ident {};
|
||||
struct oneof_field : if_must< type, sps, field_name, sps, equ, sps, field_number, sps, opt< field_options, sps >, semi > {};
|
||||
struct oneof_body : sor< oneof_field, semi > {};
|
||||
struct oneof : if_must< keyword< 'o', 'n', 'e', 'o', 'f' >, sps, oneof_name, sps, one< '{' >, sps, until< one< '}' >, oneof_body, sps >, sps > {};
|
||||
|
||||
struct key_type : seq< sor< bool_type, string_type, int32_type, int64_type, sint32_type, sint64_type, uint32_type, uint64_type, fixed32_type, fixed64_type, sfixed32_type, sfixed64_type >, not_at< ident_other > > {};
|
||||
struct map_name : ident {};
|
||||
struct map_field : if_must< keyword< 'm', 'a', 'p' >, sps, one< '<' >, sps, key_type, sps, comma, sps, type, sps, one< '>' >, sps, map_name, sps, equ, sps, field_number, sps, opt< field_options, sps >, semi > {};
|
||||
|
||||
struct range : if_must< int_lit, sps, keyword< 't', 'o' >, sps, sor< int_lit, keyword< 'm', 'a', 'x' > > > {};
|
||||
struct ranges : list_must< range, comma, sp > {};
|
||||
struct field_names : list_must< field_name, comma, sp > {};
|
||||
struct reserved : if_must< keyword< 'r', 'e', 's', 'e', 'r', 'v', 'e', 'd' >, sps, sor< ranges, field_names >, sps, semi > {};
|
||||
|
||||
struct enum_name : ident {};
|
||||
struct enum_value_option : seq< option_name, sps, equ, sps, constant > {};
|
||||
struct enum_field : seq< ident, sps, equ, sps, int_lit, sps, opt_must< one< '[' >, sps, list_must< enum_value_option, comma, sp >, sps, one< ']' >, sps >, semi > {};
|
||||
struct enum_body : if_must< one< '{' >, sps, star< sor< option, enum_field, semi >, sps >, one< '}' > > {};
|
||||
struct enum_def : if_must< keyword< 'e', 'n', 'u', 'm' >, sps, enum_name, sps, enum_body > {};
|
||||
|
||||
struct message_thing : sor< field, enum_def, message, option, oneof, map_field, reserved, extend, semi > {};
|
||||
struct message_body : seq< one<'{'>, sps, star< message_thing, sps >, one<'}'> > {};
|
||||
struct message : if_must< keyword< 'm', 'e', 's', 's', 'a', 'g', 'e' >, sps, defined_type, sps, message_body > {};
|
||||
struct extend : if_must< keyword< 'e', 'x', 't', 'e', 'n', 'd' >, sps, defined_type, sps, message_body > {};
|
||||
|
||||
struct package : if_must< keyword< 'p', 'a', 'c', 'k', 'a', 'g', 'e' >, sps, full_ident, sps, semi > {};
|
||||
|
||||
struct import_option : opt< sor< keyword< 'w', 'e', 'a', 'k' >, keyword< 'p', 'u', 'b', 'l', 'i', 'c' > > > {};
|
||||
struct import : if_must< keyword< 'i', 'm', 'p', 'o', 'r', 't' >, sps, import_option, sps, str_lit, sps, semi > {};
|
||||
|
||||
struct rpc_name : ident {};
|
||||
struct rpc_type : if_must< one< '(' >, sps, opt< keyword< 's', 't', 'r', 'e', 'a', 'm' >, sps >, defined_type, sps, one< ')' > > {};
|
||||
struct rpc_options : if_must< one< '{' >, sps, star< sor< option, semi >, sps >, one< '}' > > {};
|
||||
struct rpc : if_must< keyword< 'r', 'p', 'c' >, sps, rpc_name, sps, rpc_type, sps, keyword< 'r', 'e', 't', 'u', 'r', 'n', 's' >, sps, rpc_type, sps, sor< semi, rpc_options > > {};
|
||||
struct service_name : ident {};
|
||||
struct service : if_must< keyword< 's', 'e', 'r', 'v', 'i', 'c', 'e' >, sps, service_name, sps, one< '{' >, sps, star< sor< option, rpc, semi >, sps >, one< '}' > > {};
|
||||
|
||||
struct body : sor< import, package, option, message, enum_def, service, extend, semi > {};
|
||||
|
||||
struct quote : one< '\'', '"' > {};
|
||||
struct head : if_must< keyword< 's', 'y', 'n', 't', 'a', 'x' >, sps, equ, sps, quote, string< 'p', 'r', 'o', 't', 'o', '3' >, quote, sps, semi > {};
|
||||
struct proto : must< sps, head, sps, star< body, sps >, eof > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::proto3
|
||||
|
||||
#endif
|
|
@ -0,0 +1,233 @@
|
|||
// Copyright (c) 2014-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_RAW_STRING_HPP
|
||||
#define TAO_PEGTL_CONTRIB_RAW_STRING_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
|
||||
#include "../apply_mode.hpp"
|
||||
#include "../ascii.hpp"
|
||||
#include "../config.hpp"
|
||||
#include "../rewind_mode.hpp"
|
||||
#include "../rules.hpp"
|
||||
|
||||
#include "analyze_traits.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
template< char Open, char Marker >
|
||||
struct raw_string_open
|
||||
{
|
||||
using rule_t = raw_string_open;
|
||||
using subs_t = empty_list;
|
||||
|
||||
template< apply_mode A,
|
||||
rewind_mode,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput >
|
||||
[[nodiscard]] static bool match( ParseInput& in, std::size_t& marker_size ) noexcept( noexcept( in.size( 0 ) ) )
|
||||
{
|
||||
if( in.empty() || ( in.peek_char( 0 ) != Open ) ) {
|
||||
return false;
|
||||
}
|
||||
for( std::size_t i = 1; i < in.size( i + 1 ); ++i ) {
|
||||
switch( const auto c = in.peek_char( i ) ) {
|
||||
case Open:
|
||||
marker_size = i + 1;
|
||||
in.bump_in_this_line( marker_size );
|
||||
(void)eol::match( in );
|
||||
return true;
|
||||
case Marker:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template< char Open, char Marker >
|
||||
inline constexpr bool enable_control< raw_string_open< Open, Marker > > = false;
|
||||
|
||||
template< char Marker, char Close >
|
||||
struct at_raw_string_close
|
||||
{
|
||||
using rule_t = at_raw_string_close;
|
||||
using subs_t = empty_list;
|
||||
|
||||
template< apply_mode A,
|
||||
rewind_mode,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput >
|
||||
[[nodiscard]] static bool match( ParseInput& in, const std::size_t& marker_size ) noexcept( noexcept( in.size( 0 ) ) )
|
||||
{
|
||||
if( in.size( marker_size ) < marker_size ) {
|
||||
return false;
|
||||
}
|
||||
if( in.peek_char( 0 ) != Close ) {
|
||||
return false;
|
||||
}
|
||||
if( in.peek_char( marker_size - 1 ) != Close ) {
|
||||
return false;
|
||||
}
|
||||
for( std::size_t i = 0; i < ( marker_size - 2 ); ++i ) {
|
||||
if( in.peek_char( i + 1 ) != Marker ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template< char Marker, char Close >
|
||||
inline constexpr bool enable_control< at_raw_string_close< Marker, Close > > = false;
|
||||
|
||||
template< typename Cond, typename... Rules >
|
||||
struct raw_string_until
|
||||
: raw_string_until< Cond, seq< Rules... > >
|
||||
{};
|
||||
|
||||
template< typename Cond >
|
||||
struct raw_string_until< Cond >
|
||||
{
|
||||
using rule_t = raw_string_until;
|
||||
using subs_t = type_list< Cond >;
|
||||
|
||||
template< apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, const std::size_t& marker_size, States&&... /*unused*/ )
|
||||
{
|
||||
auto m = in.template mark< M >();
|
||||
|
||||
while( !Control< Cond >::template match< A, rewind_mode::required, Action, Control >( in, marker_size ) ) {
|
||||
if( in.empty() ) {
|
||||
return false;
|
||||
}
|
||||
in.bump();
|
||||
}
|
||||
return m( true );
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Cond, typename Rule >
|
||||
struct raw_string_until< Cond, Rule >
|
||||
{
|
||||
using rule_t = raw_string_until;
|
||||
using subs_t = type_list< Cond, Rule >;
|
||||
|
||||
template< apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, const std::size_t& marker_size, States&&... st )
|
||||
{
|
||||
auto m = in.template mark< M >();
|
||||
using m_t = decltype( m );
|
||||
|
||||
while( !Control< Cond >::template match< A, rewind_mode::required, Action, Control >( in, marker_size ) ) {
|
||||
if( !Control< Rule >::template match< A, m_t::next_rewind_mode, Action, Control >( in, st... ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return m( true );
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Cond, typename... Rules >
|
||||
inline constexpr bool enable_control< raw_string_until< Cond, Rules... > > = false;
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// raw_string matches Lua-style long literals.
|
||||
//
|
||||
// The following description was taken from the Lua documentation
|
||||
// (see http://www.lua.org/docs.html):
|
||||
//
|
||||
// - An "opening long bracket of level n" is defined as an opening square
|
||||
// bracket followed by n equal signs followed by another opening square
|
||||
// bracket. So, an opening long bracket of level 0 is written as `[[`,
|
||||
// an opening long bracket of level 1 is written as `[=[`, and so on.
|
||||
// - A "closing long bracket" is defined similarly; for instance, a closing
|
||||
// long bracket of level 4 is written as `]====]`.
|
||||
// - A "long literal" starts with an opening long bracket of any level and
|
||||
// ends at the first closing long bracket of the same level. It can
|
||||
// contain any text except a closing bracket of the same level.
|
||||
// - Literals in this bracketed form can run for several lines, do not
|
||||
// interpret any escape sequences, and ignore long brackets of any other
|
||||
// level.
|
||||
// - For convenience, when the opening long bracket is eagerly followed
|
||||
// by a newline, the newline is not included in the string.
|
||||
//
|
||||
// Note that unlike Lua's long literal, a raw_string is customizable to use
|
||||
// other characters than `[`, `=` and `]` for matching. Also note that Lua
|
||||
// introduced newline-specific replacements in Lua 5.2, which we do not
|
||||
// support on the grammar level.
|
||||
|
||||
template< char Open, char Marker, char Close, typename... Contents >
|
||||
struct raw_string
|
||||
{
|
||||
// This is used for binding the apply()-method and for error-reporting
|
||||
// when a raw string is not closed properly or has invalid content.
|
||||
struct content
|
||||
: internal::raw_string_until< internal::at_raw_string_close< Marker, Close >, Contents... >
|
||||
{};
|
||||
|
||||
using rule_t = raw_string;
|
||||
using subs_t = empty_list; // type_list< internal::raw_string_open< Open, Marker >, content >;
|
||||
|
||||
template< apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, States&&... st )
|
||||
{
|
||||
std::size_t marker_size;
|
||||
if( Control< internal::raw_string_open< Open, Marker > >::template match< A, M, Action, Control >( in, marker_size ) ) {
|
||||
if( Control< content >::template match< A, M, Action, Control >( in, marker_size, st... ) ) {
|
||||
in.bump_in_this_line( marker_size );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Name, char Open, char Marker, char Close >
|
||||
struct analyze_traits< Name, raw_string< Open, Marker, Close > >
|
||||
: analyze_any_traits<>
|
||||
{};
|
||||
|
||||
template< typename Name, char Open, char Marker, char Close, typename... Contents >
|
||||
struct analyze_traits< Name, raw_string< Open, Marker, Close, Contents... > >
|
||||
: analyze_traits< Name, typename seq< any, star< Contents... >, any >::rule_t >
|
||||
{};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,73 @@
|
|||
// Copyright (c) 2019-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_REMOVE_FIRST_STATE_HPP
|
||||
#define TAO_PEGTL_CONTRIB_REMOVE_FIRST_STATE_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "../config.hpp"
|
||||
|
||||
#include "../internal/has_unwind.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
// The first state is removed for most of the control functions forwarded to Base,
|
||||
// start(), success(), failure(), unwind(), raise(), apply(), and apply0(). The call
|
||||
// to match() is unchanged because it can call other grammar rules that require all
|
||||
// states when starting their match to keep an even playing field.
|
||||
|
||||
template< typename Base >
|
||||
struct remove_first_state
|
||||
: Base
|
||||
{
|
||||
template< typename ParseInput, typename State, typename... States >
|
||||
static void start( const ParseInput& in, State&& /*unused*/, States&&... st ) noexcept( noexcept( Base::start( in, st... ) ) )
|
||||
{
|
||||
Base::start( in, st... );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename State, typename... States >
|
||||
static void success( const ParseInput& in, State&& /*unused*/, States&&... st ) noexcept( noexcept( Base::success( in, st... ) ) )
|
||||
{
|
||||
Base::success( in, st... );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename State, typename... States >
|
||||
static void failure( const ParseInput& in, State&& /*unused*/, States&&... st ) noexcept( noexcept( Base::failure( in, st... ) ) )
|
||||
{
|
||||
Base::failure( in, st... );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename State, typename... States >
|
||||
[[noreturn]] static void raise( const ParseInput& in, State&& /*unused*/, States&&... st )
|
||||
{
|
||||
Base::raise( in, st... );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename State, typename... States >
|
||||
static auto unwind( const ParseInput& in, State&& /*unused*/, States&&... st )
|
||||
-> std::enable_if_t< internal::has_unwind< Base, void, const ParseInput&, States... > >
|
||||
{
|
||||
Base::unwind( in, st... );
|
||||
}
|
||||
|
||||
template< template< typename... > class Action, typename Iterator, typename ParseInput, typename State, typename... States >
|
||||
static auto apply( const Iterator& begin, const ParseInput& in, State&& /*unused*/, States&&... st ) noexcept( noexcept( Base::template apply< Action >( begin, in, st... ) ) )
|
||||
-> decltype( Base::template apply< Action >( begin, in, st... ) )
|
||||
{
|
||||
return Base::template apply< Action >( begin, in, st... );
|
||||
}
|
||||
|
||||
template< template< typename... > class Action, typename ParseInput, typename State, typename... States >
|
||||
static auto apply0( const ParseInput& in, State&& /*unused*/, States&&... st ) noexcept( noexcept( Base::template apply0< Action >( in, st... ) ) )
|
||||
-> decltype( Base::template apply0< Action >( in, st... ) )
|
||||
{
|
||||
return Base::template apply0< Action >( in, st... );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,122 @@
|
|||
// Copyright (c) 2020-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_REMOVE_LAST_STATES_HPP
|
||||
#define TAO_PEGTL_CONTRIB_REMOVE_LAST_STATES_HPP
|
||||
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include "../config.hpp"
|
||||
|
||||
#include "../internal/has_unwind.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
// The last N states are removed for most of the control functions forwarded to Base,
|
||||
// start(), success(), failure(), unwind(), raise(), apply(), and apply0(). The call
|
||||
// to match() is unchanged because it can call other grammar rules that require all
|
||||
// states when starting their match to keep an even playing field.
|
||||
|
||||
template< typename Base, std::size_t N >
|
||||
struct remove_last_states
|
||||
: Base
|
||||
{
|
||||
template< typename ParseInput, typename Tuple, std::size_t... Is >
|
||||
static void start_impl( const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ ) noexcept( noexcept( Base::start( in, std::get< Is >( t )... ) ) )
|
||||
{
|
||||
Base::start( in, std::get< Is >( t )... );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename... States >
|
||||
static void start( const ParseInput& in, States&&... st ) noexcept( noexcept( start_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() ) ) )
|
||||
{
|
||||
start_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename Tuple, std::size_t... Is >
|
||||
static void success_impl( const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ ) noexcept( noexcept( Base::success( in, std::get< Is >( t )... ) ) )
|
||||
{
|
||||
Base::success( in, std::get< Is >( t )... );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename... States >
|
||||
static void success( const ParseInput& in, States&&... st ) noexcept( noexcept( success_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() ) ) )
|
||||
{
|
||||
success_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename Tuple, std::size_t... Is >
|
||||
static void failure_impl( const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ ) noexcept( noexcept( Base::failure( in, std::get< Is >( t )... ) ) )
|
||||
{
|
||||
Base::failure( in, std::get< Is >( t )... );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename... States >
|
||||
static void failure( const ParseInput& in, States&&... st ) noexcept( noexcept( failure_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() ) ) )
|
||||
{
|
||||
failure_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename Tuple, std::size_t... Is >
|
||||
[[noreturn]] static void raise_impl( const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ )
|
||||
{
|
||||
Base::raise( in, std::get< Is >( t )... );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename... States >
|
||||
[[noreturn]] static void raise( const ParseInput& in, States&&... st )
|
||||
{
|
||||
raise_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename Tuple, std::size_t... Is >
|
||||
static auto unwind_impl( const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ )
|
||||
-> std::enable_if_t< internal::has_unwind< Base, void, const ParseInput&, std::tuple_element_t< Is, Tuple >... > >
|
||||
{
|
||||
Base::unwind( in, std::get< Is >( t )... );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename... States >
|
||||
static auto unwind( const ParseInput& in, States&&... st )
|
||||
-> decltype( unwind_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() ) )
|
||||
{
|
||||
unwind_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() );
|
||||
}
|
||||
|
||||
template< template< typename... > class Action, typename Iterator, typename ParseInput, typename Tuple, std::size_t... Is >
|
||||
static auto apply_impl( const Iterator& begin, const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ ) noexcept( noexcept( Base::template apply< Action >( begin, in, std::get< Is >( t )... ) ) )
|
||||
-> decltype( Base::template apply< Action >( begin, in, std::get< Is >( t )... ) )
|
||||
{
|
||||
return Base::template apply< Action >( begin, in, std::get< Is >( t )... );
|
||||
}
|
||||
|
||||
template< template< typename... > class Action, typename Iterator, typename ParseInput, typename... States >
|
||||
static auto apply( const Iterator& begin, const ParseInput& in, States&&... st ) noexcept( noexcept( apply_impl< Action >( begin, in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() ) ) )
|
||||
-> decltype( apply_impl< Action >( begin, in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() ) )
|
||||
{
|
||||
return apply_impl< Action >( begin, in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() );
|
||||
}
|
||||
|
||||
template< template< typename... > class Action, typename ParseInput, typename Tuple, std::size_t... Is >
|
||||
static auto apply0_impl( const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ ) noexcept( noexcept( Base::template apply0< Action >( in, std::get< Is >( t )... ) ) )
|
||||
-> decltype( Base::template apply0< Action >( in, std::get< Is >( t )... ) )
|
||||
{
|
||||
return Base::template apply0< Action >( in, std::get< Is >( t )... );
|
||||
}
|
||||
|
||||
template< template< typename... > class Action, typename ParseInput, typename... States >
|
||||
static auto apply0( const ParseInput& in, States&&... st ) noexcept( noexcept( apply0_impl< Action >( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() ) ) )
|
||||
-> decltype( apply0_impl< Action >( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() ) )
|
||||
{
|
||||
return apply0_impl< Action >( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) - N >() );
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Base >
|
||||
using remove_last_state = remove_last_states< Base, 1 >;
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,101 @@
|
|||
// Copyright (c) 2017-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_REP_ONE_MIN_MAX_HPP
|
||||
#define TAO_PEGTL_CONTRIB_REP_ONE_MIN_MAX_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <type_traits>
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "../type_list.hpp"
|
||||
|
||||
#include "../internal/bump_help.hpp"
|
||||
#include "../internal/bytes.hpp"
|
||||
#include "../internal/enable_control.hpp"
|
||||
#include "../internal/opt.hpp"
|
||||
|
||||
#include "analyze_traits.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
template< unsigned Min, unsigned Max, char C >
|
||||
struct rep_one_min_max
|
||||
{
|
||||
using rule_t = rep_one_min_max;
|
||||
using subs_t = empty_list;
|
||||
|
||||
static_assert( Min <= Max );
|
||||
|
||||
template< int Eol >
|
||||
static constexpr bool can_match_eol = ( C == Eol );
|
||||
|
||||
template< typename ParseInput >
|
||||
[[nodiscard]] static bool match( ParseInput& in )
|
||||
{
|
||||
const auto size = in.size( Max + 1 );
|
||||
if( size < Min ) {
|
||||
return false;
|
||||
}
|
||||
std::size_t i = 0;
|
||||
while( ( i < size ) && ( in.peek_char( i ) == C ) ) {
|
||||
++i;
|
||||
}
|
||||
if( ( Min <= i ) && ( i <= Max ) ) {
|
||||
bump_help< rep_one_min_max >( in, i );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template< unsigned Max, char C >
|
||||
struct rep_one_min_max< 0, Max, C >
|
||||
{
|
||||
using rule_t = rep_one_min_max;
|
||||
using subs_t = empty_list;
|
||||
|
||||
template< int Eol >
|
||||
static constexpr bool can_match_eol = ( C == Eol );
|
||||
|
||||
template< typename ParseInput >
|
||||
[[nodiscard]] static bool match( ParseInput& in )
|
||||
{
|
||||
const auto size = in.size( Max + 1 );
|
||||
std::size_t i = 0;
|
||||
while( ( i < size ) && ( in.peek_char( i ) == C ) ) {
|
||||
++i;
|
||||
}
|
||||
if( i <= Max ) {
|
||||
bump_help< rep_one_min_max >( in, i );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template< unsigned Min, unsigned Max, char C >
|
||||
inline constexpr bool enable_control< rep_one_min_max< Min, Max, C > > = false;
|
||||
|
||||
} // namespace internal
|
||||
|
||||
inline namespace ascii
|
||||
{
|
||||
template< unsigned Min, unsigned Max, char C >
|
||||
struct rep_one_min_max
|
||||
: internal::rep_one_min_max< Min, Max, C >
|
||||
{};
|
||||
|
||||
} // namespace ascii
|
||||
|
||||
template< typename Name, unsigned Min, unsigned Max, char C >
|
||||
struct analyze_traits< Name, internal::rep_one_min_max< Min, Max, C > >
|
||||
: std::conditional_t< ( Min != 0 ), analyze_any_traits<>, analyze_opt_traits<> >
|
||||
{};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright (c) 2019-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_REP_STRING_HPP
|
||||
#define TAO_PEGTL_CONTRIB_REP_STRING_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "../internal/string.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
template< std::size_t, typename, char... >
|
||||
struct make_rep_string;
|
||||
|
||||
template< char... Ss, char... Cs >
|
||||
struct make_rep_string< 0, string< Ss... >, Cs... >
|
||||
{
|
||||
using type = string< Ss... >;
|
||||
};
|
||||
|
||||
template< std::size_t N, char... Ss, char... Cs >
|
||||
struct make_rep_string< N, string< Ss... >, Cs... >
|
||||
: make_rep_string< N - 1, string< Ss..., Cs... >, Cs... >
|
||||
{};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
inline namespace ascii
|
||||
{
|
||||
template< std::size_t N, char... Cs >
|
||||
struct rep_string
|
||||
: internal::make_rep_string< N, internal::string<>, Cs... >::type
|
||||
{};
|
||||
|
||||
} // namespace ascii
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright (c) 2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_SEPARATED_SEQ_HPP
|
||||
#define TAO_PEGTL_CONTRIB_SEPARATED_SEQ_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
|
||||
#include "../internal/seq.hpp"
|
||||
#include "../type_list.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
template< typename... >
|
||||
struct sep;
|
||||
|
||||
template< typename... Ts, typename S, typename Rule, typename... Rules >
|
||||
struct sep< type_list< Ts... >, S, Rule, Rules... >
|
||||
: sep< type_list< Ts..., Rule, S >, S, Rules... >
|
||||
{};
|
||||
|
||||
template< typename... Ts, typename S, typename Rule >
|
||||
struct sep< type_list< Ts... >, S, Rule >
|
||||
{
|
||||
using type = seq< Ts..., Rule >;
|
||||
};
|
||||
|
||||
template< typename S >
|
||||
struct sep< type_list<>, S >
|
||||
{
|
||||
using type = seq<>;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template< typename S, typename... Rules >
|
||||
struct separated_seq
|
||||
: internal::sep< type_list<>, S, Rules... >::type
|
||||
{};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,194 @@
|
|||
// Copyright (c) 2020-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_SHUFFLE_STATES_HPP
|
||||
#define TAO_PEGTL_CONTRIB_SHUFFLE_STATES_HPP
|
||||
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "../config.hpp"
|
||||
|
||||
#include "../internal/has_unwind.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
template< std::size_t N >
|
||||
struct rotate_left
|
||||
{
|
||||
template< std::size_t I, std::size_t S >
|
||||
static constexpr std::size_t value = ( I + N ) % S;
|
||||
};
|
||||
|
||||
template< std::size_t N >
|
||||
struct rotate_right
|
||||
{
|
||||
template< std::size_t I, std::size_t S >
|
||||
static constexpr std::size_t value = ( I + S - N ) % S;
|
||||
};
|
||||
|
||||
struct reverse
|
||||
{
|
||||
template< std::size_t I, std::size_t S >
|
||||
static constexpr std::size_t value = ( S - 1 ) - I;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Applies 'Shuffle' to the states of start(), success(), failure(), raise(), apply(), and apply0()
|
||||
template< typename Base, typename Shuffle >
|
||||
struct shuffle_states
|
||||
: Base
|
||||
{
|
||||
template< typename ParseInput, typename Tuple, std::size_t... Is >
|
||||
static void start_impl( const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ ) noexcept( noexcept( Base::start( in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... ) ) )
|
||||
{
|
||||
Base::start( in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename... States >
|
||||
static void start( const ParseInput& in, States&&... st ) noexcept( noexcept( start_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() ) ) )
|
||||
{
|
||||
start_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename State >
|
||||
static void start( const ParseInput& in, State&& st ) noexcept( noexcept( Base::start( in, st ) ) )
|
||||
{
|
||||
Base::start( in, st );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename Tuple, std::size_t... Is >
|
||||
static void success_impl( const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ ) noexcept( noexcept( Base::success( in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... ) ) )
|
||||
{
|
||||
Base::success( in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename... States >
|
||||
static void success( const ParseInput& in, States&&... st ) noexcept( noexcept( success_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() ) ) )
|
||||
{
|
||||
success_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename State >
|
||||
static void success( const ParseInput& in, State&& st ) noexcept( noexcept( Base::success( in, st ) ) )
|
||||
{
|
||||
Base::success( in, st );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename Tuple, std::size_t... Is >
|
||||
static void failure_impl( const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ ) noexcept( noexcept( Base::failure( in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... ) ) )
|
||||
{
|
||||
Base::failure( in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename... States >
|
||||
static void failure( const ParseInput& in, States&&... st ) noexcept( noexcept( failure_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() ) ) )
|
||||
{
|
||||
failure_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename State >
|
||||
static void failure( const ParseInput& in, State&& st ) noexcept( noexcept( Base::failure( in, st ) ) )
|
||||
{
|
||||
Base::failure( in, st );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename Tuple, std::size_t... Is >
|
||||
[[noreturn]] static void raise_impl( const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ )
|
||||
{
|
||||
Base::raise( in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename... States >
|
||||
[[noreturn]] static void raise( const ParseInput& in, States&&... st )
|
||||
{
|
||||
raise_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename State >
|
||||
[[noreturn]] static void raise( const ParseInput& in, State&& st )
|
||||
{
|
||||
Base::raise( in, st );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename Tuple, std::size_t... Is >
|
||||
static auto unwind_impl( const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ )
|
||||
-> std::enable_if_t< internal::has_unwind< Base, void, const ParseInput&, std::tuple_element_t< Shuffle::template value< Is, sizeof...( Is ) >, Tuple >... > >
|
||||
{
|
||||
Base::unwind( in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename... States >
|
||||
static auto unwind( const ParseInput& in, States&&... st )
|
||||
-> decltype( unwind_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() ) )
|
||||
{
|
||||
unwind_impl( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename State >
|
||||
static auto unwind( const ParseInput& in, State&& st )
|
||||
-> std::enable_if_t< internal::has_unwind< Base, void, const ParseInput&, State > >
|
||||
{
|
||||
Base::unwind( in, st );
|
||||
}
|
||||
|
||||
template< template< typename... > class Action, typename Iterator, typename ParseInput, typename Tuple, std::size_t... Is >
|
||||
static auto apply_impl( const Iterator& begin, const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ ) noexcept( noexcept( Base::template apply< Action >( begin, in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... ) ) )
|
||||
-> decltype( Base::template apply< Action >( begin, in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... ) )
|
||||
{
|
||||
return Base::template apply< Action >( begin, in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... );
|
||||
}
|
||||
|
||||
template< template< typename... > class Action, typename Iterator, typename ParseInput, typename... States >
|
||||
static auto apply( const Iterator& begin, const ParseInput& in, States&&... st ) noexcept( noexcept( apply_impl< Action >( begin, in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() ) ) )
|
||||
-> decltype( apply_impl< Action >( begin, in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() ) )
|
||||
{
|
||||
return apply_impl< Action >( begin, in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() );
|
||||
}
|
||||
|
||||
template< template< typename... > class Action, typename Iterator, typename ParseInput, typename State >
|
||||
static auto apply( const Iterator& begin, const ParseInput& in, State&& st ) noexcept( noexcept( Base::template apply< Action >( begin, in, st ) ) )
|
||||
-> decltype( Base::template apply< Action >( begin, in, st ) )
|
||||
{
|
||||
return Base::template apply< Action >( begin, in, st );
|
||||
}
|
||||
|
||||
template< template< typename... > class Action, typename ParseInput, typename Tuple, std::size_t... Is >
|
||||
static auto apply0_impl( const ParseInput& in, const Tuple& t, std::index_sequence< Is... > /*unused*/ ) noexcept( noexcept( Base::template apply0< Action >( in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... ) ) )
|
||||
-> decltype( Base::template apply0< Action >( in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... ) )
|
||||
{
|
||||
return Base::template apply0< Action >( in, std::get< Shuffle::template value< Is, sizeof...( Is ) > >( t )... );
|
||||
}
|
||||
|
||||
template< template< typename... > class Action, typename ParseInput, typename... States >
|
||||
static auto apply0( const ParseInput& in, States&&... st ) noexcept( noexcept( apply0_impl< Action >( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() ) ) )
|
||||
-> decltype( apply0_impl< Action >( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() ) )
|
||||
{
|
||||
return apply0_impl< Action >( in, std::tie( st... ), std::make_index_sequence< sizeof...( st ) >() );
|
||||
}
|
||||
|
||||
template< template< typename... > class Action, typename ParseInput, typename State >
|
||||
static auto apply0( const ParseInput& in, State&& st ) noexcept( noexcept( Base::template apply0< Action >( in, st ) ) )
|
||||
-> decltype( Base::template apply0< Action >( in, st ) )
|
||||
{
|
||||
return Base::template apply0< Action >( in, st );
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Base, std::size_t N = 1 >
|
||||
using rotate_states_left = shuffle_states< Base, internal::rotate_left< N > >;
|
||||
|
||||
template< typename Base, std::size_t N = 1 >
|
||||
using rotate_states_right = shuffle_states< Base, internal::rotate_right< N > >;
|
||||
|
||||
template< typename Base >
|
||||
using reverse_states = shuffle_states< Base, internal::reverse >;
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,123 @@
|
|||
// Copyright (c) 2020-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_STATE_CONTROL_HPP
|
||||
#define TAO_PEGTL_CONTRIB_STATE_CONTROL_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "shuffle_states.hpp"
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "../internal/has_unwind.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
template< template< typename... > class Control >
|
||||
struct state_control
|
||||
{
|
||||
template< typename Rule >
|
||||
struct control
|
||||
: Control< Rule >
|
||||
{
|
||||
static constexpr bool enable = true;
|
||||
|
||||
template< typename ParseInput, typename State, typename... States >
|
||||
static void start( [[maybe_unused]] const ParseInput& in, [[maybe_unused]] State& state, [[maybe_unused]] States&&... st )
|
||||
{
|
||||
if constexpr( Control< Rule >::enable ) {
|
||||
Control< Rule >::start( in, st... );
|
||||
}
|
||||
if constexpr( State::template enable< Rule > ) {
|
||||
state.template start< Rule >( in, st... );
|
||||
}
|
||||
#if defined( _MSC_VER )
|
||||
( (void)st,
|
||||
... );
|
||||
#endif
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename State, typename... States >
|
||||
static void success( [[maybe_unused]] const ParseInput& in, [[maybe_unused]] State& state, [[maybe_unused]] States&&... st )
|
||||
{
|
||||
if constexpr( State::template enable< Rule > ) {
|
||||
state.template success< Rule >( in, st... );
|
||||
}
|
||||
if constexpr( Control< Rule >::enable ) {
|
||||
Control< Rule >::success( in, st... );
|
||||
}
|
||||
#if defined( _MSC_VER )
|
||||
( (void)st,
|
||||
... );
|
||||
#endif
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename State, typename... States >
|
||||
static void failure( [[maybe_unused]] const ParseInput& in, [[maybe_unused]] State& state, [[maybe_unused]] States&&... st )
|
||||
{
|
||||
if constexpr( State::template enable< Rule > ) {
|
||||
state.template failure< Rule >( in, st... );
|
||||
}
|
||||
if constexpr( Control< Rule >::enable ) {
|
||||
Control< Rule >::failure( in, st... );
|
||||
}
|
||||
#if defined( _MSC_VER )
|
||||
( (void)st,
|
||||
... );
|
||||
#endif
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename State, typename... States >
|
||||
[[noreturn]] static void raise( const ParseInput& in, [[maybe_unused]] State& state, States&&... st )
|
||||
{
|
||||
if constexpr( State::template enable< Rule > ) {
|
||||
state.template raise< Rule >( in, st... );
|
||||
}
|
||||
Control< Rule >::raise( in, st... );
|
||||
}
|
||||
|
||||
template< typename ParseInput, typename State, typename... States >
|
||||
static auto unwind( [[maybe_unused]] const ParseInput& in, [[maybe_unused]] State& state, [[maybe_unused]] States&&... st )
|
||||
-> std::enable_if_t< State::template enable< Rule > || ( Control< Rule >::enable && internal::has_unwind< Control< Rule >, void, const ParseInput&, States... > ) >
|
||||
{
|
||||
if constexpr( State::template enable< Rule > ) {
|
||||
state.template unwind< Rule >( in, st... );
|
||||
}
|
||||
if constexpr( Control< Rule >::enable && internal::has_unwind< Control< Rule >, void, const ParseInput&, States... > ) {
|
||||
Control< Rule >::unwind( in, st... );
|
||||
}
|
||||
#if defined( _MSC_VER )
|
||||
( (void)st,
|
||||
... );
|
||||
#endif
|
||||
}
|
||||
|
||||
template< template< typename... > class Action, typename Iterator, typename ParseInput, typename State, typename... States >
|
||||
static auto apply( const Iterator& begin, const ParseInput& in, [[maybe_unused]] State& state, States&&... st )
|
||||
-> decltype( Control< Rule >::template apply< Action >( begin, in, st... ) )
|
||||
{
|
||||
if constexpr( State::template enable< Rule > ) {
|
||||
state.template apply< Rule >( in, st... );
|
||||
}
|
||||
return Control< Rule >::template apply< Action >( begin, in, st... );
|
||||
}
|
||||
|
||||
template< template< typename... > class Action, typename ParseInput, typename State, typename... States >
|
||||
static auto apply0( const ParseInput& in, [[maybe_unused]] State& state, States&&... st )
|
||||
-> decltype( Control< Rule >::template apply0< Action >( in, st... ) )
|
||||
{
|
||||
if constexpr( State::template enable< Rule > ) {
|
||||
state.template apply0< Rule >( in, st... );
|
||||
}
|
||||
return Control< Rule >::template apply0< Action >( in, st... );
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Rule >
|
||||
using type = rotate_states_right< control< Rule > >;
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright (c) 2017-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_TO_STRING_HPP
|
||||
#define TAO_PEGTL_CONTRIB_TO_STRING_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "../config.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
template< typename >
|
||||
struct to_string;
|
||||
|
||||
template< template< char... > class X, char... Cs >
|
||||
struct to_string< X< Cs... > >
|
||||
{
|
||||
[[nodiscard]] static std::string get()
|
||||
{
|
||||
const char s[] = { Cs..., 0 };
|
||||
return std::string( s, sizeof...( Cs ) );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template< typename T >
|
||||
[[nodiscard]] std::string to_string()
|
||||
{
|
||||
return internal::to_string< T >::get();
|
||||
}
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,241 @@
|
|||
// Copyright (c) 2020-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_TRACE_HPP
|
||||
#define TAO_PEGTL_CONTRIB_TRACE_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
|
||||
#include "state_control.hpp"
|
||||
|
||||
#include "../apply_mode.hpp"
|
||||
#include "../config.hpp"
|
||||
#include "../demangle.hpp"
|
||||
#include "../normal.hpp"
|
||||
#include "../nothing.hpp"
|
||||
#include "../parse.hpp"
|
||||
#include "../rewind_mode.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
template< bool HideInternal = true,
|
||||
bool UseColor = true,
|
||||
bool PrintSourceLine = false,
|
||||
std::size_t IndentIncrement = 2,
|
||||
std::size_t InitialIndent = 8 >
|
||||
struct tracer_traits
|
||||
{
|
||||
template< typename Rule >
|
||||
static constexpr bool enable = ( HideInternal ? normal< Rule >::enable : true );
|
||||
|
||||
static constexpr std::size_t initial_indent = InitialIndent;
|
||||
static constexpr std::size_t indent_increment = IndentIncrement;
|
||||
|
||||
static constexpr bool print_source_line = PrintSourceLine;
|
||||
|
||||
static constexpr std::string_view ansi_reset = UseColor ? "\033[m" : "";
|
||||
static constexpr std::string_view ansi_rule = UseColor ? "\033[36m" : "";
|
||||
static constexpr std::string_view ansi_hide = UseColor ? "\033[37m" : "";
|
||||
|
||||
static constexpr std::string_view ansi_position = UseColor ? "\033[1;34m" : "";
|
||||
static constexpr std::string_view ansi_success = UseColor ? "\033[32m" : "";
|
||||
static constexpr std::string_view ansi_failure = UseColor ? "\033[31m" : "";
|
||||
static constexpr std::string_view ansi_raise = UseColor ? "\033[1;31m" : "";
|
||||
static constexpr std::string_view ansi_unwind = UseColor ? "\033[31m" : "";
|
||||
static constexpr std::string_view ansi_apply = UseColor ? "\033[1;36m" : "";
|
||||
};
|
||||
|
||||
using standard_tracer_traits = tracer_traits< true >;
|
||||
using complete_tracer_traits = tracer_traits< false >;
|
||||
|
||||
template< typename TracerTraits >
|
||||
struct tracer
|
||||
{
|
||||
const std::ios_base::fmtflags m_flags;
|
||||
std::size_t m_count = 0;
|
||||
std::vector< std::size_t > m_stack;
|
||||
position m_position;
|
||||
|
||||
template< typename Rule >
|
||||
static constexpr bool enable = TracerTraits::template enable< Rule >;
|
||||
|
||||
template< typename ParseInput >
|
||||
explicit tracer( const ParseInput& in )
|
||||
: m_flags( std::cerr.flags() ),
|
||||
m_position( in.position() )
|
||||
{
|
||||
std::cerr << std::left;
|
||||
print_position( in );
|
||||
}
|
||||
|
||||
tracer( const tracer& ) = delete;
|
||||
tracer( tracer&& ) = delete;
|
||||
|
||||
~tracer()
|
||||
{
|
||||
std::cerr.flags( m_flags );
|
||||
}
|
||||
|
||||
tracer& operator=( const tracer& ) = delete;
|
||||
tracer& operator=( tracer&& ) = delete;
|
||||
|
||||
[[nodiscard]] std::size_t indent() const noexcept
|
||||
{
|
||||
return TracerTraits::initial_indent + TracerTraits::indent_increment * m_stack.size();
|
||||
}
|
||||
|
||||
template< typename ParseInput >
|
||||
void print_position( [[maybe_unused]] const ParseInput& in ) const
|
||||
{
|
||||
std::cerr << std::setw( indent() ) << ' ' << TracerTraits::ansi_position << "position" << TracerTraits::ansi_reset << ' ' << m_position << '\n';
|
||||
if constexpr( TracerTraits::print_source_line ) {
|
||||
std::cerr << std::setw( indent() ) << ' ' << TracerTraits::ansi_position << "source" << TracerTraits::ansi_reset << ' ' << in.line_at( m_position ) << '\n';
|
||||
std::cerr << std::setw( indent() + 6 + m_position.column ) << ' ' << "^\n";
|
||||
}
|
||||
}
|
||||
|
||||
template< typename ParseInput >
|
||||
void update_position( const ParseInput& in )
|
||||
{
|
||||
const auto p = in.position();
|
||||
if( m_position != p ) {
|
||||
m_position = p;
|
||||
print_position( in );
|
||||
}
|
||||
}
|
||||
|
||||
template< typename Rule, typename ParseInput, typename... States >
|
||||
void start( const ParseInput& /*unused*/, States&&... /*unused*/ )
|
||||
{
|
||||
std::cerr << '#' << std::setw( indent() - 1 ) << ++m_count << TracerTraits::ansi_rule << demangle< Rule >() << TracerTraits::ansi_reset << '\n';
|
||||
m_stack.push_back( m_count );
|
||||
}
|
||||
|
||||
template< typename Rule, typename ParseInput, typename... States >
|
||||
void success( const ParseInput& in, States&&... /*unused*/ )
|
||||
{
|
||||
const auto prev = m_stack.back();
|
||||
m_stack.pop_back();
|
||||
std::cerr << std::setw( indent() ) << ' ' << TracerTraits::ansi_success << "success" << TracerTraits::ansi_reset;
|
||||
if( m_count != prev ) {
|
||||
std::cerr << " #" << prev << ' ' << TracerTraits::ansi_hide << demangle< Rule >() << TracerTraits::ansi_reset;
|
||||
}
|
||||
std::cerr << '\n';
|
||||
update_position( in );
|
||||
}
|
||||
|
||||
template< typename Rule, typename ParseInput, typename... States >
|
||||
void failure( const ParseInput& in, States&&... /*unused*/ )
|
||||
{
|
||||
const auto prev = m_stack.back();
|
||||
m_stack.pop_back();
|
||||
std::cerr << std::setw( indent() ) << ' ' << TracerTraits::ansi_failure << "failure" << TracerTraits::ansi_reset;
|
||||
if( m_count != prev ) {
|
||||
std::cerr << " #" << prev << ' ' << TracerTraits::ansi_hide << demangle< Rule >() << TracerTraits::ansi_reset;
|
||||
}
|
||||
std::cerr << '\n';
|
||||
update_position( in );
|
||||
}
|
||||
|
||||
template< typename Rule, typename ParseInput, typename... States >
|
||||
void raise( const ParseInput& /*unused*/, States&&... /*unused*/ )
|
||||
{
|
||||
std::cerr << std::setw( indent() ) << ' ' << TracerTraits::ansi_raise << "raise" << TracerTraits::ansi_reset << ' ' << TracerTraits::ansi_rule << demangle< Rule >() << TracerTraits::ansi_reset << '\n';
|
||||
}
|
||||
|
||||
template< typename Rule, typename ParseInput, typename... States >
|
||||
void unwind( const ParseInput& in, States&&... /*unused*/ )
|
||||
{
|
||||
const auto prev = m_stack.back();
|
||||
m_stack.pop_back();
|
||||
std::cerr << std::setw( indent() ) << ' ' << TracerTraits::ansi_unwind << "unwind" << TracerTraits::ansi_reset;
|
||||
if( m_count != prev ) {
|
||||
std::cerr << " #" << prev << ' ' << TracerTraits::ansi_hide << demangle< Rule >() << TracerTraits::ansi_reset;
|
||||
}
|
||||
std::cerr << '\n';
|
||||
update_position( in );
|
||||
}
|
||||
|
||||
template< typename Rule, typename ParseInput, typename... States >
|
||||
void apply( const ParseInput& /*unused*/, States&&... /*unused*/ )
|
||||
{
|
||||
std::cerr << std::setw( static_cast< int >( indent() - TracerTraits::indent_increment ) ) << ' ' << TracerTraits::ansi_apply << "apply" << TracerTraits::ansi_reset << '\n';
|
||||
}
|
||||
|
||||
template< typename Rule, typename ParseInput, typename... States >
|
||||
void apply0( const ParseInput& /*unused*/, States&&... /*unused*/ )
|
||||
{
|
||||
std::cerr << std::setw( static_cast< int >( indent() - TracerTraits::indent_increment ) ) << ' ' << TracerTraits::ansi_apply << "apply0" << TracerTraits::ansi_reset << '\n';
|
||||
}
|
||||
|
||||
template< typename Rule,
|
||||
template< typename... > class Action = nothing,
|
||||
template< typename... > class Control = normal,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
bool parse( ParseInput&& in, States&&... st )
|
||||
{
|
||||
return TAO_PEGTL_NAMESPACE::parse< Rule, Action, state_control< Control >::template type >( in, st..., *this );
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Rule,
|
||||
template< typename... > class Action = nothing,
|
||||
template< typename... > class Control = normal,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
bool standard_trace( ParseInput&& in, States&&... st )
|
||||
{
|
||||
tracer< standard_tracer_traits > tr( in );
|
||||
return tr.parse< Rule, Action, Control >( in, st... );
|
||||
}
|
||||
|
||||
template< typename Rule,
|
||||
template< typename... > class Action = nothing,
|
||||
template< typename... > class Control = normal,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
bool complete_trace( ParseInput&& in, States&&... st )
|
||||
{
|
||||
tracer< complete_tracer_traits > tr( in );
|
||||
return tr.parse< Rule, Action, Control >( in, st... );
|
||||
}
|
||||
|
||||
template< typename Tracer >
|
||||
struct trace
|
||||
: maybe_nothing
|
||||
{
|
||||
template< typename Rule,
|
||||
apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, States&&... st )
|
||||
{
|
||||
if constexpr( sizeof...( st ) == 0 ) {
|
||||
return TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, state_control< Control >::template type >( in, st..., Tracer( in ) );
|
||||
}
|
||||
else if constexpr( !std::is_same_v< std::tuple_element_t< sizeof...( st ) - 1, std::tuple< States... > >, Tracer& > ) {
|
||||
return TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, state_control< Control >::template type >( in, st..., Tracer( in ) );
|
||||
}
|
||||
else {
|
||||
return TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, st... );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
using trace_standard = trace< tracer< standard_tracer_traits > >;
|
||||
using trace_complete = trace< tracer< complete_tracer_traits > >;
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,63 @@
|
|||
// Copyright (c) 2018-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_UINT16_HPP
|
||||
#define TAO_PEGTL_CONTRIB_UINT16_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "../internal/result_on_found.hpp"
|
||||
#include "../internal/rules.hpp"
|
||||
|
||||
#include "internal/peek_mask_uint.hpp"
|
||||
#include "internal/peek_uint.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
namespace uint16_be
|
||||
{
|
||||
// clang-format off
|
||||
struct any : internal::any< internal::peek_uint16_be > {};
|
||||
|
||||
template< std::uint16_t... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_uint16_be, Cs... > {};
|
||||
template< std::uint16_t Lo, std::uint16_t Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_uint16_be, Lo, Hi > {};
|
||||
template< std::uint16_t... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_uint16_be, Cs... > {};
|
||||
template< std::uint16_t Lo, std::uint16_t Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_uint16_be, Lo, Hi > {};
|
||||
template< std::uint16_t... Cs > struct ranges : internal::ranges< internal::peek_uint16_be, Cs... > {};
|
||||
template< std::uint16_t... Cs > struct string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_uint16_be, Cs >... > {};
|
||||
|
||||
template< std::uint16_t M, std::uint16_t... Cs > struct mask_not_one : internal::one< internal::result_on_found::failure, internal::peek_mask_uint16_be< M >, Cs... > {};
|
||||
template< std::uint16_t M, std::uint16_t Lo, std::uint16_t Hi > struct mask_not_range : internal::range< internal::result_on_found::failure, internal::peek_mask_uint16_be< M >, Lo, Hi > {};
|
||||
template< std::uint16_t M, std::uint16_t... Cs > struct mask_one : internal::one< internal::result_on_found::success, internal::peek_mask_uint16_be< M >, Cs... > {};
|
||||
template< std::uint16_t M, std::uint16_t Lo, std::uint16_t Hi > struct mask_range : internal::range< internal::result_on_found::success, internal::peek_mask_uint16_be< M >, Lo, Hi > {};
|
||||
template< std::uint16_t M, std::uint16_t... Cs > struct mask_ranges : internal::ranges< internal::peek_mask_uint16_be< M >, Cs... > {};
|
||||
template< std::uint16_t M, std::uint16_t... Cs > struct mask_string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_mask_uint16_be< M >, Cs >... > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace uint16_be
|
||||
|
||||
namespace uint16_le
|
||||
{
|
||||
// clang-format off
|
||||
struct any : internal::any< internal::peek_uint16_le > {};
|
||||
|
||||
template< std::uint16_t... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_uint16_le, Cs... > {};
|
||||
template< std::uint16_t Lo, std::uint16_t Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_uint16_le, Lo, Hi > {};
|
||||
template< std::uint16_t... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_uint16_le, Cs... > {};
|
||||
template< std::uint16_t Lo, std::uint16_t Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_uint16_le, Lo, Hi > {};
|
||||
template< std::uint16_t... Cs > struct ranges : internal::ranges< internal::peek_uint16_le, Cs... > {};
|
||||
template< std::uint16_t... Cs > struct string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_uint16_le, Cs >... > {};
|
||||
|
||||
template< std::uint16_t M, std::uint16_t... Cs > struct mask_not_one : internal::one< internal::result_on_found::failure, internal::peek_mask_uint16_le< M >, Cs... > {};
|
||||
template< std::uint16_t M, std::uint16_t Lo, std::uint16_t Hi > struct mask_not_range : internal::range< internal::result_on_found::failure, internal::peek_mask_uint16_le< M >, Lo, Hi > {};
|
||||
template< std::uint16_t M, std::uint16_t... Cs > struct mask_one : internal::one< internal::result_on_found::success, internal::peek_mask_uint16_le< M >, Cs... > {};
|
||||
template< std::uint16_t M, std::uint16_t Lo, std::uint16_t Hi > struct mask_range : internal::range< internal::result_on_found::success, internal::peek_mask_uint16_le< M >, Lo, Hi > {};
|
||||
template< std::uint16_t M, std::uint16_t... Cs > struct mask_ranges : internal::ranges< internal::peek_mask_uint16_le< M >, Cs... > {};
|
||||
template< std::uint16_t M, std::uint16_t... Cs > struct mask_string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_mask_uint16_le< M >, Cs >... > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace uint16_le
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,63 @@
|
|||
// Copyright (c) 2018-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_UINT32_HPP
|
||||
#define TAO_PEGTL_CONTRIB_UINT32_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "../internal/result_on_found.hpp"
|
||||
#include "../internal/rules.hpp"
|
||||
|
||||
#include "internal/peek_mask_uint.hpp"
|
||||
#include "internal/peek_uint.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
namespace uint32_be
|
||||
{
|
||||
// clang-format off
|
||||
struct any : internal::any< internal::peek_uint32_be > {};
|
||||
|
||||
template< std::uint32_t... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_uint32_be, Cs... > {};
|
||||
template< std::uint32_t Lo, std::uint32_t Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_uint32_be, Lo, Hi > {};
|
||||
template< std::uint32_t... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_uint32_be, Cs... > {};
|
||||
template< std::uint32_t Lo, std::uint32_t Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_uint32_be, Lo, Hi > {};
|
||||
template< std::uint32_t... Cs > struct ranges : internal::ranges< internal::peek_uint32_be, Cs... > {};
|
||||
template< std::uint32_t... Cs > struct string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_uint32_be, Cs >... > {};
|
||||
|
||||
template< std::uint32_t M, std::uint32_t... Cs > struct mask_not_one : internal::one< internal::result_on_found::failure, internal::peek_mask_uint32_be< M >, Cs... > {};
|
||||
template< std::uint32_t M, std::uint32_t Lo, std::uint32_t Hi > struct mask_not_range : internal::range< internal::result_on_found::failure, internal::peek_mask_uint32_be< M >, Lo, Hi > {};
|
||||
template< std::uint32_t M, std::uint32_t... Cs > struct mask_one : internal::one< internal::result_on_found::success, internal::peek_mask_uint32_be< M >, Cs... > {};
|
||||
template< std::uint32_t M, std::uint32_t Lo, std::uint32_t Hi > struct mask_range : internal::range< internal::result_on_found::success, internal::peek_mask_uint32_be< M >, Lo, Hi > {};
|
||||
template< std::uint32_t M, std::uint32_t... Cs > struct mask_ranges : internal::ranges< internal::peek_mask_uint32_be< M >, Cs... > {};
|
||||
template< std::uint32_t M, std::uint32_t... Cs > struct mask_string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_mask_uint32_be< M >, Cs >... > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace uint32_be
|
||||
|
||||
namespace uint32_le
|
||||
{
|
||||
// clang-format off
|
||||
struct any : internal::any< internal::peek_uint32_le > {};
|
||||
|
||||
template< std::uint32_t... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_uint32_le, Cs... > {};
|
||||
template< std::uint32_t Lo, std::uint32_t Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_uint32_le, Lo, Hi > {};
|
||||
template< std::uint32_t... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_uint32_le, Cs... > {};
|
||||
template< std::uint32_t Lo, std::uint32_t Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_uint32_le, Lo, Hi > {};
|
||||
template< std::uint32_t... Cs > struct ranges : internal::ranges< internal::peek_uint32_le, Cs... > {};
|
||||
template< std::uint32_t... Cs > struct string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_uint32_le, Cs >... > {};
|
||||
|
||||
template< std::uint32_t M, std::uint32_t... Cs > struct mask_not_one : internal::one< internal::result_on_found::failure, internal::peek_mask_uint32_le< M >, Cs... > {};
|
||||
template< std::uint32_t M, std::uint32_t Lo, std::uint32_t Hi > struct mask_not_range : internal::range< internal::result_on_found::failure, internal::peek_mask_uint32_le< M >, Lo, Hi > {};
|
||||
template< std::uint32_t M, std::uint32_t... Cs > struct mask_one : internal::one< internal::result_on_found::success, internal::peek_mask_uint32_le< M >, Cs... > {};
|
||||
template< std::uint32_t M, std::uint32_t Lo, std::uint32_t Hi > struct mask_range : internal::range< internal::result_on_found::success, internal::peek_mask_uint32_le< M >, Lo, Hi > {};
|
||||
template< std::uint32_t M, std::uint32_t... Cs > struct mask_ranges : internal::ranges< internal::peek_mask_uint32_le< M >, Cs... > {};
|
||||
template< std::uint32_t M, std::uint32_t... Cs > struct mask_string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_mask_uint32_le< M >, Cs >... > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace uint32_le
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,64 @@
|
|||
// Copyright (c) 2018-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_UINT64_HPP
|
||||
#define TAO_PEGTL_CONTRIB_UINT64_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "../internal/result_on_found.hpp"
|
||||
#include "../internal/rules.hpp"
|
||||
|
||||
#include "internal/peek_mask_uint.hpp"
|
||||
#include "internal/peek_uint.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
namespace uint64_be
|
||||
{
|
||||
// clang-format off
|
||||
struct any : internal::any< internal::peek_uint64_be > {};
|
||||
|
||||
template< std::uint64_t... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_uint64_be, Cs... > {};
|
||||
template< std::uint64_t Lo, std::uint64_t Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_uint64_be, Lo, Hi > {};
|
||||
template< std::uint64_t... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_uint64_be, Cs... > {};
|
||||
template< std::uint64_t Lo, std::uint64_t Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_uint64_be, Lo, Hi > {};
|
||||
template< std::uint64_t... Cs > struct ranges : internal::ranges< internal::peek_uint64_be, Cs... > {};
|
||||
template< std::uint64_t... Cs > struct string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_uint64_be, Cs >... > {};
|
||||
|
||||
|
||||
template< std::uint64_t M, std::uint64_t... Cs > struct mask_not_one : internal::one< internal::result_on_found::failure, internal::peek_mask_uint64_be< M >, Cs... > {};
|
||||
template< std::uint64_t M, std::uint64_t Lo, std::uint64_t Hi > struct mask_not_range : internal::range< internal::result_on_found::failure, internal::peek_mask_uint64_be< M >, Lo, Hi > {};
|
||||
template< std::uint64_t M, std::uint64_t... Cs > struct mask_one : internal::one< internal::result_on_found::success, internal::peek_mask_uint64_be< M >, Cs... > {};
|
||||
template< std::uint64_t M, std::uint64_t Lo, std::uint64_t Hi > struct mask_range : internal::range< internal::result_on_found::success, internal::peek_mask_uint64_be< M >, Lo, Hi > {};
|
||||
template< std::uint64_t M, std::uint64_t... Cs > struct mask_ranges : internal::ranges< internal::peek_mask_uint64_be< M >, Cs... > {};
|
||||
template< std::uint64_t M, std::uint64_t... Cs > struct mask_string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_mask_uint64_be< M >, Cs >... > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace uint64_be
|
||||
|
||||
namespace uint64_le
|
||||
{
|
||||
// clang-format off
|
||||
struct any : internal::any< internal::peek_uint64_le > {};
|
||||
|
||||
template< std::uint64_t... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_uint64_le, Cs... > {};
|
||||
template< std::uint64_t Lo, std::uint64_t Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_uint64_le, Lo, Hi > {};
|
||||
template< std::uint64_t... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_uint64_le, Cs... > {};
|
||||
template< std::uint64_t Lo, std::uint64_t Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_uint64_le, Lo, Hi > {};
|
||||
template< std::uint64_t... Cs > struct ranges : internal::ranges< internal::peek_uint64_le, Cs... > {};
|
||||
template< std::uint64_t... Cs > struct string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_uint64_le, Cs >... > {};
|
||||
|
||||
template< std::uint64_t M, std::uint64_t... Cs > struct mask_not_one : internal::one< internal::result_on_found::failure, internal::peek_mask_uint64_le< M >, Cs... > {};
|
||||
template< std::uint64_t M, std::uint64_t Lo, std::uint64_t Hi > struct mask_not_range : internal::range< internal::result_on_found::failure, internal::peek_mask_uint64_le< M >, Lo, Hi > {};
|
||||
template< std::uint64_t M, std::uint64_t... Cs > struct mask_one : internal::one< internal::result_on_found::success, internal::peek_mask_uint64_le< M >, Cs... > {};
|
||||
template< std::uint64_t M, std::uint64_t Lo, std::uint64_t Hi > struct mask_range : internal::range< internal::result_on_found::success, internal::peek_mask_uint64_le< M >, Lo, Hi > {};
|
||||
template< std::uint64_t M, std::uint64_t... Cs > struct mask_ranges : internal::ranges< internal::peek_mask_uint64_le< M >, Cs... > {};
|
||||
template< std::uint64_t M, std::uint64_t... Cs > struct mask_string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_mask_uint64_le< M >, Cs >... > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace uint64_le
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright (c) 2018-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_UINT8_HPP
|
||||
#define TAO_PEGTL_CONTRIB_UINT8_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "../internal/result_on_found.hpp"
|
||||
#include "../internal/rules.hpp"
|
||||
|
||||
#include "internal/peek_mask_uint8.hpp"
|
||||
#include "internal/peek_uint8.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::uint8
|
||||
{
|
||||
// clang-format off
|
||||
struct any : internal::any< internal::peek_uint8 > {};
|
||||
|
||||
template< std::uint8_t... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_uint8, Cs... > {};
|
||||
template< std::uint8_t Lo, std::uint8_t Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_uint8, Lo, Hi > {};
|
||||
template< std::uint8_t... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_uint8, Cs... > {};
|
||||
template< std::uint8_t Lo, std::uint8_t Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_uint8, Lo, Hi > {};
|
||||
template< std::uint8_t... Cs > struct ranges : internal::ranges< internal::peek_uint8, Cs... > {};
|
||||
template< std::uint8_t... Cs > struct string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_uint8, Cs >... > {};
|
||||
|
||||
template< std::uint8_t M, std::uint8_t... Cs > struct mask_not_one : internal::one< internal::result_on_found::failure, internal::peek_mask_uint8< M >, Cs... > {};
|
||||
template< std::uint8_t M, std::uint8_t Lo, std::uint8_t Hi > struct mask_not_range : internal::range< internal::result_on_found::failure, internal::peek_mask_uint8< M >, Lo, Hi > {};
|
||||
template< std::uint8_t M, std::uint8_t... Cs > struct mask_one : internal::one< internal::result_on_found::success, internal::peek_mask_uint8< M >, Cs... > {};
|
||||
template< std::uint8_t M, std::uint8_t Lo, std::uint8_t Hi > struct mask_range : internal::range< internal::result_on_found::success, internal::peek_mask_uint8< M >, Lo, Hi > {};
|
||||
template< std::uint8_t M, std::uint8_t... Cs > struct mask_ranges : internal::ranges< internal::peek_mask_uint8< M >, Cs... > {};
|
||||
template< std::uint8_t M, std::uint8_t... Cs > struct mask_string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_mask_uint8< M >, Cs >... > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::uint8
|
||||
|
||||
#endif
|
|
@ -0,0 +1,215 @@
|
|||
// Copyright (c) 2014-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_UNESCAPE_HPP
|
||||
#define TAO_PEGTL_CONTRIB_UNESCAPE_HPP
|
||||
|
||||
#include <cassert>
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
#include "../ascii.hpp"
|
||||
#include "../config.hpp"
|
||||
#include "../parse_error.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::unescape
|
||||
{
|
||||
// Utility functions for the unescape actions.
|
||||
|
||||
[[nodiscard]] inline bool utf8_append_utf32( std::string& string, const unsigned utf32 )
|
||||
{
|
||||
if( utf32 <= 0x7f ) {
|
||||
string += char( utf32 & 0xff );
|
||||
return true;
|
||||
}
|
||||
if( utf32 <= 0x7ff ) {
|
||||
char tmp[] = { char( ( ( utf32 & 0x7c0 ) >> 6 ) | 0xc0 ),
|
||||
char( ( ( utf32 & 0x03f ) ) | 0x80 ) };
|
||||
string.append( tmp, sizeof( tmp ) );
|
||||
return true;
|
||||
}
|
||||
if( utf32 <= 0xffff ) {
|
||||
if( utf32 >= 0xd800 && utf32 <= 0xdfff ) {
|
||||
// nope, this is a UTF-16 surrogate
|
||||
return false;
|
||||
}
|
||||
char tmp[] = { char( ( ( utf32 & 0xf000 ) >> 12 ) | 0xe0 ),
|
||||
char( ( ( utf32 & 0x0fc0 ) >> 6 ) | 0x80 ),
|
||||
char( ( ( utf32 & 0x003f ) ) | 0x80 ) };
|
||||
string.append( tmp, sizeof( tmp ) );
|
||||
return true;
|
||||
}
|
||||
if( utf32 <= 0x10ffff ) {
|
||||
char tmp[] = { char( ( ( utf32 & 0x1c0000 ) >> 18 ) | 0xf0 ),
|
||||
char( ( ( utf32 & 0x03f000 ) >> 12 ) | 0x80 ),
|
||||
char( ( ( utf32 & 0x000fc0 ) >> 6 ) | 0x80 ),
|
||||
char( ( ( utf32 & 0x00003f ) ) | 0x80 ) };
|
||||
string.append( tmp, sizeof( tmp ) );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// This function MUST only be called for characters matching TAO_PEGTL_NAMESPACE::ascii::xdigit!
|
||||
template< typename I >
|
||||
[[nodiscard]] I unhex_char( const char c )
|
||||
{
|
||||
switch( c ) {
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
return I( c - '0' );
|
||||
case 'a':
|
||||
case 'b':
|
||||
case 'c':
|
||||
case 'd':
|
||||
case 'e':
|
||||
case 'f':
|
||||
return I( c - 'a' + 10 );
|
||||
case 'A':
|
||||
case 'B':
|
||||
case 'C':
|
||||
case 'D':
|
||||
case 'E':
|
||||
case 'F':
|
||||
return I( c - 'A' + 10 );
|
||||
default: // LCOV_EXCL_LINE
|
||||
std::terminate(); // LCOV_EXCL_LINE
|
||||
}
|
||||
}
|
||||
|
||||
template< typename I >
|
||||
[[nodiscard]] I unhex_string( const char* begin, const char* end )
|
||||
{
|
||||
I r = 0;
|
||||
while( begin != end ) {
|
||||
r <<= 4;
|
||||
r += unhex_char< I >( *begin++ );
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
// Actions for common unescape situations.
|
||||
|
||||
struct append_all
|
||||
{
|
||||
template< typename ActionInput >
|
||||
static void apply( const ActionInput& in, std::string& s )
|
||||
{
|
||||
s.append( in.begin(), in.size() );
|
||||
}
|
||||
};
|
||||
|
||||
// This action MUST be called for a character matching T which MUST be TAO_PEGTL_NAMESPACE::one< ... >.
|
||||
template< typename T, char... Rs >
|
||||
struct unescape_c
|
||||
{
|
||||
template< typename ActionInput >
|
||||
static void apply( const ActionInput& in, std::string& s )
|
||||
{
|
||||
assert( in.size() == 1 );
|
||||
s += apply_one( in, static_cast< const T* >( nullptr ) );
|
||||
}
|
||||
|
||||
template< typename ActionInput, char... Qs >
|
||||
[[nodiscard]] static char apply_one( const ActionInput& in, const one< Qs... >* /*unused*/ )
|
||||
{
|
||||
static_assert( sizeof...( Qs ) == sizeof...( Rs ), "size mismatch between escaped characters and their mappings" );
|
||||
return apply_two( in, { Qs... }, { Rs... } );
|
||||
}
|
||||
|
||||
template< typename ActionInput >
|
||||
[[nodiscard]] static char apply_two( const ActionInput& in, const std::initializer_list< char >& q, const std::initializer_list< char >& r )
|
||||
{
|
||||
const char c = *in.begin();
|
||||
for( std::size_t i = 0; i < q.size(); ++i ) {
|
||||
if( *( q.begin() + i ) == c ) {
|
||||
return *( r.begin() + i );
|
||||
}
|
||||
}
|
||||
std::terminate(); // LCOV_EXCL_LINE
|
||||
}
|
||||
};
|
||||
|
||||
// See src/example/pegtl/unescape.cpp for why the following two actions
|
||||
// skip the first input character. They also MUST be called
|
||||
// with non-empty matched inputs!
|
||||
|
||||
struct unescape_u
|
||||
{
|
||||
#if defined( __cpp_exceptions )
|
||||
template< typename ActionInput >
|
||||
static void apply( const ActionInput& in, std::string& s )
|
||||
{
|
||||
assert( !in.empty() ); // First character MUST be present, usually 'u' or 'U'.
|
||||
if( !utf8_append_utf32( s, unhex_string< unsigned >( in.begin() + 1, in.end() ) ) ) {
|
||||
throw parse_error( "invalid escaped unicode code point", in );
|
||||
}
|
||||
}
|
||||
#else
|
||||
template< typename ActionInput >
|
||||
static bool apply( const ActionInput& in, std::string& s )
|
||||
{
|
||||
assert( !in.empty() ); // First character MUST be present, usually 'u' or 'U'.
|
||||
return utf8_append_utf32( s, unhex_string< unsigned >( in.begin() + 1, in.end() ) );
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
struct unescape_x
|
||||
{
|
||||
template< typename ActionInput >
|
||||
static void apply( const ActionInput& in, std::string& s )
|
||||
{
|
||||
assert( !in.empty() ); // First character MUST be present, usually 'x'.
|
||||
s += unhex_string< char >( in.begin() + 1, in.end() );
|
||||
}
|
||||
};
|
||||
|
||||
// The unescape_j action is similar to unescape_u, however unlike
|
||||
// unescape_u it
|
||||
// (a) assumes exactly 4 hexdigits per escape sequence,
|
||||
// (b) accepts multiple consecutive escaped 16-bit values.
|
||||
// When applied to more than one escape sequence, unescape_j
|
||||
// translates UTF-16 surrogate pairs in the input into a single
|
||||
// UTF-8 sequence in s, as required for JSON by RFC 8259.
|
||||
|
||||
struct unescape_j
|
||||
{
|
||||
template< typename ActionInput >
|
||||
static bool apply( const ActionInput& in, std::string& s )
|
||||
{
|
||||
assert( ( ( in.size() + 1 ) % 6 ) == 0 ); // Expects multiple "\\u1234", starting with the first "u".
|
||||
for( const char* b = in.begin() + 1; b < in.end(); b += 6 ) {
|
||||
const auto c = unhex_string< unsigned >( b, b + 4 );
|
||||
if( ( 0xd800 <= c ) && ( c <= 0xdbff ) && ( b + 6 < in.end() ) ) {
|
||||
const auto d = unhex_string< unsigned >( b + 6, b + 10 );
|
||||
if( ( 0xdc00 <= d ) && ( d <= 0xdfff ) ) {
|
||||
b += 6;
|
||||
(void)utf8_append_utf32( s, ( ( ( c & 0x03ff ) << 10 ) | ( d & 0x03ff ) ) + 0x10000 );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if( !utf8_append_utf32( s, c ) ) {
|
||||
#if defined( __cpp_exceptions )
|
||||
throw parse_error( "invalid escaped unicode code point", in );
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::unescape
|
||||
|
||||
#endif
|
|
@ -0,0 +1,112 @@
|
|||
// Copyright (c) 2014-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_URI_HPP
|
||||
#define TAO_PEGTL_CONTRIB_URI_HPP
|
||||
|
||||
#if !defined( __cpp_exceptions )
|
||||
#error "Exception support required for tao/pegtl/contrib/uri.hpp"
|
||||
#else
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "../ascii.hpp"
|
||||
#include "../config.hpp"
|
||||
#include "../rules.hpp"
|
||||
#include "../utf8.hpp"
|
||||
|
||||
#include "abnf.hpp"
|
||||
#include "integer.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::uri
|
||||
{
|
||||
// URI grammar according to RFC 3986.
|
||||
|
||||
// This grammar is a direct PEG translation of the original URI grammar.
|
||||
// It should be considered experimental -- in case of any issues, in particular
|
||||
// missing rules for attached actions, please contact the developers.
|
||||
|
||||
// Note that this grammar has multiple top-level rules.
|
||||
|
||||
using dot = one< '.' >;
|
||||
using colon = one< ':' >;
|
||||
|
||||
// clang-format off
|
||||
struct dec_octet : maximum_rule< std::uint8_t > {};
|
||||
|
||||
struct IPv4address : seq< dec_octet, dot, dec_octet, dot, dec_octet, dot, dec_octet > {};
|
||||
|
||||
struct h16 : rep_min_max< 1, 4, abnf::HEXDIG > {};
|
||||
struct ls32 : sor< seq< h16, colon, h16 >, IPv4address > {};
|
||||
|
||||
struct dcolon : two< ':' > {};
|
||||
|
||||
struct IPv6address : sor< seq< rep< 6, h16, colon >, ls32 >,
|
||||
seq< dcolon, rep< 5, h16, colon >, ls32 >,
|
||||
seq< opt< h16 >, dcolon, rep< 4, h16, colon >, ls32 >,
|
||||
seq< opt< h16, opt< colon, h16 > >, dcolon, rep< 3, h16, colon >, ls32 >,
|
||||
seq< opt< h16, rep_opt< 2, colon, h16 > >, dcolon, rep< 2, h16, colon >, ls32 >,
|
||||
seq< opt< h16, rep_opt< 3, colon, h16 > >, dcolon, h16, colon, ls32 >,
|
||||
seq< opt< h16, rep_opt< 4, colon, h16 > >, dcolon, ls32 >,
|
||||
seq< opt< h16, rep_opt< 5, colon, h16 > >, dcolon, h16 >,
|
||||
seq< opt< h16, rep_opt< 6, colon, h16 > >, dcolon > > {};
|
||||
|
||||
struct gen_delims : one< ':', '/', '?', '#', '[', ']', '@' > {};
|
||||
struct sub_delims : one< '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=' > {};
|
||||
|
||||
struct unreserved : sor< abnf::ALPHA, abnf::DIGIT, one< '-', '.', '_', '~' > > {};
|
||||
struct reserved : sor< gen_delims, sub_delims > {};
|
||||
|
||||
struct IPvFuture : if_must< one< 'v', 'V' >, plus< abnf::HEXDIG >, dot, plus< sor< unreserved, sub_delims, colon > > > {};
|
||||
|
||||
struct IP_literal : if_must< one< '[' >, sor< IPvFuture, IPv6address >, one< ']' > > {};
|
||||
|
||||
struct pct_encoded : if_must< one< '%' >, abnf::HEXDIG, abnf::HEXDIG > {};
|
||||
struct pchar : sor< unreserved, pct_encoded, sub_delims, one< ':', '@' > > {};
|
||||
|
||||
struct query : star< sor< pchar, one< '/', '?' > > > {};
|
||||
struct fragment : star< sor< pchar, one< '/', '?' > > > {};
|
||||
|
||||
struct segment : star< pchar > {};
|
||||
struct segment_nz : plus< pchar > {};
|
||||
struct segment_nz_nc : plus< sor< unreserved, pct_encoded, sub_delims, one< '@' > > > {}; // non-zero-length segment without any colon ":"
|
||||
|
||||
struct path_abempty : star< one< '/' >, segment > {};
|
||||
struct path_absolute : seq< one< '/' >, opt< segment_nz, star< one< '/' >, segment > > > {};
|
||||
struct path_noscheme : seq< segment_nz_nc, star< one< '/' >, segment > > {};
|
||||
struct path_rootless : seq< segment_nz, star< one< '/' >, segment > > {};
|
||||
struct path_empty : success {};
|
||||
|
||||
struct path : sor< path_noscheme, // begins with a non-colon segment
|
||||
path_rootless, // begins with a segment
|
||||
path_absolute, // begins with "/" but not "//"
|
||||
path_abempty > {}; // begins with "/" or is empty
|
||||
|
||||
struct reg_name : star< sor< unreserved, pct_encoded, sub_delims > > {};
|
||||
|
||||
struct port : star< abnf::DIGIT > {};
|
||||
struct host : sor< IP_literal, IPv4address, reg_name > {};
|
||||
struct userinfo : star< sor< unreserved, pct_encoded, sub_delims, colon > > {};
|
||||
struct opt_userinfo : opt< userinfo, one< '@' > > {};
|
||||
struct authority : seq< opt_userinfo, host, opt< colon, port > > {};
|
||||
|
||||
struct scheme : seq< abnf::ALPHA, star< sor< abnf::ALPHA, abnf::DIGIT, one< '+', '-', '.' > > > > {};
|
||||
|
||||
using dslash = two< '/' >;
|
||||
using opt_query = opt_must< one< '?' >, query >;
|
||||
using opt_fragment = opt_must< one< '#' >, fragment >;
|
||||
|
||||
struct hier_part : sor< if_must< dslash, authority, path_abempty >, path_rootless, path_absolute, path_empty > {};
|
||||
struct relative_part : sor< if_must< dslash, authority, path_abempty >, path_noscheme, path_absolute, path_empty > {};
|
||||
struct relative_ref : seq< relative_part, opt_query, opt_fragment > {};
|
||||
|
||||
struct URI : seq< scheme, one< ':' >, hier_part, opt_query, opt_fragment > {};
|
||||
struct URI_reference : sor< URI, relative_ref > {};
|
||||
struct absolute_URI : seq< scheme, one< ':' >, hier_part, opt_query > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::uri
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,58 @@
|
|||
// Copyright (c) 2015-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_UTF16_HPP
|
||||
#define TAO_PEGTL_CONTRIB_UTF16_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "../internal/result_on_found.hpp"
|
||||
#include "../internal/rules.hpp"
|
||||
|
||||
#include "internal/peek_utf16.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
namespace utf16_be
|
||||
{
|
||||
// clang-format off
|
||||
struct any : internal::any< internal::peek_utf16_be > {};
|
||||
struct bom : internal::one< internal::result_on_found::success, internal::peek_utf16_be, 0xfeff > {};
|
||||
template< char32_t... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_utf16_be, Cs... > {};
|
||||
template< char32_t Lo, char32_t Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_utf16_be, Lo, Hi > {};
|
||||
template< char32_t... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_utf16_be, Cs... > {};
|
||||
template< char32_t Lo, char32_t Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_utf16_be, Lo, Hi > {};
|
||||
template< char32_t... Cs > struct ranges : internal::ranges< internal::peek_utf16_be, Cs... > {};
|
||||
template< char32_t... Cs > struct string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_utf16_be, Cs >... > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace utf16_be
|
||||
|
||||
namespace utf16_le
|
||||
{
|
||||
// clang-format off
|
||||
struct any : internal::any< internal::peek_utf16_le > {};
|
||||
struct bom : internal::one< internal::result_on_found::success, internal::peek_utf16_le, 0xfeff > {};
|
||||
template< char32_t... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_utf16_le, Cs... > {};
|
||||
template< char32_t Lo, char32_t Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_utf16_le, Lo, Hi > {};
|
||||
template< char32_t... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_utf16_le, Cs... > {};
|
||||
template< char32_t Lo, char32_t Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_utf16_le, Lo, Hi > {};
|
||||
template< char32_t... Cs > struct ranges : internal::ranges< internal::peek_utf16_le, Cs... > {};
|
||||
template< char32_t... Cs > struct string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_utf16_le, Cs >... > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace utf16_le
|
||||
|
||||
#if defined( _WIN32 ) && !defined( __MINGW32__ ) && !defined( __CYGWIN__ )
|
||||
namespace utf16 = utf16_le;
|
||||
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
namespace utf16 = utf16_le;
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
namespace utf16 = utf16_be;
|
||||
#else
|
||||
#error Unknown endianness.
|
||||
#endif
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,58 @@
|
|||
// Copyright (c) 2014-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CONTRIB_UTF32_HPP
|
||||
#define TAO_PEGTL_CONTRIB_UTF32_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "../internal/result_on_found.hpp"
|
||||
#include "../internal/rules.hpp"
|
||||
|
||||
#include "internal/peek_utf32.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
namespace utf32_be
|
||||
{
|
||||
// clang-format off
|
||||
struct any : internal::any< internal::peek_utf32_be > {};
|
||||
struct bom : internal::one< internal::result_on_found::success, internal::peek_utf32_be, 0xfeff > {};
|
||||
template< char32_t... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_utf32_be, Cs... > {};
|
||||
template< char32_t Lo, char32_t Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_utf32_be, Lo, Hi > {};
|
||||
template< char32_t... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_utf32_be, Cs... > {};
|
||||
template< char32_t Lo, char32_t Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_utf32_be, Lo, Hi > {};
|
||||
template< char32_t... Cs > struct ranges : internal::ranges< internal::peek_utf32_be, Cs... > {};
|
||||
template< char32_t... Cs > struct string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_utf32_be, Cs >... > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace utf32_be
|
||||
|
||||
namespace utf32_le
|
||||
{
|
||||
// clang-format off
|
||||
struct any : internal::any< internal::peek_utf32_le > {};
|
||||
struct bom : internal::one< internal::result_on_found::success, internal::peek_utf32_le, 0xfeff > {};
|
||||
template< char32_t... Cs > struct not_one : internal::one< internal::result_on_found::failure, internal::peek_utf32_le, Cs... > {};
|
||||
template< char32_t Lo, char32_t Hi > struct not_range : internal::range< internal::result_on_found::failure, internal::peek_utf32_le, Lo, Hi > {};
|
||||
template< char32_t... Cs > struct one : internal::one< internal::result_on_found::success, internal::peek_utf32_le, Cs... > {};
|
||||
template< char32_t Lo, char32_t Hi > struct range : internal::range< internal::result_on_found::success, internal::peek_utf32_le, Lo, Hi > {};
|
||||
template< char32_t... Cs > struct ranges : internal::ranges< internal::peek_utf32_le, Cs... > {};
|
||||
template< char32_t... Cs > struct string : internal::seq< internal::one< internal::result_on_found::success, internal::peek_utf32_le, Cs >... > {};
|
||||
// clang-format on
|
||||
|
||||
} // namespace utf32_le
|
||||
|
||||
#if defined( _WIN32 ) && !defined( __MINGW32__ ) && !defined( __CYGWIN__ )
|
||||
namespace utf32 = utf32_le;
|
||||
#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
namespace utf32 = utf32_le;
|
||||
#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
namespace utf32 = utf32_be;
|
||||
#else
|
||||
#error Unknown endianness.
|
||||
#endif
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) 2017-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_CSTREAM_INPUT_HPP
|
||||
#define TAO_PEGTL_CSTREAM_INPUT_HPP
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include "buffer_input.hpp"
|
||||
#include "config.hpp"
|
||||
#include "eol.hpp"
|
||||
|
||||
#include "internal/cstream_reader.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
template< typename Eol = eol::lf_crlf, std::size_t Chunk = 64 >
|
||||
struct cstream_input
|
||||
: buffer_input< internal::cstream_reader, Eol, std::string, Chunk >
|
||||
{
|
||||
template< typename T >
|
||||
cstream_input( std::FILE* in_stream, const std::size_t in_maximum, T&& in_source )
|
||||
: buffer_input< internal::cstream_reader, Eol, std::string, Chunk >( std::forward< T >( in_source ), in_maximum, in_stream )
|
||||
{}
|
||||
};
|
||||
|
||||
template< typename... Ts >
|
||||
cstream_input( Ts&&... ) -> cstream_input<>;
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,141 @@
|
|||
// Copyright (c) 2014-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_DEMANGLE_HPP
|
||||
#define TAO_PEGTL_DEMANGLE_HPP
|
||||
|
||||
#include <ciso646>
|
||||
#include <string_view>
|
||||
|
||||
#include "config.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
#if defined( __clang__ )
|
||||
|
||||
#if defined( _LIBCPP_VERSION )
|
||||
|
||||
template< typename T >
|
||||
[[nodiscard]] constexpr std::string_view demangle() noexcept
|
||||
{
|
||||
constexpr std::string_view sv = __PRETTY_FUNCTION__;
|
||||
constexpr auto begin = sv.find( '=' );
|
||||
static_assert( begin != std::string_view::npos );
|
||||
return sv.substr( begin + 2, sv.size() - begin - 3 );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// When using libstdc++ with clang, std::string_view::find is not constexpr :(
|
||||
template< char C >
|
||||
constexpr const char* find( const char* p, std::size_t n ) noexcept
|
||||
{
|
||||
while( n ) {
|
||||
if( *p == C ) {
|
||||
return p;
|
||||
}
|
||||
++p;
|
||||
--n;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
[[nodiscard]] constexpr std::string_view demangle() noexcept
|
||||
{
|
||||
constexpr std::string_view sv = __PRETTY_FUNCTION__;
|
||||
constexpr auto begin = find< '=' >( sv.data(), sv.size() );
|
||||
static_assert( begin != nullptr );
|
||||
return { begin + 2, sv.data() + sv.size() - begin - 3 };
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#elif defined( __GNUC__ )
|
||||
|
||||
#if( __GNUC__ == 7 )
|
||||
|
||||
// GCC 7 wrongly sometimes disallows __PRETTY_FUNCTION__ in constexpr functions,
|
||||
// therefore we drop the 'constexpr' and hope for the best.
|
||||
template< typename T >
|
||||
[[nodiscard]] std::string_view demangle() noexcept
|
||||
{
|
||||
const std::string_view sv = __PRETTY_FUNCTION__;
|
||||
const auto begin = sv.find( '=' );
|
||||
const auto tmp = sv.substr( begin + 2 );
|
||||
const auto end = tmp.rfind( ';' );
|
||||
return tmp.substr( 0, end );
|
||||
}
|
||||
|
||||
#elif( __GNUC__ == 9 ) && ( __GNUC_MINOR__ < 3 )
|
||||
|
||||
// GCC 9.1 and 9.2 have a bug that leads to truncated __PRETTY_FUNCTION__ names,
|
||||
// see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91155
|
||||
template< typename T >
|
||||
[[nodiscard]] constexpr std::string_view demangle() noexcept
|
||||
{
|
||||
// fallback: requires RTTI, no demangling
|
||||
return typeid( T ).name();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template< typename T >
|
||||
[[nodiscard]] constexpr std::string_view demangle() noexcept
|
||||
{
|
||||
constexpr std::string_view sv = __PRETTY_FUNCTION__;
|
||||
constexpr auto begin = sv.find( '=' );
|
||||
static_assert( begin != std::string_view::npos );
|
||||
constexpr auto tmp = sv.substr( begin + 2 );
|
||||
constexpr auto end = tmp.rfind( ';' );
|
||||
static_assert( end != std::string_view::npos );
|
||||
return tmp.substr( 0, end );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#elif defined( _MSC_VER )
|
||||
|
||||
#if( _MSC_VER < 1920 )
|
||||
|
||||
template< typename T >
|
||||
[[nodiscard]] constexpr std::string_view demangle() noexcept
|
||||
{
|
||||
const std::string_view sv = __FUNCSIG__;
|
||||
const auto begin = sv.find( "demangle<" );
|
||||
const auto tmp = sv.substr( begin + 9 );
|
||||
const auto end = tmp.rfind( '>' );
|
||||
return tmp.substr( 0, end );
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template< typename T >
|
||||
[[nodiscard]] constexpr std::string_view demangle() noexcept
|
||||
{
|
||||
constexpr std::string_view sv = __FUNCSIG__;
|
||||
constexpr auto begin = sv.find( "demangle<" );
|
||||
static_assert( begin != std::string_view::npos );
|
||||
constexpr auto tmp = sv.substr( begin + 9 );
|
||||
constexpr auto end = tmp.rfind( '>' );
|
||||
static_assert( end != std::string_view::npos );
|
||||
return tmp.substr( 0, end );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
template< typename T >
|
||||
[[nodiscard]] constexpr std::string_view demangle() noexcept
|
||||
{
|
||||
// fallback: requires RTTI, no demangling
|
||||
return typeid( T ).name();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) 2019-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_DISABLE_ACTION_HPP
|
||||
#define TAO_PEGTL_DISABLE_ACTION_HPP
|
||||
|
||||
#include "apply_mode.hpp"
|
||||
#include "config.hpp"
|
||||
#include "match.hpp"
|
||||
#include "nothing.hpp"
|
||||
#include "rewind_mode.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
struct disable_action
|
||||
: maybe_nothing
|
||||
{
|
||||
template< typename Rule,
|
||||
apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, States&&... st )
|
||||
{
|
||||
return TAO_PEGTL_NAMESPACE::match< Rule, apply_mode::nothing, M, Action, Control >( in, st... );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (c) 2019-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_DISCARD_INPUT_HPP
|
||||
#define TAO_PEGTL_DISCARD_INPUT_HPP
|
||||
|
||||
#include "apply_mode.hpp"
|
||||
#include "config.hpp"
|
||||
#include "match.hpp"
|
||||
#include "nothing.hpp"
|
||||
#include "rewind_mode.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
struct discard_input
|
||||
: maybe_nothing
|
||||
{
|
||||
template< typename Rule,
|
||||
apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, States&&... st )
|
||||
{
|
||||
const bool result = TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, st... );
|
||||
in.discard();
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (c) 2019-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_DISCARD_INPUT_ON_FAILURE_HPP
|
||||
#define TAO_PEGTL_DISCARD_INPUT_ON_FAILURE_HPP
|
||||
|
||||
#include "apply_mode.hpp"
|
||||
#include "config.hpp"
|
||||
#include "match.hpp"
|
||||
#include "nothing.hpp"
|
||||
#include "rewind_mode.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
struct discard_input_on_failure
|
||||
: maybe_nothing
|
||||
{
|
||||
template< typename Rule,
|
||||
apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, States&&... st )
|
||||
{
|
||||
const bool result = TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, st... );
|
||||
if( !result ) {
|
||||
in.discard();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (c) 2019-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_DISCARD_INPUT_ON_SUCCESS_HPP
|
||||
#define TAO_PEGTL_DISCARD_INPUT_ON_SUCCESS_HPP
|
||||
|
||||
#include "apply_mode.hpp"
|
||||
#include "config.hpp"
|
||||
#include "match.hpp"
|
||||
#include "nothing.hpp"
|
||||
#include "rewind_mode.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
struct discard_input_on_success
|
||||
: maybe_nothing
|
||||
{
|
||||
template< typename Rule,
|
||||
apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, States&&... st )
|
||||
{
|
||||
const bool result = TAO_PEGTL_NAMESPACE::match< Rule, A, M, Action, Control >( in, st... );
|
||||
if( result ) {
|
||||
in.discard();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,36 @@
|
|||
// Copyright (c) 2019-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_ENABLE_ACTION_HPP
|
||||
#define TAO_PEGTL_ENABLE_ACTION_HPP
|
||||
|
||||
#include "apply_mode.hpp"
|
||||
#include "config.hpp"
|
||||
#include "match.hpp"
|
||||
#include "nothing.hpp"
|
||||
#include "rewind_mode.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
struct enable_action
|
||||
: maybe_nothing
|
||||
{
|
||||
template< typename Rule,
|
||||
apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, States&&... st )
|
||||
{
|
||||
return TAO_PEGTL_NAMESPACE::match< Rule, apply_mode::action, M, Action, Control >( in, st... );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright (c) 2016-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_EOL_HPP
|
||||
#define TAO_PEGTL_EOL_HPP
|
||||
|
||||
#include "config.hpp"
|
||||
|
||||
#include "internal/eol.hpp"
|
||||
|
||||
#include "internal/cr_crlf_eol.hpp"
|
||||
#include "internal/cr_eol.hpp"
|
||||
#include "internal/crlf_eol.hpp"
|
||||
#include "internal/lf_crlf_eol.hpp"
|
||||
#include "internal/lf_eol.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
inline namespace ascii
|
||||
{
|
||||
// Struct eol is both a rule and a pseudo-namespace for the
|
||||
// member structs cr, etc. (which are not themselves rules).
|
||||
|
||||
struct eol
|
||||
: internal::eol
|
||||
{
|
||||
// clang-format off
|
||||
struct cr : internal::cr_eol {};
|
||||
struct cr_crlf : internal::cr_crlf_eol {};
|
||||
struct crlf : internal::crlf_eol {};
|
||||
struct lf : internal::lf_eol {};
|
||||
struct lf_crlf : internal::lf_crlf_eol {};
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
} // namespace ascii
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright (c) 2015-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_FILE_INPUT_HPP
|
||||
#define TAO_PEGTL_FILE_INPUT_HPP
|
||||
|
||||
#include "config.hpp"
|
||||
#include "eol.hpp"
|
||||
#include "tracking_mode.hpp"
|
||||
|
||||
#if defined( __unix__ ) || ( defined( __APPLE__ ) && defined( __MACH__ ) )
|
||||
#include <unistd.h> // Required for _POSIX_MAPPED_FILES
|
||||
#endif
|
||||
|
||||
#if defined( _POSIX_MAPPED_FILES ) || defined( _WIN32 )
|
||||
#include "mmap_input.hpp"
|
||||
#else
|
||||
#include "read_input.hpp"
|
||||
#endif
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE
|
||||
{
|
||||
#if defined( _POSIX_MAPPED_FILES ) || defined( _WIN32 )
|
||||
template< tracking_mode P = tracking_mode::eager, typename Eol = eol::lf_crlf >
|
||||
struct file_input
|
||||
: mmap_input< P, Eol >
|
||||
{
|
||||
using mmap_input< P, Eol >::mmap_input;
|
||||
};
|
||||
#else
|
||||
template< tracking_mode P = tracking_mode::eager, typename Eol = eol::lf_crlf >
|
||||
struct file_input
|
||||
: read_input< P, Eol >
|
||||
{
|
||||
using read_input< P, Eol >::read_input;
|
||||
};
|
||||
#endif
|
||||
|
||||
template< typename... Ts >
|
||||
explicit file_input( Ts&&... ) -> file_input<>;
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE
|
||||
|
||||
#endif
|
|
@ -0,0 +1,55 @@
|
|||
// Copyright (c) 2014-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_INTERNAL_ACTION_HPP
|
||||
#define TAO_PEGTL_INTERNAL_ACTION_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
|
||||
#include "enable_control.hpp"
|
||||
#include "seq.hpp"
|
||||
#include "success.hpp"
|
||||
|
||||
#include "../apply_mode.hpp"
|
||||
#include "../rewind_mode.hpp"
|
||||
#include "../type_list.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
template< template< typename... > class Action, typename... Rules >
|
||||
struct action
|
||||
: action< Action, seq< Rules... > >
|
||||
{};
|
||||
|
||||
template< template< typename... > class Action >
|
||||
struct action< Action >
|
||||
: success
|
||||
{};
|
||||
|
||||
template< template< typename... > class Action, typename Rule >
|
||||
struct action< Action, Rule >
|
||||
{
|
||||
using rule_t = action;
|
||||
using subs_t = type_list< Rule >;
|
||||
|
||||
template< apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, States&&... st )
|
||||
{
|
||||
return Control< Rule >::template match< A, M, Action, Control >( in, st... );
|
||||
}
|
||||
};
|
||||
|
||||
template< template< typename... > class Action, typename... Rules >
|
||||
inline constexpr bool enable_control< action< Action, Rules... > > = false;
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,107 @@
|
|||
// Copyright (c) 2016-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_INTERNAL_ACTION_INPUT_HPP
|
||||
#define TAO_PEGTL_INTERNAL_ACTION_INPUT_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "iterator.hpp"
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "../position.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
template< typename ParseInput >
|
||||
class action_input
|
||||
{
|
||||
public:
|
||||
using input_t = ParseInput;
|
||||
using iterator_t = typename ParseInput::iterator_t;
|
||||
|
||||
action_input( const iterator_t& in_begin, const ParseInput& in_input ) noexcept
|
||||
: m_begin( in_begin ),
|
||||
m_input( in_input )
|
||||
{}
|
||||
|
||||
action_input( const action_input& ) = delete;
|
||||
action_input( action_input&& ) = delete;
|
||||
|
||||
~action_input() = default;
|
||||
|
||||
action_input& operator=( const action_input& ) = delete;
|
||||
action_input& operator=( action_input&& ) = delete;
|
||||
|
||||
[[nodiscard]] const iterator_t& iterator() const noexcept
|
||||
{
|
||||
return m_begin;
|
||||
}
|
||||
|
||||
[[nodiscard]] const ParseInput& input() const noexcept
|
||||
{
|
||||
return m_input;
|
||||
}
|
||||
|
||||
[[nodiscard]] const char* begin() const noexcept
|
||||
{
|
||||
if constexpr( std::is_same_v< iterator_t, const char* > ) {
|
||||
return iterator();
|
||||
}
|
||||
else {
|
||||
return iterator().data;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] const char* end() const noexcept
|
||||
{
|
||||
return input().current();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool empty() const noexcept
|
||||
{
|
||||
return begin() == end();
|
||||
}
|
||||
|
||||
[[nodiscard]] std::size_t size() const noexcept
|
||||
{
|
||||
return std::size_t( end() - begin() );
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string string() const
|
||||
{
|
||||
return std::string( begin(), size() );
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string_view string_view() const noexcept
|
||||
{
|
||||
return std::string_view( begin(), size() );
|
||||
}
|
||||
|
||||
[[nodiscard]] char peek_char( const std::size_t offset = 0 ) const noexcept
|
||||
{
|
||||
return begin()[ offset ];
|
||||
}
|
||||
|
||||
[[nodiscard]] std::uint8_t peek_uint8( const std::size_t offset = 0 ) const noexcept
|
||||
{
|
||||
return static_cast< std::uint8_t >( peek_char( offset ) );
|
||||
}
|
||||
|
||||
[[nodiscard]] TAO_PEGTL_NAMESPACE::position position() const
|
||||
{
|
||||
return input().position( iterator() ); // NOTE: Not efficient with lazy inputs.
|
||||
}
|
||||
|
||||
protected:
|
||||
const iterator_t m_begin;
|
||||
const ParseInput& m_input;
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,78 @@
|
|||
// Copyright (c) 2014-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_INTERNAL_ANY_HPP
|
||||
#define TAO_PEGTL_INTERNAL_ANY_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
|
||||
#include "enable_control.hpp"
|
||||
#include "peek_char.hpp"
|
||||
|
||||
#include "../type_list.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
template< typename Peek >
|
||||
struct any;
|
||||
|
||||
template<>
|
||||
struct any< peek_char >
|
||||
{
|
||||
using peek_t = peek_char;
|
||||
using data_t = char;
|
||||
|
||||
using rule_t = any;
|
||||
using subs_t = empty_list;
|
||||
|
||||
[[nodiscard]] static bool test( const char /*unused*/ ) noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template< typename ParseInput >
|
||||
[[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( in.empty() ) )
|
||||
{
|
||||
if( !in.empty() ) {
|
||||
in.bump();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Peek >
|
||||
struct any
|
||||
{
|
||||
using peek_t = Peek;
|
||||
using data_t = typename Peek::data_t;
|
||||
|
||||
using rule_t = any;
|
||||
using subs_t = empty_list;
|
||||
|
||||
template< int Eol >
|
||||
static constexpr bool can_match_eol = true;
|
||||
|
||||
[[nodiscard]] static bool test( const data_t /*unused*/ ) noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template< typename ParseInput >
|
||||
[[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( Peek::peek( in ) ) )
|
||||
{
|
||||
if( const auto t = Peek::peek( in ) ) {
|
||||
in.bump( t.size );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Peek >
|
||||
inline constexpr bool enable_control< any< Peek > > = false;
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,54 @@
|
|||
// Copyright (c) 2017-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_INTERNAL_APPLY_HPP
|
||||
#define TAO_PEGTL_INTERNAL_APPLY_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
|
||||
#include "apply_single.hpp"
|
||||
#include "enable_control.hpp"
|
||||
|
||||
#include "../apply_mode.hpp"
|
||||
#include "../rewind_mode.hpp"
|
||||
#include "../type_list.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
template< typename... Actions >
|
||||
struct apply
|
||||
{
|
||||
using rule_t = apply;
|
||||
using subs_t = empty_list;
|
||||
|
||||
template< apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( [[maybe_unused]] ParseInput& in, [[maybe_unused]] States&&... st )
|
||||
{
|
||||
if constexpr( ( A == apply_mode::action ) && ( sizeof...( Actions ) > 0 ) ) {
|
||||
using action_t = typename ParseInput::action_t;
|
||||
const action_t i2( in.iterator(), in ); // No data -- range is from begin to begin.
|
||||
return ( apply_single< Actions >::match( i2, st... ) && ... );
|
||||
}
|
||||
else {
|
||||
#if defined( _MSC_VER )
|
||||
( (void)st, ... );
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template< typename... Actions >
|
||||
inline constexpr bool enable_control< apply< Actions... > > = false;
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright (c) 2017-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_INTERNAL_APPLY0_HPP
|
||||
#define TAO_PEGTL_INTERNAL_APPLY0_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
|
||||
#include "apply0_single.hpp"
|
||||
#include "enable_control.hpp"
|
||||
|
||||
#include "../apply_mode.hpp"
|
||||
#include "../rewind_mode.hpp"
|
||||
#include "../type_list.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
template< typename... Actions >
|
||||
struct apply0
|
||||
{
|
||||
using rule_t = apply0;
|
||||
using subs_t = empty_list;
|
||||
|
||||
template< apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& /*unused*/, [[maybe_unused]] States&&... st )
|
||||
{
|
||||
if constexpr( A == apply_mode::action ) {
|
||||
return ( apply0_single< Actions >::match( st... ) && ... );
|
||||
}
|
||||
else {
|
||||
#if defined( _MSC_VER )
|
||||
( (void)st, ... );
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template< typename... Actions >
|
||||
inline constexpr bool enable_control< apply0< Actions... > > = false;
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) 2017-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_INTERNAL_APPLY0_SINGLE_HPP
|
||||
#define TAO_PEGTL_INTERNAL_APPLY0_SINGLE_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
template< typename Action >
|
||||
struct apply0_single
|
||||
{
|
||||
template< typename... States >
|
||||
[[nodiscard]] static auto match( States&&... st ) noexcept( noexcept( Action::apply0( st... ) ) )
|
||||
-> std::enable_if_t< std::is_same_v< decltype( Action::apply0( st... ) ), void >, bool >
|
||||
{
|
||||
Action::apply0( st... );
|
||||
return true;
|
||||
}
|
||||
|
||||
template< typename... States >
|
||||
[[nodiscard]] static auto match( States&&... st ) noexcept( noexcept( Action::apply0( st... ) ) )
|
||||
-> std::enable_if_t< std::is_same_v< decltype( Action::apply0( st... ) ), bool >, bool >
|
||||
{
|
||||
return Action::apply0( st... );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) 2017-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_INTERNAL_APPLY_SINGLE_HPP
|
||||
#define TAO_PEGTL_INTERNAL_APPLY_SINGLE_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
template< typename Action >
|
||||
struct apply_single
|
||||
{
|
||||
template< typename ActionInput, typename... States >
|
||||
[[nodiscard]] static auto match( const ActionInput& in, States&&... st ) noexcept( noexcept( Action::apply( in, st... ) ) )
|
||||
-> std::enable_if_t< std::is_same_v< decltype( Action::apply( in, st... ) ), void >, bool >
|
||||
{
|
||||
Action::apply( in, st... );
|
||||
return true;
|
||||
}
|
||||
|
||||
template< typename ActionInput, typename... States >
|
||||
[[nodiscard]] static auto match( const ActionInput& in, States&&... st ) noexcept( noexcept( Action::apply( in, st... ) ) )
|
||||
-> std::enable_if_t< std::is_same_v< decltype( Action::apply( in, st... ) ), bool >, bool >
|
||||
{
|
||||
return Action::apply( in, st... );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,56 @@
|
|||
// Copyright (c) 2014-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_INTERNAL_AT_HPP
|
||||
#define TAO_PEGTL_INTERNAL_AT_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
|
||||
#include "enable_control.hpp"
|
||||
#include "seq.hpp"
|
||||
#include "success.hpp"
|
||||
|
||||
#include "../apply_mode.hpp"
|
||||
#include "../rewind_mode.hpp"
|
||||
#include "../type_list.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
template< typename... Rules >
|
||||
struct at
|
||||
: at< seq< Rules... > >
|
||||
{};
|
||||
|
||||
template<>
|
||||
struct at<>
|
||||
: success
|
||||
{};
|
||||
|
||||
template< typename Rule >
|
||||
struct at< Rule >
|
||||
{
|
||||
using rule_t = at;
|
||||
using subs_t = type_list< Rule >;
|
||||
|
||||
template< apply_mode,
|
||||
rewind_mode,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class Control,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, States&&... st )
|
||||
{
|
||||
const auto m = in.template mark< rewind_mode::required >();
|
||||
return Control< Rule >::template match< apply_mode::nothing, rewind_mode::active, Action, Control >( in, st... );
|
||||
}
|
||||
};
|
||||
|
||||
template< typename... Rules >
|
||||
inline constexpr bool enable_control< at< Rules... > > = false;
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) 2017-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_INTERNAL_BOF_HPP
|
||||
#define TAO_PEGTL_INTERNAL_BOF_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
|
||||
#include "enable_control.hpp"
|
||||
|
||||
#include "../type_list.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
struct bof
|
||||
{
|
||||
using rule_t = bof;
|
||||
using subs_t = empty_list;
|
||||
|
||||
template< typename ParseInput >
|
||||
[[nodiscard]] static bool match( ParseInput& in ) noexcept
|
||||
{
|
||||
return in.byte() == 0;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline constexpr bool enable_control< bof > = false;
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) 2017-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_INTERNAL_BOL_HPP
|
||||
#define TAO_PEGTL_INTERNAL_BOL_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "../type_list.hpp"
|
||||
|
||||
#include "enable_control.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
struct bol
|
||||
{
|
||||
using rule_t = bol;
|
||||
using subs_t = empty_list;
|
||||
|
||||
template< typename ParseInput >
|
||||
[[nodiscard]] static bool match( ParseInput& in ) noexcept
|
||||
{
|
||||
return in.column() == 1;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
inline constexpr bool enable_control< bol > = false;
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright (c) 2017-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_INTERNAL_BUMP_HPP
|
||||
#define TAO_PEGTL_INTERNAL_BUMP_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
|
||||
#include "iterator.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
inline void bump( iterator& iter, const std::size_t count, const int ch ) noexcept
|
||||
{
|
||||
for( std::size_t i = 0; i < count; ++i ) {
|
||||
if( iter.data[ i ] == ch ) {
|
||||
++iter.line;
|
||||
iter.column = 1;
|
||||
}
|
||||
else {
|
||||
++iter.column;
|
||||
}
|
||||
}
|
||||
iter.byte += count;
|
||||
iter.data += count;
|
||||
}
|
||||
|
||||
inline void bump_in_this_line( iterator& iter, const std::size_t count ) noexcept
|
||||
{
|
||||
iter.data += count;
|
||||
iter.byte += count;
|
||||
iter.column += count;
|
||||
}
|
||||
|
||||
inline void bump_to_next_line( iterator& iter, const std::size_t count ) noexcept
|
||||
{
|
||||
++iter.line;
|
||||
iter.byte += count;
|
||||
iter.column = 1;
|
||||
iter.data += count;
|
||||
}
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright (c) 2015-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_INTERNAL_BUMP_HELP_HPP
|
||||
#define TAO_PEGTL_INTERNAL_BUMP_HELP_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include "../config.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
template< typename Rule, typename ParseInput >
|
||||
void bump_help( ParseInput& in, const std::size_t count )
|
||||
{
|
||||
if constexpr( Rule::template can_match_eol< ParseInput::eol_t::ch > ) {
|
||||
in.bump( count );
|
||||
}
|
||||
else {
|
||||
in.bump_in_this_line( count );
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright (c) 2014-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_INTERNAL_BYTES_HPP
|
||||
#define TAO_PEGTL_INTERNAL_BYTES_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
|
||||
#include "enable_control.hpp"
|
||||
#include "success.hpp"
|
||||
|
||||
#include "../type_list.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
template< unsigned Cnt >
|
||||
struct bytes
|
||||
{
|
||||
using rule_t = bytes;
|
||||
using subs_t = empty_list;
|
||||
|
||||
template< typename ParseInput >
|
||||
[[nodiscard]] static bool match( ParseInput& in ) noexcept( noexcept( in.size( 0 ) ) )
|
||||
{
|
||||
if( in.size( Cnt ) >= Cnt ) {
|
||||
in.bump( Cnt );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct bytes< 0 >
|
||||
: success
|
||||
{};
|
||||
|
||||
template< unsigned Cnt >
|
||||
inline constexpr bool enable_control< bytes< Cnt > > = false;
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,55 @@
|
|||
// Copyright (c) 2014-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_INTERNAL_CONTROL_HPP
|
||||
#define TAO_PEGTL_INTERNAL_CONTROL_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
|
||||
#include "enable_control.hpp"
|
||||
#include "seq.hpp"
|
||||
#include "success.hpp"
|
||||
|
||||
#include "../apply_mode.hpp"
|
||||
#include "../rewind_mode.hpp"
|
||||
#include "../type_list.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
template< template< typename... > class Control, typename... Rules >
|
||||
struct control
|
||||
: control< Control, seq< Rules... > >
|
||||
{};
|
||||
|
||||
template< template< typename... > class Control >
|
||||
struct control< Control >
|
||||
: success
|
||||
{};
|
||||
|
||||
template< template< typename... > class Control, typename Rule >
|
||||
struct control< Control, Rule >
|
||||
{
|
||||
using rule_t = control;
|
||||
using subs_t = type_list< Rule >;
|
||||
|
||||
template< apply_mode A,
|
||||
rewind_mode M,
|
||||
template< typename... >
|
||||
class Action,
|
||||
template< typename... >
|
||||
class,
|
||||
typename ParseInput,
|
||||
typename... States >
|
||||
[[nodiscard]] static bool match( ParseInput& in, States&&... st )
|
||||
{
|
||||
return Control< Rule >::template match< A, M, Action, Control >( in, st... );
|
||||
}
|
||||
};
|
||||
|
||||
template< template< typename... > class Control, typename... Rules >
|
||||
inline constexpr bool enable_control< control< Control, Rules... > > = false;
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) 2016-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_INTERNAL_CR_CRLF_EOL_HPP
|
||||
#define TAO_PEGTL_INTERNAL_CR_CRLF_EOL_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "eol_pair.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
struct cr_crlf_eol
|
||||
{
|
||||
static constexpr int ch = '\r';
|
||||
|
||||
template< typename ParseInput >
|
||||
[[nodiscard]] static eol_pair eol_match( ParseInput& in ) noexcept( noexcept( in.size( 2 ) ) )
|
||||
{
|
||||
eol_pair p = { false, in.size( 2 ) };
|
||||
if( p.second ) {
|
||||
if( in.peek_char() == '\r' ) {
|
||||
in.bump_to_next_line( 1 + ( ( p.second > 1 ) && ( in.peek_char( 1 ) == '\n' ) ) );
|
||||
p.first = true;
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) 2016-2021 Dr. Colin Hirsch and Daniel Frey
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef TAO_PEGTL_INTERNAL_CR_EOL_HPP
|
||||
#define TAO_PEGTL_INTERNAL_CR_EOL_HPP
|
||||
|
||||
#include "../config.hpp"
|
||||
#include "eol_pair.hpp"
|
||||
|
||||
namespace TAO_PEGTL_NAMESPACE::internal
|
||||
{
|
||||
struct cr_eol
|
||||
{
|
||||
static constexpr int ch = '\r';
|
||||
|
||||
template< typename ParseInput >
|
||||
[[nodiscard]] static eol_pair eol_match( ParseInput& in ) noexcept( noexcept( in.size( 1 ) ) )
|
||||
{
|
||||
eol_pair p = { false, in.size( 1 ) };
|
||||
if( p.second ) {
|
||||
if( in.peek_char() == '\r' ) {
|
||||
in.bump_to_next_line();
|
||||
p.first = true;
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace TAO_PEGTL_NAMESPACE::internal
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue