
"ParmName: ParmValue" I'm looking for certain ParmNames, and I have to grab the associated ParmValue.
[Nat] Maybe the Spirit parser is the wrong place to get specific about the ParmNames you're seeking? Maybe what you should do is parse *every* item of that form, stuffing the pairs into a std::map. Then you can extract from that map the specific items you want.
Nat, thanks for the reply. In the course of writing a reply to you explaining what I'm really trying to do, I had an "aha" head-slapping moment. You know how it is... sometimes, just trying to explain a problem is enough to generate the answer. In reply to your quoted text above, yes, I should not be specific about which ParmNames I'm seeking at this level. I was actually using a map; I had just removed that from my example to make it a bit easier to understand. There is a bigger problem that the files I'm looking at may have mismatched single quotes in the parts of the file I don't care about. Like this random-text " random-text random-text In other words, to a parser looking for quoted text, these single quotes would appear as damaged, and the parser would still halt like it does now. The only thing I can be sure of is that "ParmName: ParmValue" will be properly quoted and non-damaged and consistent within itself. So it turns out my basic comprehension problem here is similar to one I had actually gone through when I was first learning pattern matching and regular expressions under Perl. I went and dug up some old Perl code of mine that did a similar search to see how I did it back then. My basic problem is thinking that the parser would continue grinding through non-matches just by putting a kleene-star on the front of it. Once I took this into account, a new strategy emerged. First, search for a single quote. Then try and see if there is a match at that point. If a match, move to just beyond the match, else just move to the next character. Repeat. The code is not as simple as my previous non-working version, since now I have to use iterators. This example also looks for multiple types of ParmNames. It comes out looking like the code below. I love that you can load up a complex map assignment right in the middle of the rule. map<string,string> smap; string key; typedef string::const_iterator iterator_t; typedef scanner<iterator_t> scanner_t; typedef rule<scanner_t> rule_t; typedef parse_info<iterator_t> parse_info_t; rule_t quote = ch_p('"'); rule_t colon = ch_p(':'); rule_t eat_all_non_quotes = *~ch_p('"'); rule_t parm_names = str_p(DWARF_DEVICE_NAME) | DWARF_DEVICE_TYPE | DWARF_DEVICE_SOFTWARE_VERSION | DWARF_DEVICE_COMMENTS; rule_t parm_string = quote >> parm_names[assign_a(key)] >> colon >> *blank_p >> eat_all_non_quotes[insert_at_a(smap, key)] >> quote; string str = "\"broken\" (text \"DeviceName: Altera in Controller\" (blah))"; iterator_t first = str.begin(); iterator_t last = str.end(); parse_info_t pi; while (first != last) { // skip to first quote character pi = parse(first, last, eat_all_non_quotes); first = pi.stop; // make sure we haven't gone past the end if (first != last) { // eat up any matching parms here pi = parse(first, last, parm_string); if (pi.hit) first = pi.stop; else first++; } } Thanks for the help, -todd-