D
Ich habe mir dafür dann extra Parser geschrieben, die einen entsprechenden
Resulttype hatten. Da kannst du dann auch einfach assign_a auf einen komplexeren Datentyp anwenden (sofern Assignment unterstützt wird).
Zum Beispiel folgende Datenstruktur:
const unsigned int RGB = 0;
const unsigned int GRAY = 1;
struct Color {
unsigned int type;
unsigned char c1, c2, c3;
Color() : type(RGB), c1(0), c2(0), c3(0) { }
Color(unsigned int type, unsigned char c1, unsigned char c2, unsigned char c3) : type(type), c1(c1), c2(c2), c3(c3) { }
};
Dann hatte ich dafür folgenden Parser:
struct ColorParser : public boost::spirit::parser<ColorParser> {
typedef ColorParser self_t;
template<typename ScannerT>
struct result {
typedef typename boost::spirit::match_result<ScannerT, Color>::type type;
};
template <typename ScannerT>
typename boost::spirit::parser_result<self_t, ScannerT>::type
parse(ScannerT const& scan) const {
using namespace boost::spirit;
typedef typename ScannerT::iterator_t Iterator;
typedef typename boost::spirit::parser_result<self_t, ScannerT>::type ResultType;
Color color;
Iterator save = scan.first;
ResultType result = (
(str_p("RGB(")[assign_a(color.type, RGB)]
>> limit_d(0u, 255u)[uint_p[assign_a(color.c1)]] >> ","
>> limit_d(0u, 255u)[uint_p[assign_a(color.c2)]] >> ","
>> limit_d(0u, 255u)[uint_p[assign_a(color.c3)]] >> ")")
|
(str_p("GRAY(")[assign_a(color.type, GRAY)]
>> limit_d(0u, 255u)[uint_p[assign_a(color.c1)]] >> ")")
).parse(scan);
if (result) {
return match<Color>(result.length(), color);
}
scan.first = save;
return scan.no_match();
}
};
const ColorParser color_p = ColorParser();
Einsetzen kann man sowas dann (sinngemäß) wiefolgt:
Color c1, c2;
parse("RGB(255, 0, 0) GRAY(192)", color_p[assign_a(c1)] >> color_p[assign_a(c2)], space_p);
Leider ließen sich die Farbtypen nicht als Enums festlegen, assign_a hat dann immer irgendwelche unsinnigen Werte zugewiesen.