Reputation: 7677
I have a relatively trivial parser
struct Command {
std::string name;
std::vector<std::string> args;
std::string expected;
};
// Enable Fusion adaptation for Command to work with Boost Spirit X3
BOOST_FUSION_ADAPT_STRUCT(
Command,
name,
args,
expected
)
// helper template to ensure correct type propogation
template <typename T> static auto as = [](auto p) {
return x3::rule<struct tag, T> {"as"} = p;
};
auto parse_command = [](const std::string& line) {
// Define parser rules
//auto commandName_parser = as<std::string>(x3::lexeme[x3::alpha >> *x3::alnum]);
auto commandName_parser = as<std::string>(x3::lexeme[+(x3::alpha | '_') >> *x3::alnum]);
auto arg_parser = as<std::string>(x3::lexeme[+(x3::char_ - ',' - "->" - x3::space)]);
auto args_parser = -(arg_parser % ',');
auto expected_parser = as<std::string>(x3::omit[x3::lit("->")] >> x3::lexeme[+x3::char_]);
// Define full command grammar
auto command_parser = commandName_parser >>
args_parser >>
-expected_parser;
// Create a skipper (optional whitespace skipping)
auto const skipper = x3::space;
Command cmd;
// Parse the input line
auto iter = line.begin();
bool success = x3::phrase_parse(iter, line.end(),
command_parser,
skipper, cmd);
if (success && iter == line.end()) {
fmt::print("'{}' : args[\n", cmd.name);
for (auto&& arg: cmd.args) {
fmt::print("\t- {}\n", arg);
}
fmt ::print("\t],\n");
fmt ::print("\tExpected : {}\n", cmd.expected);
} else {
fmt::print("ERROR: Failed to parse '{}'\n", line);
}
};
This code parses lines such as the following correctly:
SetDBName someName -> Expect 0
DoCommand arg1, arg2, arg3 -> Expect 0
unfortunately when it parses a name with an underscore character, the _
is removed, i.e.
`Pause_ms 400`
is stored as Pausems
how do I fix the commandName_parser
to accurately store the text that was matched?
Upvotes: 0
Views: 81