mirror of
https://github.com/boostorg/parser.git
synced 2026-01-19 04:22:13 +00:00
Add more tests of seq_parser and or_parser, to cover all the permutations of
different parsers that they might use. Fixes #126.
This commit is contained in:
@@ -53,6 +53,7 @@ add_test_executable(replace)
|
||||
add_test_executable(transform_replace)
|
||||
add_test_executable(hl)
|
||||
add_test_executable(aggr_tuple_assignment)
|
||||
add_test_executable(parser_attributes)
|
||||
add_test_executable(parser_lazy_params)
|
||||
add_test_executable(parser_if_switch)
|
||||
add_test_executable(parser_rule)
|
||||
@@ -68,3 +69,7 @@ add_test_executable(case_fold_generated)
|
||||
add_test_executable(no_case)
|
||||
add_test_executable(merge_separate)
|
||||
add_test_executable(parse_coords_new)
|
||||
add_test_executable(parser_seq_permutations_1)
|
||||
add_test_executable(parser_seq_permutations_2)
|
||||
add_test_executable(parser_or_permutations_1)
|
||||
add_test_executable(parser_or_permutations_2)
|
||||
|
||||
67
test/parser_attributes.cpp
Normal file
67
test/parser_attributes.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Copyright (C) 2024 T. Zachary Laine
|
||||
*
|
||||
* 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)
|
||||
*/
|
||||
|
||||
#include <boost/parser/parser.hpp>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
|
||||
namespace bp = boost::parser;
|
||||
|
||||
bp::rule<struct seq1_tag, bp::tuple<int, char>> seq1 = "";
|
||||
bp::rule<struct seq2_tag, bp::tuple<int, char>> seq2 = "";
|
||||
auto const seq1_def = bp::int_ >> bp::char_('a');
|
||||
auto const seq2_def = bp::int_ >> bp::char_('b');
|
||||
BOOST_PARSER_DEFINE_RULES(seq1, seq2);
|
||||
|
||||
TEST(attributes, internal_errors_munging_attributes)
|
||||
{
|
||||
// These are just some assorted cases that have, or seemed likely to,
|
||||
// cause problems when an internal failure in an alternative wipes out an
|
||||
// existing result. This covers all the cases where "if (!success)"
|
||||
// causes the attribute to be overwritten with a default-constructed
|
||||
// value.
|
||||
|
||||
{
|
||||
auto const parser =
|
||||
bp::string("FOO") >> -(bp::string("bar") | bp::string("foo"));
|
||||
|
||||
auto result = bp::parse("FOOfoo", parser);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(bp::get(*result, bp::llong<0>{}), std::string("FOO"));
|
||||
EXPECT_EQ(bp::get(*result, bp::llong<1>{}), std::string("foo"));
|
||||
}
|
||||
|
||||
{
|
||||
auto const parser = bp::merge
|
||||
[bp::string("FOO") >> (bp::string("bar") | bp::string("foo"))];
|
||||
|
||||
auto result = bp::parse("FOOfoo", parser);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, std::string("FOOfoo"));
|
||||
}
|
||||
|
||||
{
|
||||
auto const parser = bp::merge
|
||||
[(bp::attr(std::vector<std::string>({"FOO"})) | bp::eps) >>
|
||||
(bp::repeat(1)[bp::string("foo")] | bp::eps)];
|
||||
|
||||
auto result = bp::parse("", parser);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_TRUE(*result);
|
||||
EXPECT_EQ(*result, std::vector<std::string>({"FOO"}));
|
||||
}
|
||||
|
||||
{
|
||||
auto const parser = bp::merge[seq1 >> (seq2 | seq1)];
|
||||
|
||||
auto result = bp::parse("7a9a", parser);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (bp::tuple<int, char>(9, 'a')));
|
||||
}
|
||||
}
|
||||
338
test/parser_or_permutations_1.cpp
Normal file
338
test/parser_or_permutations_1.cpp
Normal file
@@ -0,0 +1,338 @@
|
||||
/**
|
||||
* Copyright (C) 2024 T. Zachary Laine
|
||||
*
|
||||
* 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)
|
||||
*/
|
||||
|
||||
#include <boost/parser/parser.hpp>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
|
||||
namespace bp = boost::parser;
|
||||
|
||||
namespace make {
|
||||
template<typename... Ts>
|
||||
auto tuple(Ts &&... xs)
|
||||
{
|
||||
return bp::tuple<Ts...>((Ts &&) xs...);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
{P0, -P0, *P0, P1, P2, P3, eps}
|
||||
<cartesian product>
|
||||
{P0, P1, P2, P3, eps, *P0, -P0, (P0 |/>> P2), -(P0 |/>> P1), (-P0 |/>> P1)}
|
||||
|
||||
P0 = bp::string("foo");
|
||||
P1 = bp::string("bar");
|
||||
P2 = bp::int_;
|
||||
P3 = bp::char_('c');
|
||||
*/
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
TEST(attributes, or_parser_permutations_1)
|
||||
{
|
||||
[[maybe_unused]] int dummy = 0; // for clang-format(!)
|
||||
|
||||
// P0
|
||||
{
|
||||
auto result = bp::parse("foo", bp::string("foo") | bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, "foo"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("bar", bp::string("foo") | bp::string("bar"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, "bar"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("42", bp::string("foo") | bp::int_);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 1u);
|
||||
EXPECT_EQ(std::get<int>(*result), 42);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("c", bp::string("foo") | bp::char_('c'));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 1u);
|
||||
EXPECT_EQ(std::get<char>(*result), 'c');
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("foo", bp::string("foo") | bp::eps);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, std::optional("foo"s));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("foo", bp::string("foo") | *bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<std::string>(*result), "foo"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("", bp::string("foo") | -bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 1u);
|
||||
EXPECT_EQ(std::get<std::optional<std::string>>(*result), std::nullopt);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foo", bp::string("foo") | (bp::string("foo") | bp::int_));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<std::string>(*result), "foo"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"bar",
|
||||
bp::string("foo") | -(bp::string("foo") | bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 1);
|
||||
EXPECT_EQ(std::get<std::optional<std::string>>(*result), "bar"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"", bp::string("foo") | (-bp::string("foo") | bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 1);
|
||||
EXPECT_EQ(std::get<std::optional<std::string>>(*result), std::nullopt);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foo", bp::string("foo") | (bp::string("foo") >> bp::int_));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<std::string>(*result), "foo"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"", bp::string("foo") | -(bp::string("foo") >> bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 1u);
|
||||
EXPECT_EQ(
|
||||
(std::get<std::optional<bp::tuple<std::string, std::string>>>(
|
||||
*result)),
|
||||
std::nullopt);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"bar",
|
||||
bp::string("foo") | (-bp::string("foo") >> bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 1u);
|
||||
EXPECT_EQ(
|
||||
(std::get<bp::tuple<std::optional<std::string>, std::string>>(
|
||||
*result)),
|
||||
(make::tuple(std::optional<std::string>{}, "bar"s)));
|
||||
}
|
||||
|
||||
// -P0
|
||||
{
|
||||
auto result = bp::parse("foo", -bp::string("foo") | bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(
|
||||
std::get<std::optional<std::string>>(*result),
|
||||
std::optional("foo"s));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("", -bp::string("foo") | bp::string("bar"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<std::optional<std::string>>(*result), std::nullopt);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("", -bp::string("foo") | bp::int_);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<std::optional<std::string>>(*result), std::nullopt);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("", -bp::string("foo") | bp::char_('c'));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<std::optional<std::string>>(*result), std::nullopt);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("foo", -bp::string("foo") | bp::eps);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, "foo"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("foo", -bp::string("foo") | *bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<std::optional<std::string>>(*result), "foo"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("foo", -bp::string("foo") | -bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, "foo"s);
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("", -bp::string("foo") | (bp::string("foo") | bp::int_));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<std::optional<std::string>>(*result), std::nullopt);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foo",
|
||||
-bp::string("foo") | -(bp::string("foo") | bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, "foo"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"", -bp::string("foo") | (-bp::string("foo") | bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<std::optional<std::string>>(*result), std::nullopt);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foo", -bp::string("foo") | (bp::string("foo") >> bp::int_));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<std::optional<std::string>>(*result), "foo"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foo",
|
||||
-bp::string("foo") | -(bp::string("foo") >> bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<std::optional<std::string>>(*result), "foo"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foo",
|
||||
-bp::string("foo") | (-bp::string("foo") >> bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<std::optional<std::string>>(*result), "foo"s);
|
||||
}
|
||||
|
||||
// *P0
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foo", bp::lexeme[*bp::string("foo")] | bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(
|
||||
std::get<std::vector<std::string>>(*result), std::vector({"foo"s}));
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("foofoo", *bp::string("foo") | bp::string("bar"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(
|
||||
std::get<std::vector<std::string>>(*result),
|
||||
std::vector({"foo"s, "foo"s}));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("", *bp::string("foo") | bp::int_);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(
|
||||
std::get<std::vector<std::string>>(*result),
|
||||
std::vector<std::string>{});
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("", *bp::string("foo") | bp::char_('c'));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(
|
||||
std::get<std::vector<std::string>>(*result),
|
||||
std::vector<std::string>{});
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("foofoo", *bp::string("foo") | bp::eps);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, std::optional(std::vector({"foo"s, "foo"s})));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foofoo", bp::lexeme[*bp::string("foo")] | *bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, std::vector({"foo"s, "foo"s}));
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("foofoo", *bp::string("foo") | -bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(
|
||||
std::get<std::vector<std::string>>(*result),
|
||||
std::vector({"foo"s, "foo"s}));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foofoo",
|
||||
bp::lexeme[*bp::string("foo")] | (bp::string("foo") | bp::int_));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(
|
||||
std::get<std::vector<std::string>>(*result),
|
||||
std::vector({"foo"s, "foo"s}));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foofoo",
|
||||
bp::lexeme[*bp::string("foo")] |
|
||||
-(bp::string("foo") | bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(
|
||||
std::get<std::vector<std::string>>(*result),
|
||||
std::vector({"foo"s, "foo"s}));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foofoo",
|
||||
bp::lexeme[*bp::string("foo")] |
|
||||
(-bp::string("foo") | bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(
|
||||
std::get<std::vector<std::string>>(*result),
|
||||
std::vector({"foo"s, "foo"s}));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foofoo",
|
||||
bp::lexeme[*bp::string("foo")] | (bp::string("foo") >> bp::int_));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(
|
||||
std::get<std::vector<std::string>>(*result),
|
||||
std::vector({"foo"s, "foo"s}));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foofoo",
|
||||
bp::lexeme[*bp::string("foo")] |
|
||||
-(bp::string("foo") >> bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(
|
||||
std::get<std::vector<std::string>>(*result),
|
||||
std::vector({"foo"s, "foo"s}));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foofoo",
|
||||
bp::lexeme[*bp::string("foo")] |
|
||||
(-bp::string("foo") >> bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(
|
||||
std::get<std::vector<std::string>>(*result),
|
||||
std::vector({"foo"s, "foo"s}));
|
||||
}
|
||||
}
|
||||
312
test/parser_or_permutations_2.cpp
Normal file
312
test/parser_or_permutations_2.cpp
Normal file
@@ -0,0 +1,312 @@
|
||||
/**
|
||||
* Copyright (C) 2024 T. Zachary Laine
|
||||
*
|
||||
* 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)
|
||||
*/
|
||||
|
||||
#include <boost/parser/parser.hpp>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
|
||||
namespace bp = boost::parser;
|
||||
|
||||
namespace make {
|
||||
template<typename... Ts>
|
||||
auto tuple(Ts &&... xs)
|
||||
{
|
||||
return bp::tuple<Ts...>((Ts &&) xs...);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
{P0, -P0, *P0, P1, P2, P3, eps}
|
||||
<cartesian product>
|
||||
{P0, P1, P2, P3, eps, *P0, -P0, (P0 >>/| P2), -(P0 >>/| P1), (-P0 >>/| P1)}
|
||||
|
||||
P0 = bp::string("foo");
|
||||
P1 = bp::string("bar");
|
||||
P2 = bp::int_;
|
||||
P3 = bp::char_('c');
|
||||
*/
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
TEST(attributes, or_parser_permutations_2)
|
||||
{
|
||||
[[maybe_unused]] int dummy = 0; // for clang-format(!)
|
||||
|
||||
// P1
|
||||
{
|
||||
auto result = bp::parse("foo", bp::string("bar") | bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, "foo"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("bar", bp::string("bar") | bp::string("bar"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, "bar"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("42", bp::string("bar") | bp::int_);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 1u);
|
||||
EXPECT_EQ(std::get<int>(*result), 42);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("bar", bp::string("bar") | bp::char_('c'));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<std::string>(*result), "bar"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("", bp::string("bar") | bp::eps);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, std::nullopt);
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("foofoo", bp::string("bar") | *bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 1u);
|
||||
EXPECT_EQ(
|
||||
std::get<std::vector<std::string>>(*result),
|
||||
std::vector({"foo"s, "foo"s}));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("bar", bp::string("bar") | -bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<std::string>(*result), "bar"s);
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("42", bp::string("bar") | (bp::string("foo") | bp::int_));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 1u);
|
||||
EXPECT_EQ(std::get<int>(*result), 42);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"bar",
|
||||
bp::string("foo") | -(bp::string("foo") | bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 1u);
|
||||
EXPECT_EQ(std::get<std::optional<std::string>>(*result), "bar"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foo",
|
||||
bp::string("bar") | (-bp::string("foo") | bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 1u);
|
||||
EXPECT_EQ(std::get<std::optional<std::string>>(*result), "foo"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"bar", bp::string("bar") | (bp::string("foo") >> bp::int_));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<std::string>(*result), "bar"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"bar",
|
||||
bp::string("bar") | -(bp::string("foo") >> bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<std::string>(*result), "bar"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"bar",
|
||||
bp::string("bar") | (-bp::string("foo") >> bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<std::string>(*result), "bar"s);
|
||||
}
|
||||
|
||||
// P2
|
||||
{
|
||||
auto result = bp::parse("42", bp::int_ | bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<int>(*result), 42);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("bar", bp::int_ | bp::string("bar"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 1u);
|
||||
EXPECT_EQ(std::get<std::string>(*result), "bar"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("42", bp::int_ | bp::int_, bp::ws);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, 42);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("c", bp::int_ | bp::char_('c'));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 1u);
|
||||
EXPECT_EQ(std::get<char>(*result), 'c');
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("", bp::int_ | bp::eps);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, std::nullopt);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("foofoo", bp::int_ | *bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 1u);
|
||||
EXPECT_EQ(
|
||||
std::get<std::vector<std::string>>(*result),
|
||||
std::vector({"foo"s, "foo"s}));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("42", bp::int_ | -bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<int>(*result), 42);
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("42", bp::int_ | (bp::string("foo") | bp::int_));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<int>(*result), 42);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"bar", bp::int_ | -(bp::string("foo") | bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 1u);
|
||||
EXPECT_EQ(
|
||||
std::get<std::optional<std::string>>(*result),
|
||||
std::optional("bar"s));
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("", bp::int_ | (-bp::string("foo") | bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 1u);
|
||||
EXPECT_EQ(std::get<std::optional<std::string>>(*result), std::nullopt);
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("42", bp::int_ | (bp::string("foo") >> bp::int_));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<int>(*result), 42);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"42", bp::int_ | -(bp::string("foo") >> bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<int>(*result), 42);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"42", bp::int_ | (-bp::string("foo") >> bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<int>(*result), 42);
|
||||
}
|
||||
|
||||
// P3
|
||||
{
|
||||
auto result = bp::parse("c", bp::char_('c') | bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<char>(*result), 'c');
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("bar", bp::char_('c') | bp::string("bar"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 1u);
|
||||
EXPECT_EQ(std::get<std::string>(*result), "bar"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("42", bp::char_('c') | bp::int_);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 1u);
|
||||
EXPECT_EQ(std::get<int>(*result), 42);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("c", bp::char_('c') | bp::char_('c'));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, 'c');
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("c", bp::char_('c') | bp::eps);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, 'c');
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("foofoo", bp::char_('c') | *bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 1u);
|
||||
EXPECT_EQ(
|
||||
std::get<std::vector<std::string>>(*result),
|
||||
std::vector({"foo"s, "foo"s}));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("c", bp::char_('c') | -bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<char>(*result), 'c');
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("42", bp::char_('c') | (bp::string("foo") | bp::int_));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 2u);
|
||||
EXPECT_EQ(std::get<int>(*result), 42);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"bar", bp::char_('c') | -(bp::string("foo") | bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 1u);
|
||||
EXPECT_EQ(
|
||||
std::get<std::optional<std::string>>(*result),
|
||||
std::optional("bar"s));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foo", bp::char_('c') | (-bp::string("foo") | bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 1u);
|
||||
EXPECT_EQ(
|
||||
std::get<std::optional<std::string>>(*result),
|
||||
std::optional("foo"s));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foo42", bp::char_('c') | (bp::string("foo") >> bp::int_));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 1u);
|
||||
EXPECT_EQ(
|
||||
(std::get<bp::tuple<std::string, int>>(*result)),
|
||||
(make::tuple("foo"s, 42)));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"c", bp::char_('c') | -(bp::string("foo") >> bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<char>(*result), 'c');
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"c", bp::char_('c') | (-bp::string("foo") >> bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(result->index(), 0);
|
||||
EXPECT_EQ(std::get<char>(*result), 'c');
|
||||
}
|
||||
|
||||
// eps | ... prohibited.
|
||||
}
|
||||
339
test/parser_seq_permutations_1.cpp
Normal file
339
test/parser_seq_permutations_1.cpp
Normal file
@@ -0,0 +1,339 @@
|
||||
/**
|
||||
* Copyright (C) 2024 T. Zachary Laine
|
||||
*
|
||||
* 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)
|
||||
*/
|
||||
|
||||
#include <boost/parser/parser.hpp>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
|
||||
namespace bp = boost::parser;
|
||||
|
||||
namespace make {
|
||||
template<typename... Ts>
|
||||
auto tuple(Ts &&... xs)
|
||||
{
|
||||
return bp::tuple<Ts...>((Ts &&) xs...);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
{P0, -P0, *P0, P1, P2, P3, eps}
|
||||
<cartesian product>
|
||||
{P0, P1, P2, P3, eps, *P0, -P0, (P0 >>/| P2), -(P0 >>/| P1), (-P0 >>/| P1)}
|
||||
|
||||
P0 = bp::string("foo");
|
||||
P1 = bp::string("bar");
|
||||
P2 = bp::int_;
|
||||
P3 = bp::char_('c');
|
||||
*/
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
TEST(attributes, seq_parser_permutations_1)
|
||||
{
|
||||
[[maybe_unused]] int dummy = 0; // for clang-format(!)
|
||||
|
||||
// P0
|
||||
{
|
||||
auto result =
|
||||
bp::parse("foofoo", bp::string("foo") >> bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple("foo"s, "foo"s)));
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("foobar", bp::string("foo") >> bp::string("bar"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple("foo"s, "bar"s)));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("foo42", bp::string("foo") >> bp::int_);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple("foo"s, 42)));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("fooc", bp::string("foo") >> bp::char_('c'));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, "fooc"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("foo", bp::string("foo") >> bp::eps);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, "foo"s);
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("foofoofoo", bp::string("foo") >> *bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, std::vector({"foo"s, "foo"s, "foo"s}));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("foo", bp::string("foo") >> -bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple("foo"s, std::optional<std::string>{})));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foofoo42", bp::string("foo") >> (bp::string("foo") >> bp::int_));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple("foo"s, "foo"s, 42)));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foofoobar",
|
||||
bp::string("foo") >> -(bp::string("foo") >> bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result,
|
||||
(make::tuple("foo"s, std::optional(make::tuple("foo"s, "bar"s)))));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foofoobar",
|
||||
bp::string("foo") >> (-bp::string("foo") >> bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result, (make::tuple("foo"s, std::optional("foo"s), "bar"s)));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foo42", bp::string("foo") >> (bp::string("foo") | bp::int_));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result, (make::tuple("foo"s, std::variant<std::string, int>(42))));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foo",
|
||||
bp::string("foo") >> -(bp::string("foo") | bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple("foo"s, std::optional<std::string>{})));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foo",
|
||||
bp::string("foo") >> (-bp::string("foo") | bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result,
|
||||
(make::tuple(
|
||||
"foo"s,
|
||||
std::variant<std::optional<std::string>, std::string>(
|
||||
std::nullopt))));
|
||||
}
|
||||
|
||||
// -P0
|
||||
{
|
||||
auto result =
|
||||
bp::parse("foofoo", -bp::string("foo") >> bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple(std::optional("foo"s), "foo"s)));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("bar", -bp::string("foo") >> bp::string("bar"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple(std::optional<std::string>{}, "bar"s)));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("42", -bp::string("foo") >> bp::int_);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple(std::optional<std::string>{}, 42)));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("c", -bp::string("foo") >> bp::char_('c'));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple(std::optional<std::string>{}, 'c')));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("foo", -bp::string("foo") >> bp::eps);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, std::optional("foo"s));
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("foofoo", -bp::string("foo") >> *bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, std::vector({"foo"s, "foo"s}));
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("foofoo", -bp::string("foo") >> -bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result,
|
||||
(make::tuple(std::optional("foo"s), std::optional("foo"s))));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foofoo42", -bp::string("foo") >> (bp::string("foo") >> bp::int_));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple(std::optional("foo"s), "foo"s, 42)));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foofoobar",
|
||||
-bp::string("foo") >> -(bp::string("foo") >> bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result,
|
||||
(make::tuple(
|
||||
std::optional("foo"s),
|
||||
std::optional((make::tuple("foo"s, "bar"s))))));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foofoobar",
|
||||
-bp::string("foo") >> (-bp::string("foo") >> bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result,
|
||||
(make::tuple(
|
||||
std::optional("foo"s), std::optional("foo"s), "bar"s)));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foo42", -bp::string("foo") >> (bp::string("foo") | bp::int_));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result,
|
||||
(make::tuple(
|
||||
std::optional("foo"s), std::variant<std::string, int>(42))));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foobar",
|
||||
-bp::string("foo") >> -(bp::string("foo") | bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result,
|
||||
(make::tuple(std::optional("foo"s), std::optional("bar"s))));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foofoo",
|
||||
-bp::string("foo") >> (-bp::string("foo") | bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result,
|
||||
(make::tuple(
|
||||
"foo"s,
|
||||
std::variant<std::optional<std::string>, std::string>(
|
||||
std::optional("foo"s)))));
|
||||
}
|
||||
|
||||
// *P0
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foo foo",
|
||||
bp::lexeme[*bp::string("foo")] >> bp::string("foo"),
|
||||
bp::ws);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, std::vector({"foo"s, "foo"s}));
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("foobar", *bp::string("foo") >> bp::string("bar"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, std::vector({"foo"s, "bar"s}));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("foo42", *bp::string("foo") >> bp::int_);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple(std::vector({"foo"s}), 42)));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("fooc", *bp::string("foo") >> bp::char_('c'));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple(std::vector({"foo"s}), 'c')));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("foo", *bp::string("foo") >> bp::eps);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, std::vector({"foo"s}));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foo foo",
|
||||
bp::lexeme[*bp::string("foo")] >> *bp::string("foo"),
|
||||
bp::ws);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result,
|
||||
(make::tuple(std::vector({"foo"s}), std::vector({"foo"s}))));
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("foo", *bp::string("foo") >> -bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, std::vector({"foo"s}));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foo foo42",
|
||||
bp::lexeme[*bp::string("foo")] >> (bp::string("foo") >> bp::int_),
|
||||
bp::ws);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple(std::vector({"foo"s, "foo"s}), 42)));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foo foobar",
|
||||
bp::lexeme[*bp::string("foo")] >>
|
||||
-(bp::string("foo") >> bp::string("bar")),
|
||||
bp::ws);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result,
|
||||
(make::tuple(
|
||||
std::vector({"foo"s}),
|
||||
std::optional((make::tuple("foo"s, "bar"s))))));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foo foobar",
|
||||
bp::lexeme[*bp::string("foo")] >>
|
||||
(-bp::string("foo") >> bp::string("bar")),
|
||||
bp::ws);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, std::vector({"foo"s, "foo"s, "bar"s}));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foo 42",
|
||||
bp::lexeme[*bp::string("foo")] >> (bp::string("foo") | bp::int_),
|
||||
bp::ws);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result,
|
||||
(make::tuple(
|
||||
std::vector({"foo"s}), std::variant<std::string, int>(42))));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foo bar",
|
||||
bp::lexeme[*bp::string("foo")] >>
|
||||
-(bp::string("foo") | bp::string("bar")),
|
||||
bp::ws);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, std::vector({"foo"s, "bar"s}));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foo",
|
||||
bp::lexeme[*bp::string("foo")] >>
|
||||
(-bp::string("foo") | bp::string("bar")),
|
||||
bp::ws);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result,
|
||||
(make::tuple(
|
||||
std::vector({"foo"s}),
|
||||
std::variant<std::optional<std::string>, std::string>(
|
||||
std::nullopt))));
|
||||
}
|
||||
}
|
||||
370
test/parser_seq_permutations_2.cpp
Normal file
370
test/parser_seq_permutations_2.cpp
Normal file
@@ -0,0 +1,370 @@
|
||||
/**
|
||||
* Copyright (C) 2024 T. Zachary Laine
|
||||
*
|
||||
* 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)
|
||||
*/
|
||||
|
||||
#include <boost/parser/parser.hpp>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
|
||||
namespace bp = boost::parser;
|
||||
|
||||
namespace make {
|
||||
template<typename... Ts>
|
||||
auto tuple(Ts &&... xs)
|
||||
{
|
||||
return bp::tuple<Ts...>((Ts &&) xs...);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
{P0, -P0, *P0, P1, P2, P3, eps}
|
||||
<cartesian product>
|
||||
{P0, P1, P2, P3, eps, *P0, -P0, (P0 >>/| P2), -(P0 >>/| P1), (-P0 >>/| P1)}
|
||||
|
||||
P0 = bp::string("foo");
|
||||
P1 = bp::string("bar");
|
||||
P2 = bp::int_;
|
||||
P3 = bp::char_('c');
|
||||
*/
|
||||
|
||||
using namespace std::literals;
|
||||
|
||||
TEST(attributes, seq_parser_permutations_2)
|
||||
{
|
||||
[[maybe_unused]] int dummy = 0; // for clang-format(!)
|
||||
|
||||
// P1
|
||||
{
|
||||
auto result =
|
||||
bp::parse("barfoo", bp::string("bar") >> bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple("bar"s, "foo"s)));
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("barbar", bp::string("bar") >> bp::string("bar"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple("bar"s, "bar"s)));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("bar42", bp::string("bar") >> bp::int_);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple("bar"s, 42)));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("barc", bp::string("bar") >> bp::char_('c'));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, "barc"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("bar", bp::string("bar") >> bp::eps);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, "bar"s);
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("barfoofoo", bp::string("bar") >> *bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, std::vector({"bar"s, "foo"s, "foo"s}));
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("barfoo", bp::string("bar") >> -bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple("bar"s, std::optional("foo"s))));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"barfoo42", bp::string("bar") >> (bp::string("foo") >> bp::int_));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple("bar"s, "foo"s, 42)));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"barfoobar",
|
||||
bp::string("bar") >> -(bp::string("foo") >> bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result,
|
||||
(make::tuple("bar"s, std::optional(make::tuple("foo"s, "bar"s)))));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"barfoobar",
|
||||
bp::string("bar") >> (-bp::string("foo") >> bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result, (make::tuple("bar"s, std::optional("foo"s), "bar"s)));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"bar42", bp::string("bar") >> (bp::string("foo") | bp::int_));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result, (make::tuple("bar"s, std::variant<std::string, int>(42))));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"bar",
|
||||
bp::string("bar") >> -(bp::string("foo") | bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple("bar"s, std::optional<std::string>{})));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"bar",
|
||||
bp::string("bar") >> (-bp::string("foo") | bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result,
|
||||
make::tuple(
|
||||
"bar"s,
|
||||
std::variant<std::optional<std::string>, std::string>(
|
||||
std::nullopt)));
|
||||
}
|
||||
|
||||
// P2
|
||||
{
|
||||
auto result = bp::parse("42foo", bp::int_ >> bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple(42, "foo"s)));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("42bar", bp::int_ >> bp::string("bar"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple(42, "bar"s)));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("42 42", bp::int_ >> bp::int_, bp::ws);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple(42, 42)));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("42c", bp::int_ >> bp::char_('c'));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple(42, 'c')));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("42", bp::int_ >> bp::eps);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, 42);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("42foofoo", bp::int_ >> *bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple(42, std::vector({"foo"s, "foo"s}))));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("42foo", bp::int_ >> -bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple(42, std::optional("foo"s))));
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("42foo42", bp::int_ >> (bp::string("foo") >> bp::int_));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple(42, "foo"s, 42)));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"42foobar", bp::int_ >> -(bp::string("foo") >> bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result,
|
||||
(make::tuple(42, std::optional(make::tuple("foo"s, "bar"s)))));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"42foobar", bp::int_ >> (-bp::string("foo") >> bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple(42, std::optional("foo"s), "bar"s)));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"42 42", bp::int_ >> (bp::string("foo") | bp::int_), bp::ws);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result, (make::tuple(42, std::variant<std::string, int>(42))));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"42", bp::int_ >> -(bp::string("foo") | bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple(42, std::optional<std::string>{})));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"42", bp::int_ >> (-bp::string("foo") | bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result,
|
||||
make::tuple(
|
||||
42,
|
||||
std::variant<std::optional<std::string>, std::string>(
|
||||
std::nullopt)));
|
||||
}
|
||||
|
||||
// P3
|
||||
{
|
||||
auto result = bp::parse("cfoo", bp::char_('c') >> bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, "cfoo"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("cbar", bp::char_('c') >> bp::string("bar"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, "cbar"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("c42", bp::char_('c') >> bp::int_);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple('c', 42)));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("cc", bp::char_('c') >> bp::char_('c'));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, "cc"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("c", bp::char_('c') >> bp::eps);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, 'c');
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("cfoofoo", bp::char_('c') >> *bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple('c', std::vector({"foo"s, "foo"s}))));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("cfoo", bp::char_('c') >> -bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple('c', std::optional("foo"s))));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"cfoo42", bp::char_('c') >> (bp::string("foo") >> bp::int_));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple("cfoo"s, 42)));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"cfoobar",
|
||||
bp::char_('c') >> -(bp::string("foo") >> bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result,
|
||||
(make::tuple('c', std::optional(make::tuple("foo"s, "bar"s)))));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"cfoobar",
|
||||
bp::char_('c') >> (-bp::string("foo") >> bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple('c', std::optional("foo"s), "bar"s)));
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("c42", bp::char_('c') >> (bp::string("foo") | bp::int_));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result, (make::tuple('c', std::variant<std::string, int>(42))));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"c", bp::char_('c') >> -(bp::string("foo") | bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple('c', std::optional<std::string>{})));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"c", bp::char_('c') >> (-bp::string("foo") | bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result,
|
||||
(make::tuple(
|
||||
'c',
|
||||
std::variant<std::optional<std::string>, std::string>(
|
||||
std::nullopt))));
|
||||
}
|
||||
|
||||
// eps
|
||||
{
|
||||
auto result = bp::parse("foo", bp::eps >> bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, "foo"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("bar", bp::eps >> bp::string("bar"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, "bar"s);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("42", bp::eps >> bp::int_);
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, 42);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("c", bp::eps >> bp::char_('c'));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, 'c');
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("", bp::eps >> bp::eps);
|
||||
EXPECT_TRUE(result);
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("foofoo", bp::eps >> *bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, std::vector({"foo"s, "foo"s}));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse("foo", bp::eps >> -bp::string("foo"));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, std::optional("foo"s));
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("foo42", bp::eps >> (bp::string("foo") >> bp::int_));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple("foo"s, 42)));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foobar", bp::eps >> -(bp::string("foo") >> bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, std::optional((make::tuple("foo"s, "bar"s))));
|
||||
}
|
||||
{
|
||||
auto result = bp::parse(
|
||||
"foobar", bp::eps >> (-bp::string("foo") >> bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (make::tuple(std::optional("foo"s), "bar"s)));
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("42", bp::eps >> (bp::string("foo") | bp::int_));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, (std::variant<std::string, int>(42)));
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("", bp::eps >> -(bp::string("foo") | bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(*result, std::optional<std::string>{});
|
||||
}
|
||||
{
|
||||
auto result =
|
||||
bp::parse("", bp::eps >> (-bp::string("foo") | bp::string("bar")));
|
||||
EXPECT_TRUE(result);
|
||||
EXPECT_EQ(
|
||||
*result,
|
||||
(std::variant<std::optional<std::string>, std::string>(
|
||||
std::nullopt)));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user