-
Hi there, is there some way one can create a With I have something like this (not complete code, but should give you the idea), inspired by https://github.com/foonathan/lexy/blob/main/examples/shell.cpp:
I get errors when I try to test this at compile time:
Any suggestions? |
Beta Was this translation helpful? Give feedback.
Replies: 7 comments 1 reply
-
BTW, the "line 119" is this one:
|
Beta Was this translation helpful? Give feedback.
-
Hmm, I think this is not really a problem with using |
Beta Was this translation helpful? Give feedback.
-
As you realized, the issue is with choice. A choice requires a branch rule, but a plain sequence with + is not a branch. You need to specify which part of the sequence is being used as the condition with >>. The condition is the part that is being checked to determine whether the branch should of the choice should be taken, and then is potentially backtracked if it does not match. You probably want to use the keyword as condition: struct cmd_A {
static constexpr auto rule = dsl::keyword<"A">(identifier) >> dsl::p<argument> + dsl::eof;
static constexpr auto value = lexy::construct<CmdA>;
};
struct cmd_B {
static constexpr auto rule = dsl::keyword<"B">(identifier) >> dsl::p<argument> + dsl::eof;
static constexpr auto value = lexy::construct<CmdB>;
}; For more information: https://lexy.foonathan.net/learn/branching/ Edit: removed bogus |
Beta Was this translation helpful? Give feedback.
-
Thanks for the quick answer! However, it's still giving me the same error, even with the Here is the complete code for the example, maybe it's something to do with the namespace test {
namespace dsl = lexy::dsl;
struct CmdA {
std::string_view str;
};
struct CmdB {
std::string_view str;
};
using Command = std::variant<CmdA, CmdB>;
static constexpr auto identifier = dsl::identifier(dsl::ascii::alpha, dsl::ascii::alpha_digit_underscore);
struct argument {
struct invalid {
static constexpr auto name = "invalid argument character";
};
static constexpr auto rule = dsl::identifier(dsl::ascii::word);
static constexpr auto value = lexy::as_string<std::string_view>;
};
struct cmd_A {
static constexpr auto whitespace = dsl::ascii::space;
static constexpr auto rule = dsl::keyword<"A">(identifier) >> dsl::p<argument> +dsl::eof;
static constexpr auto value = lexy::construct<CmdA>;
};
struct cmd_B {
static constexpr auto whitespace = dsl::ascii::space;
static constexpr auto rule = dsl::keyword<"B">(identifier) >> dsl::p<argument> +dsl::eof;
static constexpr auto value = lexy::construct<CmdB>;
};
struct AnyCommand {
struct unknown_command {
static constexpr auto name = "unknown command";
};
static constexpr auto rule = [] {
auto unknown = dsl::error<unknown_command>(identifier);
auto commands = dsl::p<cmd_A> | dsl::p<cmd_B> | unknown;
return commands;
}();
static constexpr auto value = lexy::forward<Command>;
};
} // namespace test Compile errors:
Where line 50 is:
|
Beta Was this translation helpful? Give feedback.
-
I don't know why this is not true, based on what you (and the docs) say about the branch combinator, it should be...? The following assert fails: static_assert(lexy::is_branch_rule([cmd_A::rule](dsl::keyword<"A">(identifier) >> dsl::p<argument> + dsl::eof))); I suspect maybe it's because my |
Beta Was this translation helpful? Give feedback.
-
Aha! It seems to be the struct cmd_A {
//static constexpr auto whitespace = dsl::ascii::space;
static constexpr auto rule = dsl::keyword<"A">(identifier) >> dsl::ascii::space >> dsl::p<argument> + dsl::eof;
static constexpr auto value = lexy::construct<CmdA>;
};
struct cmd_B {
//static constexpr auto whitespace = dsl::ascii::space;
static constexpr auto rule = dsl::keyword<"B">(identifier) >> dsl::ascii::space >> dsl::p<argument> + dsl::eof;
static constexpr auto value = lexy::construct<CmdB>;
}; |
Beta Was this translation helpful? Give feedback.
-
Thanks again, that makes sense (bit by bit...lexy is still pretty new to me!). |
Beta Was this translation helpful? Give feedback.
As you realized, the issue is with choice. A choice requires a branch rule, but a plain sequence with + is not a branch. You need to specify which part of the sequence is being used as the condition with >>. The condition is the part that is being checked to determine whether the branch should of the choice should be taken, and then is potentially backtracked if it does not match. You probably want to use the keyword as condition: