flags.hpp
Go to the documentation of this file.
1 // Copyright (C) 2020-2024 Jonathan Müller and lexy contributors
2 // SPDX-License-Identifier: BSL-1.0
3 
4 #ifndef LEXY_DSL_FLAGS_HPP_INCLUDED
5 #define LEXY_DSL_FLAGS_HPP_INCLUDED
6 
7 #include <lexy/dsl/base.hpp>
8 #include <lexy/error.hpp>
9 
10 namespace lexy
11 {
13 {
14  static LEXY_CONSTEVAL auto name()
15  {
16  return "duplicate flag";
17  }
18 };
19 } // namespace lexy
20 
21 namespace lexyd
22 {
23 template <const auto& Table, typename Token, typename Tag>
24 struct _sym;
25 
26 template <typename FlagRule, auto Default, typename DuplicateError = void>
27 struct _flags : rule_base
28 {
29  using _enum_type = LEXY_DECAY_DECLTYPE(Default);
30  using _int_type = std::underlying_type_t<_enum_type>;
31 
32  template <typename NextParser>
33  struct p
34  {
35  template <typename Context, typename Reader>
36  static constexpr bool _parse(_int_type& result, Context& context, Reader& reader)
37  {
38  result = _int_type(Default);
39 
40  while (true)
41  {
42  auto begin = reader.position();
43 
45  if (!bp.try_parse(context.control_block, reader))
46  {
47  bp.cancel(context);
48  break;
49  }
50 
51  if (!bp.template finish<lexy::pattern_parser<_enum_type>>(context, reader))
52  return false;
53 
54  auto flag = _int_type(bp.value());
55  if ((result & flag) == flag)
56  {
58  auto err = lexy::error<Reader, tag>(begin, reader.position());
59  context.on(_ev::error{}, err);
60  // We can trivially recover.
61  }
62  result |= flag;
63  }
64 
65  return true;
66  }
67 
68  template <typename Context, typename Reader, typename... Args>
69  LEXY_PARSER_FUNC static bool parse(Context& context, Reader& reader, Args&&... args)
70  {
71  _int_type result{};
72  if (!_parse(result, context, reader))
73  return false;
74  return NextParser::parse(context, reader, LEXY_FWD(args)..., _enum_type(result));
75  }
76  };
77 
78  template <typename Tag>
79  static constexpr _flags<FlagRule, Default, Tag> error = {};
80 };
81 
82 template <auto Default, const auto& Table, typename Token, typename Tag>
83 constexpr auto flags(_sym<Table, Token, Tag> flag_rule)
84 {
85  using table_type = LEXY_DECAY_DECLTYPE(Table);
86  using enum_type = LEXY_DECAY_DECLTYPE(Default);
87  static_assert(std::is_same_v<enum_type, typename table_type::mapped_type>);
88  static_assert(std::is_enum_v<enum_type>);
89 
90  return _flags<decltype(flag_rule), Default>{};
91 }
92 template <const auto& Table, typename Token, typename Tag>
93 constexpr auto flags(_sym<Table, Token, Tag> flag_rule)
94 {
95  using table_type = LEXY_DECAY_DECLTYPE(Table);
96  using enum_type = typename table_type::mapped_type;
97  static_assert(std::is_enum_v<enum_type>);
98 
99  return _flags<decltype(flag_rule), enum_type{}>{};
100 }
101 } // namespace lexyd
102 
103 namespace lexyd
104 {
105 template <typename Rule, auto If, auto Else>
106 struct _flag : rule_base
107 {
108  template <typename NextParser>
109  struct p
110  {
111  template <typename Context, typename Reader, typename... Args>
112  LEXY_PARSER_FUNC static bool parse(Context& context, Reader& reader, Args&&... args)
113  {
115  if (branch.try_parse(context.control_block, reader))
116  return branch.template finish<NextParser>(context, reader, LEXY_FWD(args)..., If);
117  else
118  {
119  branch.cancel(context);
120  return NextParser::parse(context, reader, LEXY_FWD(args)..., Else);
121  }
122  }
123  };
124 };
125 
126 template <auto If, auto Else = LEXY_DECAY_DECLTYPE(If){}, typename Rule>
127 constexpr auto flag(Rule)
128 {
129  LEXY_REQUIRE_BRANCH_RULE(Rule, "flag()");
130  return _flag<Rule, If, Else>{};
131 }
132 
133 template <typename Rule>
134 constexpr auto flag(Rule rule)
135 {
136  return flag<true, false>(rule);
137 }
138 } // namespace lexyd
139 
140 #endif // LEXY_DSL_FLAGS_HPP_INCLUDED
141 
LEXY_CONSTEVAL
#define LEXY_CONSTEVAL
Definition: config.hpp:98
lexyd::_sym
Definition: flags.hpp:24
lexyd::_flag::p::parse
static LEXY_PARSER_FUNC bool parse(Context &context, Reader &reader, Args &&... args)
Definition: flags.hpp:112
lexyd::_flags::_int_type
std::underlying_type_t< _enum_type > _int_type
Definition: flags.hpp:30
lexy::branch_parser_for
typename BranchRule::template bp< Reader > branch_parser_for
Definition: dsl/base.hpp:116
lexyd::_flags::p
Definition: flags.hpp:33
LEXY_FWD
#define LEXY_FWD(...)
Definition: config.hpp:30
lexy::_detail::type_or
std::conditional_t< std::is_void_v< T >, Fallback, T > type_or
Definition: config.hpp:64
lexy::duplicate_flag::name
static LEXY_CONSTEVAL auto name()
Definition: flags.hpp:14
lexy
Definition: any_ref.hpp:12
lexyd::_flag::p
Definition: flags.hpp:109
lexyd::_flag
Definition: flags.hpp:106
LEXY_REQUIRE_BRANCH_RULE
#define LEXY_REQUIRE_BRANCH_RULE(Rule, Name)
Definition: grammar.hpp:73
lexyd::_flags::error
static constexpr _flags< FlagRule, Default, Tag > error
Definition: flags.hpp:79
lexy::error
Generic failure.
Definition: error.hpp:14
lexy::parse
constexpr auto parse(const Input &input, const ErrorCallback &callback)
Parses the production into a value, invoking the callback on error.
Definition: parse.hpp:171
lexy::parse_events::error
Definition: dsl/base.hpp:68
lexyd::_flags::p::parse
static LEXY_PARSER_FUNC bool parse(Context &context, Reader &reader, Args &&... args)
Definition: flags.hpp:69
LEXY_DECAY_DECLTYPE
#define LEXY_DECAY_DECLTYPE(...)
Definition: config.hpp:34
lexy::duplicate_flag
Definition: flags.hpp:12
lexyd::rule_base
Definition: grammar.hpp:17
LEXY_PARSER_FUNC
#define LEXY_PARSER_FUNC
Definition: dsl/base.hpp:108
cx::begin
constexpr auto begin(const C &c) -> decltype(c.begin())
Definition: wildcards.hpp:661
base.hpp
lexy::pattern_parser
A parser that does not support any arguments.
Definition: dsl/base.hpp:172
lexyd::_flags::p::_parse
static constexpr bool _parse(_int_type &result, Context &context, Reader &reader)
Definition: flags.hpp:36
lexyd::flags
constexpr auto flags(_sym< Table, Token, Tag > flag_rule)
Definition: flags.hpp:83
lexyd::_flags::_enum_type
LEXY_DECAY_DECLTYPE(Default) _enum_type
Definition: flags.hpp:29
lexyd
Definition: trace.hpp:22
lexyd::flag
constexpr auto flag(Rule)
Definition: flags.hpp:127
lexyd::_flags
Definition: flags.hpp:27
error.hpp


behaviortree_cpp_v4
Author(s): Davide Faconti
autogenerated on Wed Apr 16 2025 02:20:55