mark
mark

Reputation: 7677

Boost::Spirit::X3 disacrding underscore characters

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

Answers (0)

Related Questions