Boost::spirit::qi parse alternative variant

238 views Asked by At

I need to parse string with parameters A and B. Order of the parameters not defined. I.e. string can be present as one of the next formats

A="value1",B="value2"
B="value1",A="value2"

Part of my code you can see below. But in that code I can parse only A="value1",B="value2" variant. Could I modify this code to parse the first and second variants together? Yes, I can add alternative condition ("|"). But what if I need to parse new C and D parameters.

using Iterator = std::string::const_iterator;
qi::rule<Iterator, std::string()> quotedStringParser;
quotedStringParser %= ('"' >> +(qi::char_ - '"') >> '"');

std::string A;
std::string B;
bool isImport = false;

if (!qi::parse(begin(line), end(line),
    ("A=" >> quotedStringParser[px::ref(A) = qi::_1] >> ',' >> "B=" >> quotedStringParser[px::ref(B) = qi::_1]) >> qi::eoi
)) {
    return false;
}
1

There are 1 answers

3
AudioBubble On

Since you want to be able to extend this to an arbitrary number of parameters, it would be easier to treat this as a comma-delimited list of alternatives, each with a semantic action. This way, you don't have to deal with all possible permutations.

(("A=" >> quotedStringParser[px::ref(A) = qi::_1]) | 
 ("B=" >> quotedStringParser[px::ref(B) = qi::_1]) |
 ("C=" >> quotedStringParser[px::ref(C) = qi::_1]) |
 ("D=" >> quotedStringParser[px::ref(D) = qi::_1]) ) % "," >> qi::eoi

This is, however, a very tolerant parser.

  • It's acceptable to not set all values
  • It's possible to reassign the same value multiple times.

If you want to maintain the same level of strictness you had, it's all stuff that you can validate post-parsing with relative ease.