4

I'm trying to parse an object where the order of the attributes should not matter.

For example, parsing employee

employee { surname = "doe", firstname = "john", age = 30 }

should be the same as

employee { age = 30, firstname = "john", surname = "doe"}

So ideally my rule should be something like (don't mind the lack of formal definition)

unordered_rule %= lit("employee") >> "{" 
             >> kwd("surname")["=" > quoted_string] 
            / kwd("age")["=" > int_] 
            / kwd("firstname")["=" > quoted_string] 
            / kwd("age")["=" > int] >> "}"; 

But firstly, how do I incorporate the separating commas into the parsing rule? And for my C++ struct struct employee { std::string firstname; ... int age; }, does the order of the attributes matter or how does boost know which keyword corresponds to which attribute even after the struct has been converted to a fusion vector?

This doesn't really add up for me even after reading the documentation on keyword list operators.

Jon Gan
  • 867
  • 1
  • 11
  • 22

1 Answers1

1

Fusion sequences are ordered only. So the order in which the attributes are synthesized must match the order in which the fields have been adapted to the fusion sequence.

I know no elegant way to incorporate the delimiters (I think someone should extend the keyword list parser directive for that... Feel free :)).

You could use a mix of skipping e.g. (qi::space | ',') and qi::lexeme[] around the relevant items (see Boost spirit skipper issues).

Or you can use a lookahead-asserted repeating expression like

unordered_rule %= lit("employee") >> "{" 
        >> (kwd("surname")  >> (&lit('}') | ',')) [ "=" > quoted_string ]
        / kwd("age")       >> (&lit('}') | ',')) [ "=" > int_ ]
        / kwd("firstname") >> (&lit('}') | ',')) [ "=" > quoted_string ]
        / kwd("age")       >> (&lit('}') | ',')) [ "=" > int ]
        >> "}";

(not tested for now).

Community
  • 1
  • 1
sehe
  • 374,641
  • 47
  • 450
  • 633
  • So is it still possible to use parse a unordered text like my example into a fusion sequence? Or must I do it some other way? – Jon Gan Apr 28 '15 at 20:01
  • Huh. I don't think i mentioned any limitations. I just answered your question and showed a way to get the delimiters parsing. – sehe Apr 28 '15 at 20:06