2
0
mirror of https://github.com/boostorg/parser.git synced 2026-01-20 04:42:22 +00:00
Files
parser/test/lexer_and_parser_api.cpp
Zach Laine 19952581f0 Extend support for token parsing to the prefix*parse() API. Add tests for the
full set of *parse() functions that support token parsing; fix errors.

See #202.
2024-12-02 21:46:36 -06:00

185 lines
5.8 KiB
C++

/**
* 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)
*/
#define BOOST_PARSER_TESTING
#include <boost/parser/lexer.hpp>
#include <boost/parser/parser.hpp>
#include <boost/core/lightweight_test.hpp>
namespace bp = boost::parser;
constexpr auto true_false = bp::token_spec<"true|false", 0, bool>;
constexpr auto identifier = bp::token_spec<"[a-zA-Z]\\w*", 1>;
struct tf_tag
{};
struct id_tag
{};
constexpr bp::callback_rule<tf_tag, bool> callback_true_false = "";
constexpr bp::callback_rule<id_tag, std::string_view> callback_identifier = "";
constexpr auto callback_true_false_def = true_false;
constexpr auto callback_identifier_def = identifier;
BOOST_PARSER_DEFINE_RULES(callback_true_false, callback_identifier);
struct callbacks
{
void operator()(id_tag, std::string_view sv) const { sv_ = sv; }
void operator()(tf_tag, bool b) const { b_ = b; }
std::string_view & sv_;
bool & b_;
};
int main()
{
auto assign_bool_parser = identifier >> '=' >> true_false >> ';';
auto assign_bool_no_semi_parser = identifier >> '=' >> true_false;
constexpr auto lexer = bp::lexer<char, int> | true_false | identifier |
bp::token_chars<'=', ';'>;
auto r = "foo = false;" | bp::to_tokens(lexer);
// prefix_parse() w/attr
{
auto f = r.begin();
auto const l = r.end();
std::tuple<std::string_view, bool> result;
auto success = bp::prefix_parse(f, l, assign_bool_parser, result);
BOOST_TEST(success);
BOOST_TEST(std::get<0>(result) == "foo");
BOOST_TEST(std::get<1>(result) == false);
}
{
auto f = r.begin();
auto const l = r.end();
std::tuple<std::string_view, bool> result;
auto success = bp::prefix_parse(f, l, assign_bool_no_semi_parser, result);
BOOST_TEST(success);
BOOST_TEST(std::get<0>(result) == "foo");
BOOST_TEST(std::get<1>(result) == false);
BOOST_TEST(f != l);
}
// parse() w/attr
{
std::tuple<std::string_view, bool> result;
auto success = bp::parse(r, assign_bool_parser, result);
BOOST_TEST(success);
BOOST_TEST(std::get<0>(result) == "foo");
BOOST_TEST(std::get<1>(result) == false);
}
{
constexpr auto lexer = bp::lexer<char8_t, int> | true_false |
identifier | bp::token_chars<'=', ';'>;
auto r8 = u8"foo = false;" | bp::to_tokens(lexer);
std::tuple<std::u8string_view, bool> result;
auto success = bp::parse(r8, assign_bool_parser, result);
BOOST_TEST(success);
BOOST_TEST(std::get<0>(result) == u8"foo");
BOOST_TEST(std::get<1>(result) == false);
}
{
constexpr auto lexer = bp::lexer<char16_t, int> | true_false |
identifier | bp::token_chars<'=', ';'>;
auto r16 = u"foo = false;" | bp::to_tokens(lexer);
std::tuple<std::u16string_view, bool> result;
auto success = bp::parse(r16, assign_bool_parser, result);
BOOST_TEST(success);
BOOST_TEST(std::get<0>(result) == u"foo");
BOOST_TEST(std::get<1>(result) == false);
}
{
constexpr auto lexer = bp::lexer<char32_t, int> | true_false |
identifier | bp::token_chars<'=', ';'>;
auto r32 = U"foo = false;" | bp::to_tokens(lexer);
std::tuple<std::u32string_view, bool> result;
auto success = bp::parse(r32, assign_bool_parser, result);
BOOST_TEST(success);
BOOST_TEST(std::get<0>(result) == U"foo");
BOOST_TEST(std::get<1>(result) == false);
}
// prefix_parse() no attr
{
auto f = r.begin();
auto const l = r.end();
auto result = bp::prefix_parse(f, l, assign_bool_parser);
BOOST_TEST(result);
BOOST_TEST(std::get<0>(*result) == "foo");
BOOST_TEST(std::get<1>(*result) == false);
}
{
auto f = r.begin();
auto const l = r.end();
auto result = bp::prefix_parse(f, l, assign_bool_no_semi_parser);
BOOST_TEST(result);
BOOST_TEST(std::get<0>(*result) == "foo");
BOOST_TEST(std::get<1>(*result) == false);
BOOST_TEST(f != l);
}
// parse() no attr
{
auto result = bp::parse(r, assign_bool_parser);
BOOST_TEST(result);
BOOST_TEST(std::get<0>(*result) == "foo");
BOOST_TEST(std::get<1>(*result) == false);
}
// callback_prefix_parse()
{
auto assign_bool_parser =
callback_identifier >> '=' >> callback_true_false >> ';';
auto f = r.begin();
auto const l = r.end();
std::string_view sv;
bool b = false;
auto success = bp::callback_prefix_parse(
f, l, assign_bool_parser, callbacks{sv, b});
BOOST_TEST(success);
BOOST_TEST(sv == "foo");
BOOST_TEST(b == false);
}
{
auto assign_bool_no_semi_parser =
callback_identifier >> '=' >> callback_true_false;
auto f = r.begin();
auto const l = r.end();
std::string_view sv;
bool b = false;
auto success = bp::callback_prefix_parse(
f, l, assign_bool_no_semi_parser, callbacks{sv, b});
BOOST_TEST(success);
BOOST_TEST(sv == "foo");
BOOST_TEST(b == false);
BOOST_TEST(f != l);
}
// callback_parse()
{
auto assign_bool_parser =
callback_identifier >> '=' >> callback_true_false >> ';';
std::string_view sv;
bool b = false;
auto success =
bp::callback_parse(r, assign_bool_parser, callbacks{sv, b});
BOOST_TEST(success);
BOOST_TEST(sv == "foo");
BOOST_TEST(b == false);
}
return boost::report_errors();
}