Header lexy/dsl/subgrammar.hpp
Rule for parsing a subgrammar, which is a grammar that is defined in a separate file.
Subgrammar definition
lexy/dsl/subgrammar.hpp
#define LEXY_DECLARE_SUBGRAMMAR(Production)
#define LEXY_DEFINE_SUBGRAMMAR(Production)
#define LEXY_INSTANTIATE_SUBGRAMMAR(Production, Action)
Declares and defines a subgrammar by specifying its entry production.
LEXY_DECLARE_SUBGRAMMAR
This is used in the header file where
Production
is an incomplete type.LEXY_DEFINE_SUBGRAMMAR
This is used in the source file where
Production
is defined.LEXY_INSTANTIATE_SUBGRAMMAR
This is used in the source file where
Production
is defined. It instantiates it for the specifiedAction
, which is a one of theXXX_action
types.Action
is a variadic argument, so commas in the template arguments aren’t an issue.
lexy::dsl::subgrammar
can be used in all files that include the header,
and with all parse actions that have been instantiated.
Caution | The macros must be used at global scope. |
Rule lexy::dsl::subgrammar
lexy/dsl/subgrammar.hpp
namespace lexy::dsl
{
template <typename Production, typename T>
constexpr rule auto subgrammar;
}
subgrammar
is a rule that parses the entry production Production
of a subgrammar.
- Requires
LEXY_DECLARE_SUBGRAMMAR(Production)
has been specified in the file.A different source file contains
LEXY_DEFINE_SUBGRAMMAR(Production)
andLEXY_INSTANTIATE_SUBGRAMMAR(Production, Action)
for the action that is also used to parsesubgrammar
.T
is the type of the value produced by usinglexy::parse
on theProduction
. Iflexy::parse
is never used, it can bevoid
.
- Parsing
Parses
Production
as-if it was the top level action. Unlikelexy::dsl::p
, the context is not retained: whitespace rules and parse variables get reset.- Errors
All errors raised by parsing
Production
. The rule then fails if it has failed.- Values
The single value of type
T
produced by parsingProduction
.
//=== grammar.hpp ===//
struct child_production;
LEXY_DECLARE_SUBGRAMMAR(child_production)
//=== grammar.cpp ===//
#include "grammar.hpp"
struct root_production
{
static constexpr auto rule = dsl::subgrammar<child_production, int>;
static constexpr auto value = lexy::forward<int>;
};
//=== grammar_child.cpp ===//
#include "grammar.hpp"
struct child_production
{
static constexpr auto rule = dsl::integer<int>;
static constexpr auto value = lexy::forward<int>;
};
LEXY_DEFINE_SUBGRAMMAR(child_production)
// We want to support matching on a string input without parse state.
LEXY_INSTANTIATE_SUBGRAMMAR(child_production,
lexy::match_action<void, lexy::string_input<>>)
// And we want to support parsing on a buffer using a custom parse state.
LEXY_INSTANTIATE_SUBGRAMMAR(child_production,
lexy::parse_action<my_parse_state, lexy::buffer<>,
std::decay_t<decltype(lexy_ext::report_error)>>)
Note | If you forgot a LEXY_INSTANTIATE_SUBGRAMMAR call or make an error with the type of the action, you will get linker errors. |
Caution | If the subgrammar wants automatic whitespace skipping, it needs to specify a whitespace in the entry production again. |