mirror of
https://github.com/boostorg/parser.git
synced 2026-02-21 15:22:10 +00:00
Compare commits
6 Commits
master
...
introduce_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4a200a4074 | ||
|
|
1b984e3546 | ||
|
|
316b4921a9 | ||
|
|
4706f57c8e | ||
|
|
5625f0345e | ||
|
|
a2df985cc5 |
11
.github/workflows/ubuntu.yml
vendored
11
.github/workflows/ubuntu.yml
vendored
@@ -18,6 +18,13 @@ jobs:
|
|||||||
compiler_version: [g++-10, g++-11]
|
compiler_version: [g++-10, g++-11]
|
||||||
cxx_std: [17, 20]
|
cxx_std: [17, 20]
|
||||||
os: [ubuntu-22.04]
|
os: [ubuntu-22.04]
|
||||||
|
disable_trace: [false]
|
||||||
|
include:
|
||||||
|
# Test with trace disabled
|
||||||
|
- compiler_version: g++-11
|
||||||
|
cxx_std: 20
|
||||||
|
os: ubuntu-22.04
|
||||||
|
disable_trace: true
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
@@ -30,7 +37,11 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
|
if [ "${{ matrix.disable_trace }}" = "true" ]; then
|
||||||
|
cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DCMAKE_CXX_COMPILER=${{ matrix.compiler_version }} -DCXX_STD=${{ matrix.cxx_std }} -DDISABLE_TRACE=true
|
||||||
|
else
|
||||||
cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DCMAKE_CXX_COMPILER=${{ matrix.compiler_version }} -DCXX_STD=${{ matrix.cxx_std }}
|
cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DCMAKE_CXX_COMPILER=${{ matrix.compiler_version }} -DCXX_STD=${{ matrix.cxx_std }}
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: cd build ; make -j4
|
run: cd build ; make -j4
|
||||||
|
|||||||
14
.github/workflows/windows.yml
vendored
14
.github/workflows/windows.yml
vendored
@@ -17,6 +17,12 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
cxx_std: [17, 20, 23]
|
cxx_std: [17, 20, 23]
|
||||||
os: [windows-2022]
|
os: [windows-2022]
|
||||||
|
disable_trace: [false]
|
||||||
|
include:
|
||||||
|
# Test with trace disabled
|
||||||
|
- cxx_std: 20
|
||||||
|
os: windows-2022
|
||||||
|
disable_trace: true
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
@@ -26,7 +32,13 @@ jobs:
|
|||||||
- name: Configure CMake
|
- name: Configure CMake
|
||||||
# Configure CMake in a 'build' subdirectory. Visual Studio is a multi-config generator, so we don't use CMAKE_BUILD_TYPE.
|
# Configure CMake in a 'build' subdirectory. Visual Studio is a multi-config generator, so we don't use CMAKE_BUILD_TYPE.
|
||||||
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
|
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
|
||||||
run: cmake -B build -DCXX_STD=${{ matrix.cxx_std }}
|
run: |
|
||||||
|
if ("${{ matrix.disable_trace }}" -eq "true") {
|
||||||
|
cmake -B build -DCXX_STD=${{ matrix.cxx_std }} -DDISABLE_TRACE=true
|
||||||
|
} else {
|
||||||
|
cmake -B build -DCXX_STD=${{ matrix.cxx_std }}
|
||||||
|
}
|
||||||
|
shell: pwsh
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
working-directory: build
|
working-directory: build
|
||||||
|
|||||||
@@ -64,6 +64,12 @@ if (BUILD_WITH_HANA)
|
|||||||
add_definitions(-DBOOST_PARSER_USE_HANA_TUPLE)
|
add_definitions(-DBOOST_PARSER_USE_HANA_TUPLE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(DISABLE_TRACE false CACHE BOOL
|
||||||
|
"Disable parser trace functionality (defines BOOST_PARSER_DISABLE_TRACE).")
|
||||||
|
if (DISABLE_TRACE)
|
||||||
|
add_definitions(-DBOOST_PARSER_DISABLE_TRACE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
# Dependencies
|
# Dependencies
|
||||||
|
|||||||
@@ -67,6 +67,6 @@ Develop status:
|
|||||||
|
|
||||||
[](https://github.com/tzlaine/parser/actions/workflows/windows.yml)
|
[](https://github.com/tzlaine/parser/actions/workflows/windows.yml)
|
||||||
|
|
||||||
[](https://github.com/tzlaine/parser/actions/workflows/macos-13.yml)
|
[](https://github.com/tzlaine/parser/actions/workflows/macos-15.yml)
|
||||||
|
|
||||||
[](LICENSE_1_0.txt)
|
[](LICENSE_1_0.txt)
|
||||||
|
|||||||
@@ -148,6 +148,7 @@
|
|||||||
[def _RULES_ [macroref BOOST_PARSER_DEFINE_RULES `BOOST_PARSER_DEFINE_RULES`]]
|
[def _RULES_ [macroref BOOST_PARSER_DEFINE_RULES `BOOST_PARSER_DEFINE_RULES`]]
|
||||||
[def _AGGR_SIZE_ [macroref BOOST_PARSER_MAX_AGGREGATE_SIZE `BOOST_PARSER_MAX_AGGREGATE_SIZE`]]
|
[def _AGGR_SIZE_ [macroref BOOST_PARSER_MAX_AGGREGATE_SIZE `BOOST_PARSER_MAX_AGGREGATE_SIZE`]]
|
||||||
[def _SUBRNG_ [macroref BOOST_PARSER_SUBRANGE `BOOST_PARSER_SUBRANGE`]]
|
[def _SUBRNG_ [macroref BOOST_PARSER_SUBRANGE `BOOST_PARSER_SUBRANGE`]]
|
||||||
|
[def _DISABLE_TRACE_ [macroref BOOST_PARSER_DISABLE_TRACE `BOOST_PARSER_DISABLE_TRACE`]]
|
||||||
|
|
||||||
[def __p_ [globalref boost::parser::_p `_p`]]
|
[def __p_ [globalref boost::parser::_p `_p`]]
|
||||||
|
|
||||||
|
|||||||
@@ -3766,6 +3766,22 @@ Some things to be aware of when looking at _Parser_ trace output:
|
|||||||
produces that value. In these cases, you'll see the resolved value of the
|
produces that value. In these cases, you'll see the resolved value of the
|
||||||
parse argument.
|
parse argument.
|
||||||
|
|
||||||
|
[heading Compile-time trace disabling]
|
||||||
|
|
||||||
|
While trace mode is very useful for debugging, it does have some overhead.
|
||||||
|
Most parser templates are instantiated twice: Once with tracing enabled,
|
||||||
|
once with tracing disabled.
|
||||||
|
If you want to completely disable trace functionality at compile time, you can define
|
||||||
|
`BOOST_PARSER_DISABLE_TRACE` before including any Boost.Parser headers:
|
||||||
|
|
||||||
|
[teletype]``
|
||||||
|
#define BOOST_PARSER_DISABLE_TRACE
|
||||||
|
#include <boost/parser/parser.hpp>
|
||||||
|
``
|
||||||
|
|
||||||
|
When this define is set, all trace-related code is compiled out,
|
||||||
|
reducing the compile time.
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[section Memory Allocation]
|
[section Memory Allocation]
|
||||||
@@ -3983,7 +3999,8 @@ This defines a RAII trace object that will produce the verbose trace requested
|
|||||||
by the user if they passed `_trace_::on` to the top-level parse. It only has
|
by the user if they passed `_trace_::on` to the top-level parse. It only has
|
||||||
effect if `detail::enable_trace(flags)` is `true`. If trace is enabled, it
|
effect if `detail::enable_trace(flags)` is `true`. If trace is enabled, it
|
||||||
will show the state of the parse at the point at which it is defined, and then
|
will show the state of the parse at the point at which it is defined, and then
|
||||||
again when it goes out of scope.
|
again when it goes out of scope. By defining `BOOST_PARSER_DISABLE_TRACE`,
|
||||||
|
the trace feature can be disabled globally at compile time.
|
||||||
|
|
||||||
[important For the tracing code to work, you must define an overload of
|
[important For the tracing code to work, you must define an overload of
|
||||||
`detail::print_parser` for your new parser type/template. See
|
`detail::print_parser` for your new parser type/template. See
|
||||||
|
|||||||
@@ -36,6 +36,10 @@
|
|||||||
disable the use of concepts, define this macro. */
|
disable the use of concepts, define this macro. */
|
||||||
# define BOOST_PARSER_DISABLE_CONCEPTS
|
# define BOOST_PARSER_DISABLE_CONCEPTS
|
||||||
|
|
||||||
|
/** Boost.Parser will generate code to trace the execution of each and every
|
||||||
|
parser by default. To disable all trace code, define this macro. */
|
||||||
|
# define BOOST_PARSER_DISABLE_TRACE
|
||||||
|
|
||||||
/** Define this macro to use `boost::hana::tuple` instead of `std::tuple`
|
/** Define this macro to use `boost::hana::tuple` instead of `std::tuple`
|
||||||
throughout Boost.Parser. */
|
throughout Boost.Parser. */
|
||||||
# define BOOST_PARSER_USE_HANA_TUPLE
|
# define BOOST_PARSER_USE_HANA_TUPLE
|
||||||
@@ -92,6 +96,12 @@
|
|||||||
# define BOOST_PARSER_USE_CONCEPTS 0
|
# define BOOST_PARSER_USE_CONCEPTS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(BOOST_PARSER_DISABLE_TRACE)
|
||||||
|
# define BOOST_PARSER_DO_TRACE 0
|
||||||
|
#else
|
||||||
|
# define BOOST_PARSER_DO_TRACE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__cpp_lib_ranges) && BOOST_PARSER_USE_CONCEPTS
|
#if defined(__cpp_lib_ranges) && BOOST_PARSER_USE_CONCEPTS
|
||||||
# define BOOST_PARSER_SUBRANGE std::ranges::subrange
|
# define BOOST_PARSER_SUBRANGE std::ranges::subrange
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -593,11 +593,14 @@ namespace boost { namespace parser { namespace detail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Context, typename T>
|
template<typename Context, typename T>
|
||||||
auto resolve(Context const & context, T const & x);
|
decltype(auto) resolve(Context const & context, T const & x);
|
||||||
|
|
||||||
template<typename Context>
|
template<typename Context>
|
||||||
auto resolve(Context const &, nope n);
|
auto resolve(Context const &, nope n);
|
||||||
|
|
||||||
|
template<typename DependentType, bool DoTraceMacro>
|
||||||
|
constexpr bool trace_disabled = !DoTraceMacro;
|
||||||
|
|
||||||
template<
|
template<
|
||||||
bool DoTrace,
|
bool DoTrace,
|
||||||
typename Iter,
|
typename Iter,
|
||||||
@@ -606,6 +609,8 @@ namespace boost { namespace parser { namespace detail {
|
|||||||
typename Attribute>
|
typename Attribute>
|
||||||
struct scoped_trace_t
|
struct scoped_trace_t
|
||||||
{
|
{
|
||||||
|
static_assert(!trace_disabled<Iter, BOOST_PARSER_DO_TRACE>);
|
||||||
|
|
||||||
scoped_trace_t(
|
scoped_trace_t(
|
||||||
std::ostream & os,
|
std::ostream & os,
|
||||||
Iter & first,
|
Iter & first,
|
||||||
@@ -681,6 +686,9 @@ namespace boost { namespace parser { namespace detail {
|
|||||||
flags f,
|
flags f,
|
||||||
Attribute const & attr)
|
Attribute const & attr)
|
||||||
{
|
{
|
||||||
|
if constexpr (!BOOST_PARSER_DO_TRACE)
|
||||||
|
return;
|
||||||
|
|
||||||
if constexpr (Context::do_trace) {
|
if constexpr (Context::do_trace) {
|
||||||
std::stringstream oss;
|
std::stringstream oss;
|
||||||
detail::print_parser(context, parser, oss);
|
detail::print_parser(context, parser, oss);
|
||||||
@@ -695,6 +703,9 @@ namespace boost { namespace parser { namespace detail {
|
|||||||
template<typename Context, typename Attribute>
|
template<typename Context, typename Attribute>
|
||||||
auto final_trace(Context const & context, flags f, Attribute const & attr)
|
auto final_trace(Context const & context, flags f, Attribute const & attr)
|
||||||
{
|
{
|
||||||
|
if constexpr (!BOOST_PARSER_DO_TRACE)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!detail::do_trace(f))
|
if (!detail::do_trace(f))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -1020,7 +1020,7 @@ namespace boost { namespace parser {
|
|||||||
bool Callable = is_detected_v<callable, T const &, Context const &>>
|
bool Callable = is_detected_v<callable, T const &, Context const &>>
|
||||||
struct resolve_impl
|
struct resolve_impl
|
||||||
{
|
{
|
||||||
static auto call(Context const &, T const & x) { return x; }
|
static auto& call(Context const &, T const & x) { return x; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Context, typename T>
|
template<typename Context, typename T>
|
||||||
@@ -1033,7 +1033,7 @@ namespace boost { namespace parser {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<typename Context, typename T>
|
template<typename Context, typename T>
|
||||||
auto resolve(Context const & context, T const & x)
|
decltype(auto) resolve(Context const & context, T const & x)
|
||||||
{
|
{
|
||||||
return resolve_impl<Context, T>::call(context, x);
|
return resolve_impl<Context, T>::call(context, x);
|
||||||
}
|
}
|
||||||
@@ -2168,7 +2168,10 @@ namespace boost { namespace parser {
|
|||||||
{
|
{
|
||||||
if (!gen_attrs || !x)
|
if (!gen_attrs || !x)
|
||||||
return;
|
return;
|
||||||
c.insert(c.end(), x->begin(), x->end());
|
c.insert(c.end(),
|
||||||
|
std::make_move_iterator(x->begin()),
|
||||||
|
std::make_move_iterator(x->end())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Container, typename T>
|
template<typename Container, typename T>
|
||||||
@@ -3177,6 +3180,7 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this,
|
*this,
|
||||||
first,
|
first,
|
||||||
@@ -3185,6 +3189,7 @@ namespace boost { namespace parser {
|
|||||||
detail::in_apply_parser(flags) ? detail::disable_trace(flags)
|
detail::in_apply_parser(flags) ? detail::disable_trace(flags)
|
||||||
: flags,
|
: flags,
|
||||||
retval);
|
retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
if constexpr (detail::is_optional_v<Attribute>) {
|
if constexpr (detail::is_optional_v<Attribute>) {
|
||||||
detail::optional_type<Attribute> attr;
|
detail::optional_type<Attribute> attr;
|
||||||
@@ -3341,8 +3346,10 @@ namespace boost { namespace parser {
|
|||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
//[ opt_parser_trace
|
//[ opt_parser_trace
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
//]
|
//]
|
||||||
|
|
||||||
//[ opt_parser_skip
|
//[ opt_parser_skip
|
||||||
@@ -3505,8 +3512,10 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
use_parser_t<Iter, Sentinel, Context, SkipParser> const use_parser{
|
use_parser_t<Iter, Sentinel, Context, SkipParser> const use_parser{
|
||||||
first, last, context, skip, flags, success};
|
first, last, context, skip, flags, success};
|
||||||
@@ -3629,8 +3638,10 @@ namespace boost { namespace parser {
|
|||||||
decltype(detail::hl::transform(parsers_, use_parser));
|
decltype(detail::hl::transform(parsers_, use_parser));
|
||||||
result_t retval{};
|
result_t retval{};
|
||||||
|
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first_, last, context, flags, retval);
|
*this, first_, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
call_impl(
|
call_impl(
|
||||||
first,
|
first,
|
||||||
@@ -3665,8 +3676,10 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first_, last, context, flags, retval);
|
*this, first_, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
Iter first = first_;
|
Iter first = first_;
|
||||||
use_parser_t<Iter, Sentinel, Context, SkipParser> const use_parser{
|
use_parser_t<Iter, Sentinel, Context, SkipParser> const use_parser{
|
||||||
@@ -3713,7 +3726,7 @@ namespace boost { namespace parser {
|
|||||||
if constexpr (detail::is_struct_compatible_v<
|
if constexpr (detail::is_struct_compatible_v<
|
||||||
Attribute,
|
Attribute,
|
||||||
result_t>) {
|
result_t>) {
|
||||||
detail::assign(retval, temp_retval);
|
detail::assign(retval, std::move(temp_retval));
|
||||||
} else {
|
} else {
|
||||||
detail::assign(
|
detail::assign(
|
||||||
retval,
|
retval,
|
||||||
@@ -4292,12 +4305,13 @@ namespace boost { namespace parser {
|
|||||||
{
|
{
|
||||||
Iter first = first_;
|
Iter first = first_;
|
||||||
|
|
||||||
auto temp_result =
|
using temp_result_t =
|
||||||
make_temp_result(first, last, context, skip, flags, success);
|
decltype(make_temp_result(first, last, context, skip, flags, success));
|
||||||
|
|
||||||
std::decay_t<decltype(parser::get(temp_result, llong<0>{}))>
|
std::decay_t<decltype(parser::get(std::declval<temp_result_t>(), llong<0>{}))>
|
||||||
retval{};
|
retval{};
|
||||||
|
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this,
|
*this,
|
||||||
first_,
|
first_,
|
||||||
@@ -4306,10 +4320,11 @@ namespace boost { namespace parser {
|
|||||||
detail::in_apply_parser(flags) ? detail::disable_trace(flags)
|
detail::in_apply_parser(flags) ? detail::disable_trace(flags)
|
||||||
: flags,
|
: flags,
|
||||||
retval);
|
retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
std::decay_t<decltype(parser::get(temp_result, llong<1>{}))>
|
std::decay_t<decltype(parser::get(std::declval<temp_result_t>(), llong<1>{}))>
|
||||||
indices;
|
indices;
|
||||||
std::decay_t<decltype(parser::get(temp_result, llong<2>{}))>
|
std::decay_t<decltype(parser::get(std::declval<temp_result_t>(), llong<2>{}))>
|
||||||
merged;
|
merged;
|
||||||
call_impl(
|
call_impl(
|
||||||
first,
|
first,
|
||||||
@@ -4328,7 +4343,7 @@ namespace boost { namespace parser {
|
|||||||
// A 1-tuple is converted to a scalar.
|
// A 1-tuple is converted to a scalar.
|
||||||
if constexpr (detail::hl::size(retval) == llong<1>{}) {
|
if constexpr (detail::hl::size(retval) == llong<1>{}) {
|
||||||
using namespace literals;
|
using namespace literals;
|
||||||
return parser::get(retval, 0_c);
|
return parser::get(std::move(retval), 0_c);
|
||||||
} else {
|
} else {
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@@ -4349,6 +4364,7 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this,
|
*this,
|
||||||
first_,
|
first_,
|
||||||
@@ -4357,16 +4373,17 @@ namespace boost { namespace parser {
|
|||||||
detail::in_apply_parser(flags) ? detail::disable_trace(flags)
|
detail::in_apply_parser(flags) ? detail::disable_trace(flags)
|
||||||
: flags,
|
: flags,
|
||||||
retval);
|
retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
Iter first = first_;
|
Iter first = first_;
|
||||||
|
|
||||||
auto temp_result =
|
using temp_result_t =
|
||||||
make_temp_result(first, last, context, skip, flags, success);
|
decltype(make_temp_result(first, last, context, skip, flags, success));
|
||||||
using temp_result_attr_t =
|
using temp_result_attr_t =
|
||||||
std::decay_t<decltype(parser::get(temp_result, llong<0>{}))>;
|
std::decay_t<decltype(parser::get(std::declval<temp_result_t>(), llong<0>{}))>;
|
||||||
std::decay_t<decltype(parser::get(temp_result, llong<1>{}))>
|
std::decay_t<decltype(parser::get(std::declval<temp_result_t>(), llong<1>{}))>
|
||||||
indices;
|
indices;
|
||||||
std::decay_t<decltype(parser::get(temp_result, llong<2>{}))> merged;
|
std::decay_t<decltype(parser::get(std::declval<temp_result_t>(), llong<2>{}))> merged;
|
||||||
|
|
||||||
auto max_ = [](auto result, auto x) {
|
auto max_ = [](auto result, auto x) {
|
||||||
if constexpr (decltype(result)::value < decltype(x)::value) {
|
if constexpr (decltype(result)::value < decltype(x)::value) {
|
||||||
@@ -4703,8 +4720,10 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
auto const initial_first = first;
|
auto const initial_first = first;
|
||||||
auto attr = parser_.call(
|
auto attr = parser_.call(
|
||||||
@@ -4769,8 +4788,10 @@ namespace boost { namespace parser {
|
|||||||
detail::flags flags,
|
detail::flags flags,
|
||||||
bool & success) const
|
bool & success) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, detail::global_nope);
|
*this, first, last, context, flags, detail::global_nope);
|
||||||
|
#endif
|
||||||
auto attr =
|
auto attr =
|
||||||
parser_.call(first, last, context, skip, flags, success);
|
parser_.call(first, last, context, skip, flags, success);
|
||||||
if (success && detail::gen_attrs(flags))
|
if (success && detail::gen_attrs(flags))
|
||||||
@@ -4794,8 +4815,11 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
auto attr =
|
auto attr =
|
||||||
parser_.call(first, last, context, skip, flags, success);
|
parser_.call(first, last, context, skip, flags, success);
|
||||||
if (success && detail::gen_attrs(flags))
|
if (success && detail::gen_attrs(flags))
|
||||||
@@ -4822,8 +4846,10 @@ namespace boost { namespace parser {
|
|||||||
detail::flags flags,
|
detail::flags flags,
|
||||||
bool & success) const
|
bool & success) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, detail::global_nope);
|
*this, first, last, context, flags, detail::global_nope);
|
||||||
|
#endif
|
||||||
|
|
||||||
parser_.call(
|
parser_.call(
|
||||||
first,
|
first,
|
||||||
@@ -4850,8 +4876,10 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
parser_.call(
|
parser_.call(
|
||||||
first,
|
first,
|
||||||
@@ -4901,8 +4929,10 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
auto const initial_first = first;
|
auto const initial_first = first;
|
||||||
parser_.call(
|
parser_.call(
|
||||||
@@ -4966,8 +4996,10 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
auto const initial_first = first;
|
auto const initial_first = first;
|
||||||
parser_.call(
|
parser_.call(
|
||||||
@@ -5042,8 +5074,10 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
parser_.call(
|
parser_.call(
|
||||||
first,
|
first,
|
||||||
@@ -5102,8 +5136,10 @@ namespace boost { namespace parser {
|
|||||||
auto context = context_;
|
auto context = context_;
|
||||||
++context.no_case_depth_;
|
++context.no_case_depth_;
|
||||||
|
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
parser_.call(first, last, context, skip, flags, success, retval);
|
parser_.call(first, last, context, skip, flags, success, retval);
|
||||||
}
|
}
|
||||||
@@ -5149,8 +5185,10 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
if constexpr (detail::is_nope_v<SkipParser>) {
|
if constexpr (detail::is_nope_v<SkipParser>) {
|
||||||
parser_.call(
|
parser_.call(
|
||||||
@@ -5213,8 +5251,10 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
auto first_copy = first;
|
auto first_copy = first;
|
||||||
parser_.call(
|
parser_.call(
|
||||||
@@ -5380,8 +5420,10 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
auto [trie, _0] = detail::get_trie(context, ref());
|
auto [trie, _0] = detail::get_trie(context, ref());
|
||||||
auto const lookup = context.no_case_depth_
|
auto const lookup = context.no_case_depth_
|
||||||
@@ -5455,8 +5497,10 @@ namespace boost { namespace parser {
|
|||||||
tag_type * const tag_ptr = nullptr;
|
tag_type * const tag_ptr = nullptr;
|
||||||
auto const rule_context = detail::make_rule_context(
|
auto const rule_context = detail::make_rule_context(
|
||||||
context, tag_ptr, retval, locals, params);
|
context, tag_ptr, retval, locals, params);
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, rule_context, flags, retval);
|
*this, first, last, rule_context, flags, retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
bool dont_assign = false;
|
bool dont_assign = false;
|
||||||
if constexpr (in_recursion) {
|
if constexpr (in_recursion) {
|
||||||
@@ -5485,7 +5529,7 @@ namespace boost { namespace parser {
|
|||||||
dont_assign);
|
dont_assign);
|
||||||
if (success && !dont_assign) {
|
if (success && !dont_assign) {
|
||||||
if constexpr (!detail::is_nope_v<decltype(attr)>)
|
if constexpr (!detail::is_nope_v<decltype(attr)>)
|
||||||
detail::assign(retval, attr);
|
detail::assign(retval, std::move(attr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5553,8 +5597,10 @@ namespace boost { namespace parser {
|
|||||||
auto const rule_context = detail::make_rule_context(
|
auto const rule_context = detail::make_rule_context(
|
||||||
context, tag_ptr, attr, locals, params);
|
context, tag_ptr, attr, locals, params);
|
||||||
|
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, rule_context, flags, retval);
|
*this, first, last, rule_context, flags, retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
bool dont_assign = false;
|
bool dont_assign = false;
|
||||||
parse_rule(
|
parse_rule(
|
||||||
@@ -5580,7 +5626,7 @@ namespace boost { namespace parser {
|
|||||||
container<Attribute_> && container<attr_type>) {
|
container<Attribute_> && container<attr_type>) {
|
||||||
detail::move_back(retval, attr, detail::gen_attrs(flags));
|
detail::move_back(retval, attr, detail::gen_attrs(flags));
|
||||||
} else {
|
} else {
|
||||||
detail::assign(retval, attr);
|
detail::assign(retval, std::move(attr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6744,8 +6790,10 @@ namespace boost { namespace parser {
|
|||||||
detail::flags flags,
|
detail::flags flags,
|
||||||
bool & success) const noexcept
|
bool & success) const noexcept
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, detail::global_nope);
|
*this, first, last, context, flags, detail::global_nope);
|
||||||
|
#endif
|
||||||
BOOST_PARSER_SUBRANGE const where(first, first);
|
BOOST_PARSER_SUBRANGE const where(first, first);
|
||||||
auto const predicate_context = detail::make_action_context(
|
auto const predicate_context = detail::make_action_context(
|
||||||
context, detail::global_nope, where);
|
context, detail::global_nope, where);
|
||||||
@@ -6772,8 +6820,10 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
BOOST_PARSER_SUBRANGE const where(first, first);
|
BOOST_PARSER_SUBRANGE const where(first, first);
|
||||||
auto const predicate_context = detail::make_action_context(
|
auto const predicate_context = detail::make_action_context(
|
||||||
context, detail::global_nope, where);
|
context, detail::global_nope, where);
|
||||||
@@ -6823,8 +6873,10 @@ namespace boost { namespace parser {
|
|||||||
detail::flags flags,
|
detail::flags flags,
|
||||||
bool & success) const
|
bool & success) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, detail::global_nope);
|
*this, first, last, context, flags, detail::global_nope);
|
||||||
|
#endif
|
||||||
if (first != last)
|
if (first != last)
|
||||||
success = false;
|
success = false;
|
||||||
return {};
|
return {};
|
||||||
@@ -6845,8 +6897,10 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
if (first != last)
|
if (first != last)
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
@@ -6875,8 +6929,10 @@ namespace boost { namespace parser {
|
|||||||
detail::flags flags,
|
detail::flags flags,
|
||||||
bool &) const
|
bool &) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, detail::global_nope);
|
*this, first, last, context, flags, detail::global_nope);
|
||||||
|
#endif
|
||||||
return detail::resolve(context, attr_);
|
return detail::resolve(context, attr_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6895,8 +6951,10 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute_ & retval) const
|
Attribute_ & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
if (detail::gen_attrs(flags))
|
if (detail::gen_attrs(flags))
|
||||||
detail::assign_copy(retval, detail::resolve(context, attr_));
|
detail::assign_copy(retval, detail::resolve(context, attr_));
|
||||||
}
|
}
|
||||||
@@ -6961,8 +7019,10 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (first == last) {
|
if (first == last) {
|
||||||
success = false;
|
success = false;
|
||||||
@@ -7126,8 +7186,10 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (first == last) {
|
if (first == last) {
|
||||||
success = false;
|
success = false;
|
||||||
@@ -7277,8 +7339,10 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (first == last) {
|
if (first == last) {
|
||||||
success = false;
|
success = false;
|
||||||
@@ -7357,8 +7421,10 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (first == last) {
|
if (first == last) {
|
||||||
success = false;
|
success = false;
|
||||||
@@ -7479,8 +7545,10 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (first == last) {
|
if (first == last) {
|
||||||
success = false;
|
success = false;
|
||||||
@@ -7643,8 +7711,10 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (first == last) {
|
if (first == last) {
|
||||||
success = false;
|
success = false;
|
||||||
@@ -7964,8 +8034,10 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (first == last) {
|
if (first == last) {
|
||||||
success = false;
|
success = false;
|
||||||
@@ -8131,8 +8203,10 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
|
|
||||||
auto compare =
|
auto compare =
|
||||||
[no_case = context.no_case_depth_](char32_t a, char32_t b) {
|
[no_case = context.no_case_depth_](char32_t a, char32_t b) {
|
||||||
@@ -8220,8 +8294,10 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
T attr = 0;
|
T attr = 0;
|
||||||
auto const initial = first;
|
auto const initial = first;
|
||||||
success =
|
success =
|
||||||
@@ -8361,8 +8437,10 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
T attr = 0;
|
T attr = 0;
|
||||||
auto const initial = first;
|
auto const initial = first;
|
||||||
success =
|
success =
|
||||||
@@ -8476,8 +8554,10 @@ namespace boost { namespace parser {
|
|||||||
bool & success,
|
bool & success,
|
||||||
Attribute & retval) const
|
Attribute & retval) const
|
||||||
{
|
{
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
T attr = 0;
|
T attr = 0;
|
||||||
auto const initial = first;
|
auto const initial = first;
|
||||||
success = detail::numeric::parse_real(first, last, attr);
|
success = detail::numeric::parse_real(first, last, attr);
|
||||||
@@ -8570,8 +8650,10 @@ namespace boost { namespace parser {
|
|||||||
using attr_t = decltype(or_parser_.call(
|
using attr_t = decltype(or_parser_.call(
|
||||||
first, last, context, skip, flags, success));
|
first, last, context, skip, flags, success));
|
||||||
attr_t attr{};
|
attr_t attr{};
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ =
|
[[maybe_unused]] auto _ =
|
||||||
detail::scoped_trace(*this, first, last, context, flags, attr);
|
detail::scoped_trace(*this, first, last, context, flags, attr);
|
||||||
|
#endif
|
||||||
attr = or_parser_.call(first, last, context, skip, flags, success);
|
attr = or_parser_.call(first, last, context, skip, flags, success);
|
||||||
return attr;
|
return attr;
|
||||||
}
|
}
|
||||||
@@ -8596,8 +8678,10 @@ namespace boost { namespace parser {
|
|||||||
"It looks like you tried to write switch_(val). You need at "
|
"It looks like you tried to write switch_(val). You need at "
|
||||||
"least one alternative, like: switch_(val)(value_1, "
|
"least one alternative, like: switch_(val)(value_1, "
|
||||||
"parser_1)(value_2, parser_2)..."));
|
"parser_1)(value_2, parser_2)..."));
|
||||||
|
#if BOOST_PARSER_DO_TRACE
|
||||||
[[maybe_unused]] auto _ = detail::scoped_trace(
|
[[maybe_unused]] auto _ = detail::scoped_trace(
|
||||||
*this, first, last, context, flags, retval);
|
*this, first, last, context, flags, retval);
|
||||||
|
#endif
|
||||||
or_parser_.call(first, last, context, skip, flags, success, retval);
|
or_parser_.call(first, last, context, skip, flags, success, retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9056,8 +9140,13 @@ namespace boost { namespace parser {
|
|||||||
"fill in attr above, using the attribute generated by parser. "
|
"fill in attr above, using the attribute generated by parser. "
|
||||||
"However, parser does not generate an attribute.");
|
"However, parser does not generate an attribute.");
|
||||||
if (trace_mode == trace::on) {
|
if (trace_mode == trace::on) {
|
||||||
return reset = detail::parse_impl<true>(
|
return reset =
|
||||||
first, last, parser, parser.error_handler_, attr);
|
detail::parse_impl<(true && BOOST_PARSER_DO_TRACE)>(
|
||||||
|
first,
|
||||||
|
last,
|
||||||
|
parser,
|
||||||
|
parser.error_handler_,
|
||||||
|
attr);
|
||||||
} else {
|
} else {
|
||||||
return reset = detail::parse_impl<false>(
|
return reset = detail::parse_impl<false>(
|
||||||
first, last, parser, parser.error_handler_, attr);
|
first, last, parser, parser.error_handler_, attr);
|
||||||
@@ -9074,7 +9163,8 @@ namespace boost { namespace parser {
|
|||||||
"fill in attr above, using the attribute generated by parser. "
|
"fill in attr above, using the attribute generated by parser. "
|
||||||
"However, parser does not generate an attribute.");
|
"However, parser does not generate an attribute.");
|
||||||
if (trace_mode == trace::on) {
|
if (trace_mode == trace::on) {
|
||||||
return reset = detail::parse_impl<true>(
|
return reset =
|
||||||
|
detail::parse_impl<(true && BOOST_PARSER_DO_TRACE)>(
|
||||||
f, l, parser, parser.error_handler_, attr);
|
f, l, parser, parser.error_handler_, attr);
|
||||||
} else {
|
} else {
|
||||||
return reset = detail::parse_impl<false>(
|
return reset = detail::parse_impl<false>(
|
||||||
@@ -9178,7 +9268,7 @@ namespace boost { namespace parser {
|
|||||||
{
|
{
|
||||||
if constexpr (!detail::is_char8_iter_v<I>) {
|
if constexpr (!detail::is_char8_iter_v<I>) {
|
||||||
if (trace_mode == trace::on) {
|
if (trace_mode == trace::on) {
|
||||||
return detail::parse_impl<true>(
|
return detail::parse_impl<(true && BOOST_PARSER_DO_TRACE)>(
|
||||||
first, last, parser, parser.error_handler_);
|
first, last, parser, parser.error_handler_);
|
||||||
} else {
|
} else {
|
||||||
return detail::parse_impl<false>(
|
return detail::parse_impl<false>(
|
||||||
@@ -9191,7 +9281,7 @@ namespace boost { namespace parser {
|
|||||||
auto const l = r.end();
|
auto const l = r.end();
|
||||||
auto _ = detail::scoped_base_assign(first, f);
|
auto _ = detail::scoped_base_assign(first, f);
|
||||||
if (trace_mode == trace::on) {
|
if (trace_mode == trace::on) {
|
||||||
return detail::parse_impl<true>(
|
return detail::parse_impl<(true && BOOST_PARSER_DO_TRACE)>(
|
||||||
f, l, parser, parser.error_handler_);
|
f, l, parser, parser.error_handler_);
|
||||||
} else {
|
} else {
|
||||||
return detail::parse_impl<false>(
|
return detail::parse_impl<false>(
|
||||||
@@ -9297,7 +9387,8 @@ namespace boost { namespace parser {
|
|||||||
"fill in attr above, using the attribute generated by parser. "
|
"fill in attr above, using the attribute generated by parser. "
|
||||||
"However, parser does not generate an attribute.");
|
"However, parser does not generate an attribute.");
|
||||||
if (trace_mode == trace::on) {
|
if (trace_mode == trace::on) {
|
||||||
return reset = detail::skip_parse_impl<true>(
|
return reset = detail::skip_parse_impl<(
|
||||||
|
true && BOOST_PARSER_DO_TRACE)>(
|
||||||
first,
|
first,
|
||||||
last,
|
last,
|
||||||
parser,
|
parser,
|
||||||
@@ -9325,7 +9416,8 @@ namespace boost { namespace parser {
|
|||||||
"fill in attr above, using the attribute generated by parser. "
|
"fill in attr above, using the attribute generated by parser. "
|
||||||
"However, parser does not generate an attribute.");
|
"However, parser does not generate an attribute.");
|
||||||
if (trace_mode == trace::on) {
|
if (trace_mode == trace::on) {
|
||||||
return reset = detail::skip_parse_impl<true>(
|
return reset = detail::skip_parse_impl<(
|
||||||
|
true && BOOST_PARSER_DO_TRACE)>(
|
||||||
f, l, parser, skip, parser.error_handler_, attr);
|
f, l, parser, skip, parser.error_handler_, attr);
|
||||||
} else {
|
} else {
|
||||||
return reset = detail::skip_parse_impl<false>(
|
return reset = detail::skip_parse_impl<false>(
|
||||||
@@ -9430,7 +9522,7 @@ namespace boost { namespace parser {
|
|||||||
{
|
{
|
||||||
if constexpr (!detail::is_char8_iter_v<I>) {
|
if constexpr (!detail::is_char8_iter_v<I>) {
|
||||||
if (trace_mode == trace::on) {
|
if (trace_mode == trace::on) {
|
||||||
return detail::skip_parse_impl<true>(
|
return detail::skip_parse_impl<(true && BOOST_PARSER_DO_TRACE)>(
|
||||||
first, last, parser, skip, parser.error_handler_);
|
first, last, parser, skip, parser.error_handler_);
|
||||||
} else {
|
} else {
|
||||||
return detail::skip_parse_impl<false>(
|
return detail::skip_parse_impl<false>(
|
||||||
@@ -9443,7 +9535,7 @@ namespace boost { namespace parser {
|
|||||||
auto const l = r.end();
|
auto const l = r.end();
|
||||||
auto _ = detail::scoped_base_assign(first, f);
|
auto _ = detail::scoped_base_assign(first, f);
|
||||||
if (trace_mode == trace::on) {
|
if (trace_mode == trace::on) {
|
||||||
return detail::skip_parse_impl<true>(
|
return detail::skip_parse_impl<(true && BOOST_PARSER_DO_TRACE)>(
|
||||||
f, l, parser, skip, parser.error_handler_);
|
f, l, parser, skip, parser.error_handler_);
|
||||||
} else {
|
} else {
|
||||||
return detail::skip_parse_impl<false>(
|
return detail::skip_parse_impl<false>(
|
||||||
@@ -9547,7 +9639,8 @@ namespace boost { namespace parser {
|
|||||||
{
|
{
|
||||||
if constexpr (!detail::is_char8_iter_v<I>) {
|
if constexpr (!detail::is_char8_iter_v<I>) {
|
||||||
if (trace_mode == trace::on) {
|
if (trace_mode == trace::on) {
|
||||||
return detail::callback_parse_impl<true>(
|
return detail::callback_parse_impl<(
|
||||||
|
true && BOOST_PARSER_DO_TRACE)>(
|
||||||
first, last, parser, parser.error_handler_, callbacks);
|
first, last, parser, parser.error_handler_, callbacks);
|
||||||
} else {
|
} else {
|
||||||
return detail::callback_parse_impl<false>(
|
return detail::callback_parse_impl<false>(
|
||||||
@@ -9560,7 +9653,8 @@ namespace boost { namespace parser {
|
|||||||
auto const l = r.end();
|
auto const l = r.end();
|
||||||
auto _ = detail::scoped_base_assign(first, f);
|
auto _ = detail::scoped_base_assign(first, f);
|
||||||
if (trace_mode == trace::on) {
|
if (trace_mode == trace::on) {
|
||||||
return detail::callback_parse_impl<true>(
|
return detail::callback_parse_impl<(
|
||||||
|
true && BOOST_PARSER_DO_TRACE)>(
|
||||||
f, l, parser, parser.error_handler_, callbacks);
|
f, l, parser, parser.error_handler_, callbacks);
|
||||||
} else {
|
} else {
|
||||||
return detail::callback_parse_impl<false>(
|
return detail::callback_parse_impl<false>(
|
||||||
@@ -9672,7 +9766,8 @@ namespace boost { namespace parser {
|
|||||||
{
|
{
|
||||||
if constexpr (!detail::is_char8_iter_v<I>) {
|
if constexpr (!detail::is_char8_iter_v<I>) {
|
||||||
if (trace_mode == trace::on) {
|
if (trace_mode == trace::on) {
|
||||||
return detail::callback_skip_parse_impl<true>(
|
return detail::callback_skip_parse_impl<(
|
||||||
|
true && BOOST_PARSER_DO_TRACE)>(
|
||||||
first,
|
first,
|
||||||
last,
|
last,
|
||||||
parser,
|
parser,
|
||||||
@@ -9695,7 +9790,8 @@ namespace boost { namespace parser {
|
|||||||
auto const l = r.end();
|
auto const l = r.end();
|
||||||
auto _ = detail::scoped_base_assign(first, f);
|
auto _ = detail::scoped_base_assign(first, f);
|
||||||
if (trace_mode == trace::on) {
|
if (trace_mode == trace::on) {
|
||||||
return detail::callback_skip_parse_impl<true>(
|
return detail::callback_skip_parse_impl<(
|
||||||
|
true && BOOST_PARSER_DO_TRACE)>(
|
||||||
f, l, parser, skip, parser.error_handler_, callbacks);
|
f, l, parser, skip, parser.error_handler_, callbacks);
|
||||||
} else {
|
} else {
|
||||||
return detail::callback_skip_parse_impl<false>(
|
return detail::callback_skip_parse_impl<false>(
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ add_test_executable(parser_seq_permutations_1)
|
|||||||
add_test_executable(parser_seq_permutations_2)
|
add_test_executable(parser_seq_permutations_2)
|
||||||
add_test_executable(parser_or_permutations_1)
|
add_test_executable(parser_or_permutations_1)
|
||||||
add_test_executable(parser_or_permutations_2)
|
add_test_executable(parser_or_permutations_2)
|
||||||
|
add_test_executable(disable_trace)
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
add_executable(vs_output_tracing tracing.cpp)
|
add_executable(vs_output_tracing tracing.cpp)
|
||||||
|
|||||||
27
test/disable_trace.cpp
Normal file
27
test/disable_trace.cpp
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (C) 2025
|
||||||
|
*
|
||||||
|
* Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
* accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
* http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define BOOST_PARSER_DISABLE_TRACE
|
||||||
|
|
||||||
|
#include <boost/core/lightweight_test.hpp>
|
||||||
|
#include <boost/parser/parser.hpp>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
namespace bp = boost::parser;
|
||||||
|
{
|
||||||
|
auto const parser =
|
||||||
|
bp::string("FOO") >> -(bp::string("bar") | bp::string("foo"));
|
||||||
|
|
||||||
|
auto result = bp::parse("FOOfoo", parser);
|
||||||
|
BOOST_TEST(result);
|
||||||
|
BOOST_TEST(bp::get(*result, bp::llong<0>{}) == std::string("FOO"));
|
||||||
|
BOOST_TEST(bp::get(*result, bp::llong<1>{}) == std::string("foo"));
|
||||||
|
}
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
@@ -597,6 +597,186 @@ void github_pr_297()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace github_issue_312_ {
|
||||||
|
/*
|
||||||
|
* Recursive descent parser for expressions.
|
||||||
|
* Supports addition (+), multiplication (*) and
|
||||||
|
* parethesized expressions, nothing else.
|
||||||
|
*
|
||||||
|
* Creates a tree of "evaluatable" objects which
|
||||||
|
* own their downstream objects in a unique_ptr
|
||||||
|
*/
|
||||||
|
|
||||||
|
// base class for all tree nodes
|
||||||
|
struct evaluatable
|
||||||
|
{
|
||||||
|
virtual double evaluate() = 0;
|
||||||
|
virtual ~evaluatable() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace bp = boost::parser;
|
||||||
|
|
||||||
|
// top level parser
|
||||||
|
constexpr bp::rule<struct expression_tag, std::unique_ptr<evaluatable>> expression_parser = "expression_parser";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LITERAL EXPRESSION
|
||||||
|
*/
|
||||||
|
struct literal_evaluatable : evaluatable
|
||||||
|
{
|
||||||
|
explicit literal_evaluatable(double v) : value_(v) {}
|
||||||
|
double evaluate() override
|
||||||
|
{
|
||||||
|
return value_;
|
||||||
|
}
|
||||||
|
double value_;
|
||||||
|
};
|
||||||
|
constexpr bp::rule<struct literal_tag, std::unique_ptr<evaluatable>> literal_parser = "literal_parser";
|
||||||
|
constexpr auto literal_parser_action = [](auto& ctx) {
|
||||||
|
std::unique_ptr<evaluatable>& val = _val(ctx);
|
||||||
|
double& parsed_value = _attr(ctx);
|
||||||
|
val = std::make_unique<literal_evaluatable>(parsed_value);
|
||||||
|
};
|
||||||
|
constexpr auto literal_parser_def =
|
||||||
|
bp::double_[literal_parser_action];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PARENTHESIZED EXPRESSION
|
||||||
|
*/
|
||||||
|
struct parenthesized_evaluatable : evaluatable
|
||||||
|
{
|
||||||
|
explicit parenthesized_evaluatable(std::unique_ptr<evaluatable>&& e) : evaluatable_(std::move(e)) {}
|
||||||
|
double evaluate() override
|
||||||
|
{
|
||||||
|
return evaluatable_->evaluate();
|
||||||
|
}
|
||||||
|
std::unique_ptr<evaluatable> evaluatable_;
|
||||||
|
};
|
||||||
|
constexpr bp::rule<struct parenthesized_tag, std::unique_ptr<evaluatable>> parenthesized_parser = "parenthesized_parser";
|
||||||
|
constexpr auto parenthesized_action = [](auto& ctx) {
|
||||||
|
std::unique_ptr<evaluatable>& val = _val(ctx);
|
||||||
|
std::unique_ptr<evaluatable>& attr = _attr(ctx);
|
||||||
|
val = std::make_unique<parenthesized_evaluatable>(std::move(attr));
|
||||||
|
};
|
||||||
|
constexpr auto parenthesized_parser_def =
|
||||||
|
(
|
||||||
|
bp::lit('(') > expression_parser > bp::lit(')')
|
||||||
|
)[parenthesized_action];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ATOM EXPRESSION
|
||||||
|
*/
|
||||||
|
struct atom_evaluatable : evaluatable
|
||||||
|
{
|
||||||
|
explicit atom_evaluatable(std::unique_ptr<evaluatable>&& e) : evaluatable_(std::move(e)) {}
|
||||||
|
double evaluate() override
|
||||||
|
{
|
||||||
|
return evaluatable_->evaluate();
|
||||||
|
}
|
||||||
|
std::unique_ptr<evaluatable> evaluatable_;
|
||||||
|
};
|
||||||
|
constexpr bp::rule<struct atom_tag, std::unique_ptr<evaluatable>> atom_parser = "atom_parser";
|
||||||
|
constexpr auto atom_action = [](auto& ctx) {
|
||||||
|
std::unique_ptr<evaluatable>& val = _val(ctx);
|
||||||
|
std::unique_ptr<evaluatable>& attr = _attr(ctx);
|
||||||
|
val = std::make_unique<atom_evaluatable>(std::move(attr));
|
||||||
|
};
|
||||||
|
constexpr auto atom_parser_def =
|
||||||
|
(
|
||||||
|
parenthesized_parser
|
||||||
|
|
|
||||||
|
literal_parser
|
||||||
|
)[atom_action];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MULTIPLICATION EXPRESSION
|
||||||
|
*/
|
||||||
|
struct multiplication_evaluatable : evaluatable
|
||||||
|
{
|
||||||
|
multiplication_evaluatable(std::vector<std::unique_ptr<evaluatable>>&& e)
|
||||||
|
: evaluatables_(std::move(e))
|
||||||
|
{}
|
||||||
|
double evaluate() override
|
||||||
|
{
|
||||||
|
double result = 1;
|
||||||
|
for (const auto& e : evaluatables_) {
|
||||||
|
result *= e->evaluate();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
std::vector<std::unique_ptr<evaluatable>> evaluatables_;
|
||||||
|
};
|
||||||
|
constexpr bp::rule<struct mult_tag, std::unique_ptr<evaluatable>> mult_parser = "mult_parser";
|
||||||
|
constexpr auto mult_parser_action = [](auto& ctx) {
|
||||||
|
std::unique_ptr<evaluatable>& val = _val(ctx);
|
||||||
|
std::vector<std::unique_ptr<evaluatable>>& operands = _attr(ctx);
|
||||||
|
val = std::make_unique<multiplication_evaluatable>(std::move(operands));
|
||||||
|
};
|
||||||
|
constexpr auto mult_parser_def =
|
||||||
|
(atom_parser % bp::lit('*'))[mult_parser_action];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ADDITION EXPRESSION
|
||||||
|
*/
|
||||||
|
struct addition_evaluatable : evaluatable
|
||||||
|
{
|
||||||
|
addition_evaluatable(std::vector<std::unique_ptr<evaluatable>>&& e)
|
||||||
|
: evaluatables_(std::move(e))
|
||||||
|
{}
|
||||||
|
double evaluate() override
|
||||||
|
{
|
||||||
|
double result = 0;
|
||||||
|
for (const auto& e : evaluatables_) {
|
||||||
|
result += e->evaluate();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
std::vector<std::unique_ptr<evaluatable>> evaluatables_;
|
||||||
|
};
|
||||||
|
constexpr bp::rule<struct add_tag, std::unique_ptr<evaluatable>> add_parser = "add_parser";
|
||||||
|
constexpr auto add_parser_action = [](auto& ctx) {
|
||||||
|
std::unique_ptr<evaluatable>& val = _val(ctx);
|
||||||
|
std::vector<std::unique_ptr<evaluatable>>& operands = _attr(ctx);
|
||||||
|
val = std::make_unique<addition_evaluatable>(std::move(operands));
|
||||||
|
};
|
||||||
|
constexpr auto add_parser_def =
|
||||||
|
(mult_parser % bp::lit('+'))[add_parser_action];
|
||||||
|
|
||||||
|
constexpr auto expression_parser_action = [](auto& ctx) {
|
||||||
|
std::unique_ptr<evaluatable>& val = _val(ctx);
|
||||||
|
std::unique_ptr<evaluatable>& attr = _attr(ctx);
|
||||||
|
val = std::move(attr);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EXPRESSION
|
||||||
|
*/
|
||||||
|
constexpr auto expression_parser_def =
|
||||||
|
add_parser[expression_parser_action];
|
||||||
|
|
||||||
|
BOOST_PARSER_DEFINE_RULES(
|
||||||
|
literal_parser,
|
||||||
|
mult_parser,
|
||||||
|
add_parser,
|
||||||
|
expression_parser,
|
||||||
|
parenthesized_parser,
|
||||||
|
atom_parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
void github_issue_312()
|
||||||
|
{
|
||||||
|
namespace bp = boost::parser;
|
||||||
|
using namespace github_issue_312_;
|
||||||
|
|
||||||
|
auto result = bp::parse("(2 + 3) + 3.1415 * 2", expression_parser, bp::blank);
|
||||||
|
BOOST_TEST(result);
|
||||||
|
BOOST_TEST(result.value()->evaluate() == (2 + 3) + 3.1415 * 2);
|
||||||
|
|
||||||
|
result = bp::parse("((2*0.1) + 33.) * (2 + 3) + 3.1415 * 2", expression_parser, bp::blank);
|
||||||
|
BOOST_TEST(result);
|
||||||
|
BOOST_TEST(result.value()->evaluate() == ((2*0.1) + 33.) * (2 + 3) + 3.1415 * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
@@ -615,5 +795,6 @@ int main()
|
|||||||
github_pr_290();
|
github_pr_290();
|
||||||
github_issue_294();
|
github_issue_294();
|
||||||
github_pr_297();
|
github_pr_297();
|
||||||
|
github_issue_312();
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user