Here is my look at him
I believe that a rule that would be a blocker for you would be
figure = eps >> "figure" >> name [ at_c<0>(_val) = _1 ] >> '{' >> *( ipoints [ push_back(at_c<1>(_val), _1) ] | fpoints [ push_back(at_c<2>(_val), _1) ] ) >> '}';
This is actually a symptom of you parsing the mixed strings i and f into separate containers.
Below is an alternative.
Here is my full code: test.cpp
//#define BOOST_SPIRIT_DEBUG // before including Spirit #define BOOST_SPIRIT_USE_PHOENIX_V3 #include <boost/fusion/adapted.hpp> #include <boost/spirit/include/qi.hpp>
It displays the analyzed data as a check: output.txt
Parse success # figure sets exported automatically by karma set "Myset A" { figure "AF 1" { i 0 0 0 i 1 2 5 i 1 1 1 i 3 1 5 f 3.1 45.11 5.3 f 1.1 2.33 5.166 } figure "AF 2" { i 25 5 1 i 3 1 3 } } set "Myset B" { figure "BF 1" { f 23.1 4.3 5.11 } } set "Myset C" { include "Myset A" figure "CF" { i 1 1 1 f 3.11 5.33 3.0 } }
You will notice that
- the order of the dotted lines changes (all
int_points precede all float_points ) - minor numbers are also added, for example. in the last line of
3.0 instead of 3 , to show that the type is if float. - you "forgot" (?) to include in your question
Alternative
There is something that keeps the actual dotted strings in the original order:
typedef boost::variant<int_point, float_point> if_point; struct figure { std::string name; std::vector<if_point> if_points; }
Now the rules are simple:
name = eps >> lexeme [ '"' >> *~char_('"') >> '"' ]; include = eps >> "include" >> name; ipoints = eps >> "i" >> int_ >> int_ >> int_; fpoints = eps >> "f" >> float_ >> float_ >> float_; figure = eps >> "figure" >> name >> '{' >> *(ipoints | fpoints) >> '}'; set = eps >> "set" >> name >> '{' >> *include >> *figure >> '}'; start = *set;
Pay attention to elegance in
figure = eps >> "figure" >> name >> '{' >> *(ipoints | fpoints) >> '}';
And the output remains in the exact order of input: output.txt
Once again, the full demo code (github only): test.cpp
Bonus Update
Finally, I made my first correct Karma grammar to output the results:
name = no_delimit ['"' << string << '"']; include = "include" << name; ipoints = "\ni" << int_ << int_ << int_; fpoints = "\nf" << float_ << float_ << float_; figure = "figure" << name << "\n {" << *(ipoints | fpoints) << "\n }"; set = "set" << name << "\n{" << *("\n " << include) << *("\n " << figure) << "\n}"; start = "# figure sets exported automatically by karma\n\n" << set % eol;
It was significantly more convenient than I expected. Check it out in the latest version of the fully updated gist : test.hpp