Repository navigation
How are you supposed to use the tnode/pnode rules on delimeter rule productions? #268
|
Messing around with pnodes and tnodes, I found a case where the tree will fail: // A simple grammar for a single key-value pair.
namespace grammar
{
struct key : lexy::token_production
{
static constexpr auto rule = dsl::quoted(-dsl::unicode::control);
};
struct integer
{
static constexpr auto rule = dsl::digits<>;
};
struct key_value_pair
{
static constexpr auto whitespace = dsl::ascii::space;
static constexpr auto rule = dsl::p<key> + dsl::lit_c<'='> + dsl::p<integer>;
};
} // namespace grammar
namespace tree_grammar
{
struct id {
static constexpr auto rule = dsl::tnode<lexy::any_token_kind>(dsl::capture(-dsl::quoted.open()));
static constexpr auto value = lexy::as_string<std::string>;
};
struct integer
{
// Match the digits token and extract their integer value.
static constexpr auto rule = dsl::tnode<lexy::digits_token_kind>(dsl::integer<int>);
static constexpr auto value = lexy::as_integer<int>;
};
struct key_value_pair
{
// Skip over literal and whitespace tokens automatically.
static constexpr auto whitespace
= dsl::tnode<lexy::literal_token_kind> | dsl::tnode<lexy::whitespace_token_kind>;
// Skip the key production but parse the children of the integer production.
static constexpr auto rule = [] {
auto key = dsl::pnode<grammar::key>(dsl::p<id>);
auto value = dsl::pnode<grammar::integer>;
return key + value;
}();
static constexpr auto value = lexy::forward<std::string>;
};
} // namespace tree_grammarThis will parse |
Replies: 1 comment
|
Not a bug, it's two things in struct id {
static constexpr auto rule = dsl::opt(dsl::tnode<lexy::unknown_token_kind>(dsl::capture(dsl::any)));
static constexpr auto value = lexy::as_string<std::string>;
};
|
Not a bug, it's two things in
id. The characters between the quotes become one merged token node whose kind comes from the char class you gavequoted, and-dsl::unicode::controlhas none, so thatslexy::unknown_token_kind(tokeninlexy::visualize), notany_token_kind. The rule insidetnodethen has to consume that token's whole lexeme (value, no quotes), but your char class only eats one charachter. This works on v2025.05.0:"value" = 123givesvalue. Theoptcovers"", which has no content node at all. If …