Bonjour,
J'essaye de réaliser un parser de multiple affectation. Un exemple vaut mieux que mille mots :
Sachant qu'on les contraintes suivantes :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 // affectation "normal" key1 = value1 key2 = value2 // multiple affectation key1, key2 = value1, value2
Vu qu'un parser est récursif j'ai vraiment des difficultés à parser et stocker cette écriture.If there are extra keys, they will be set to an empty value. If there are extra values the last key will be set to the comma-separated list of all remaining values.
Je dois pouvoir la stocker dans
J'ai retourner le problème dans tout les sens pour arriver à la stocker la dedans mais je ne suis pas arriver.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 struct attribute { std::string key; std::string value; }; typedef std::vector<attribute> all_attribute;
Première Question : Comment faire avec Boost.Spirit (ou alors n'hésitez à mettre une pseudo-grammaire en EBNF) ?
Par conséquent, j'ai créé une structure spécifique pour les multi assignement attribute comme ceci :
Comme ça je rempli l'un puis l'autre... Voici mon parser :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 struct multi_attribute { std::vector<std::string> keys; std::vector<std::string> values; };
Ne vous étonnez pas des règles key et value qui ne servent à rien pour le moment, elles me serviront plus tard
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 using qi::lit; using qi::lexeme; using qi::eol; using qi::eoi; using ascii::char_; using ascii::string; using ascii::space; using namespace qi::labels; using phoenix::at_c; using phoenix::push_back; using phoenix::if_; using phoenix::back; using phoenix::size; string_rule = *lit('"') >> lexeme[+(char_("a-zA-Z0-9") | char_('.'))[_val += _1]] >> *lit('"'); key %= string_rule; value %= string_rule; multiattribute = key[push_back(at_c<0>(_val), _1)] % ',' >> '=' >> value[if_(size(at_c<0>(_val)) > size(at_c<1>(_val))) [ push_back(at_c<1>(_val), _1) ] .else_ [ back(at_c<1>(_val)) += ',' + _1 ] ] % ',' >> *eol ;
Et voici mon test case :
En effet, lorsqu'il n'y a qu'une left value et plusieurs right values j'ai une erreur de parsing...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 [multiattributetests] key1, key2 = 1, no // OK key1, key2, key3 = 1, value1 // OK key1, key2 = value1 , value2 , value3 // OK key1 = value1 // OK key1 = 1, 2 , 3 // KO [/multiattributetests]
Je ne comprend absolument pas pourquoi.
Deuxième question : Pourquoi ?
Merci d'avance.
Partager