PhoenixToml  1.4.0
Toml parser for Phoenix
Loading...
Searching...
No Matches
parser_toml.cpp
Go to the documentation of this file.
1/***************************************
2 Auteur : Pierre Aubert
3 Mail : pierre.aubert@lapp.in2p3.fr
4 Licence : CeCILL-C
5****************************************/
6
7#include "parse_generic_string.h"
8#include "parser_toml.h"
9
13 PFileParser parser;
15 bool isRun;
16};
17
19
22 PTomlParserData data;
23 data.isRun = true;
24 return data;
25}
26
27bool parse_toml_var(DicoValue & dico, PTomlParserData & data);
28bool parse_toml_all(DicoValue & parent, PTomlParserData & data);
29
31
34 data.isRun = false;
35}
36
38
41 return data.isRun;
42}
43
45
49bool parse_toml_varName(PString & varName, PFileParser & parser){
50 varName = parser.getStrComposedOf("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_");
51 return varName != "";
52}
53
55
59bool parse_tomlCompactDico(DicoValue & parent, PTomlParserData & data){
60 PFileParser & parser = data.parser;
61 if(!parser.isMatch("{")){return false;}
62 while(!parser.isEndOfFile() && parse_toml_isParse(data) && !parser.isMatch("}")){ //Let's parse the vatiables of the Dico
63 if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
64 else if(parse_toml_var(parent, data)){
65 if(!parser.isMatch(",") && !parser.isMatchRewind("}")){ //We expect one element or a comma to add more
66 std::cerr << "parse_tomlCompactDico : expect ',' or '}' for unclosed dictionary of values at " << parser.getLocation() << std::endl;
68 return false;
69 }
70 }else{
71 if(!parser.isMatch("}")){
72 std::cerr << "parse_tomlCompactDico : missing '}' token to close empty dictionary of value at " << parser.getLocation() << std::endl;
74 return false;
75 }
76 }
77 }
78 return true;
79}
80
82
86bool parse_toml_varValue(DicoValue & var, PTomlParserData & data){
87 PFileParser & parser = data.parser;
88 if(parser.isMatch("[")){ //The value is a list
89 while(!parser.isEndOfFile() && !parser.isMatch("]") && parse_toml_isParse(data)){ //Let's parse the values of the Variable
90 DicoValue subValue;
91 if(parse_tomlCompactDico(subValue, data)){
92 var.getVecChild().push_back(subValue);
93 }
94 else if(parse_toml_varValue(subValue, data)){
95 var.getVecChild().push_back(subValue);
96 }
97 else{
98 if(!parser.isMatch("]")){
99 std::cerr << "parse_toml_varBase : missing ']' token to close empty list of value at " << parser.getLocation() << std::endl;
101 return false;
102 }
103 }
104
105 if(!parser.isMatch(",") && !parser.isMatchRewind("]")){ //We expect one element or a comma to add more
106 std::cerr << "parse_toml_varValue : expect ',' or ']' forunclosed list of values at " << parser.getLocation() << std::endl;
108 return false;
109 }
110 }
111 }else{
112 PString strValue("");
113 if(parse_generic_string(strValue, parser)){
114 var.setValue(strValue);
115 }else if(parser.isMatch("true")){
116 var.setValue("true");
117 }else if(parser.isMatch("false")){
118 var.setValue("false");
119 }else{
120 PString valueNumber(parser.getStrComposedOf("0123456789.-+e"));
121 if(valueNumber != ""){
122 var.setValue(valueNumber);
123 }else{
124 std::cerr << "parse_toml_varValue : missing value of variable '"<<var.getKey()<<"' at " << parser.getLocation() << std::endl;
126 return false;
127 }
128 }
129 }
130 return true;
131}
132
134
138bool parse_toml_varBase(DicoValue & var, PTomlParserData & data){
139 PFileParser & parser = data.parser;
140 PString varName("");
141 if(!parse_toml_varName(varName, parser)){return false;}
142 if(!parser.isMatch("=")){
143 std::cerr << "parse_toml_varBase : missing '=' token to define value of variable '"<<varName<<"' at " << parser.getLocation() << std::endl;
145 return false;
146 }
147 var.setKey(varName);
148 bool b(true);
149 if(parse_tomlCompactDico(var, data)){}
150 else if(parse_toml_varValue(var, data)){}
151 else{b = false;}
152 return b;
153}
154
156
160bool parse_toml_var(DicoValue & dico, PTomlParserData & data){
161 DicoValue var;
162 if(!parse_toml_varBase(var, data)){return false;}
163 dico.getMapChild()[var.getKey()] = var;
164 return true;
165}
166
168
172bool parse_toml_varTable(DicoValue & dico, PTomlParserData & data){
173 DicoValue var;
174 if(!parse_toml_varBase(var, data)){return false;}
175 dico.getVecChild().push_back(var);
176 return true;
177}
178
180
184DicoValue * parse_get_parent_dico(DicoValue & parent, const PVecString & vecDicoName){
185 DicoValue * output = &parent;
186 for(PVecString::const_iterator it(vecDicoName.begin()); it != vecDicoName.end(); ++it){
187 output = &(output->getMapChild()[*it]);
188 output->setKey(*it);
189 }
190 return output;
191}
192
194
198bool parse_toml_dico_def(DicoValue & parent, PTomlParserData & data){
199 PFileParser & parser = data.parser;
200 if(!parser.isMatch("[")){return false;}
201 PString dicoName(parser.getUntilKeyWithoutPatern("]"));
202 PVecString vecDicoName = dicoName.split('.');
203 DicoValue * dicoDef = parse_get_parent_dico(parent, vecDicoName);
204
205// dicoDef.setKey(dicoName);
206 while(!parser.isEndOfFile() && parse_toml_isParse(data) && !parser.isMatchRewind("[")){ //Let's parse the vatiables of the Dico
207 if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
208 else if(parse_toml_var(*dicoDef, data)){
209// parent.getMapChild()[dicoName] = *dicoDef;
210 }
211// else{
212// std::cerr << "parse_toml_dico_def : error at " << parser.getLocation() << std::endl;
213// std::cerr << "\tcannot parse [definition]" << std::endl;
214// parse_toml_stopParsing(data);
215// return true;
216// }
217 }
218 return true;
219}
220
222
226bool parse_toml_table_def(DicoValue & parent, PTomlParserData & data){
227 PFileParser & parser = data.parser;
228 if(!parser.isMatch("[[")){return false;}
229 PString dicoName(parser.getUntilKeyWithoutPatern("]]"));
230 PVecString vecDicoName = dicoName.split('.');
231 DicoValue * dicoDef = parse_get_parent_dico(parent, vecDicoName);
232// DicoValue dicoDef;
233// dicoDef.setKey(dicoName);
234 DicoValue table;
235 while(!parser.isEndOfFile() && parse_toml_isParse(data) && !parser.isMatchRewind("[")){ //Let's parse the vatiables of the Dico
236 if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
237 else if(parse_toml_var(table, data)){
238// parent.getMapChild()[dicoName] = *dicoDef;
239 }
240// else{
241// std::cerr << "parse_toml_table_def : error at " << parser.getLocation() << std::endl;
242// std::cerr << "\tcannot parse [[table_definition]]" << std::endl;
243// parse_toml_stopParsing(data);
244// return true;
245// }
246 }
247 dicoDef->getVecChild().push_back(table);
248 return true;
249}
250
252
256bool parser_toml_fileParser(DicoValue & dico, PTomlParserData & data){
257 PFileParser & parser = data.parser;
258 parser.getStrComposedOf(" \t\n"); //Skip all blank characters
259 while(!parser.isEndOfFile() && parse_toml_isParse(data)){
260 if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
261 else if(parse_toml_table_def(dico, data)){}
262 else if(parse_toml_dico_def(dico, data)){}
263 else{
264 PString nextToken(parser.getNextToken());
265 if(nextToken.size() != 0lu){ //If the token is empty, we are at the end of the file
266 std::cerr << "parser_toml_fileParser : error at " << parser.getLocation() << std::endl;
267 std::cerr << "\tunexpected token '"<<nextToken<<"'" << std::endl;
269 }
270 }
271 }
272 return data.isRun;
273}
274
276
280bool parser_toml(DicoValue & dico, const PPath & fileName){
282 PFileParser & parser = data.parser;
283 parser.setWhiteSpace(" \n\t");
284 parser.setSeparator(":-'\",{}[]>|");
285 parser.setEscapeChar('\\');
286 if(!parser.open(fileName)){
287 std::cerr << "parser_toml : cannot open file '"<<fileName<<"'" << std::endl;
288 return false;
289 }
290 bool b(parser_toml_fileParser(dico, data));
291 return b;
292}
293
294bool parse_toml_var(ConfigNode & parent, PTomlParserData & data);
295
297
301bool parse_tomlCompactDico(ConfigNode & parent, PTomlParserData & data){
302 PFileParser & parser = data.parser;
303 if(!parser.isMatch("{")){return false;}
304 while(!parser.isEndOfFile() && parse_toml_isParse(data) && !parser.isMatch("}")){ //Let's parse the vatiables of the Dico
305 if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
306 else if(parse_toml_var(parent, data)){
307 if(!parser.isMatch(",") && !parser.isMatchRewind("}")){ //We expect one element or a comma to add more
308 std::cerr << "parse_tomlCompactDico : expect ',' or '}' for unclosed dictionary of values at " << parser.getLocation() << std::endl;
310 return false;
311 }
312 }else{
313 if(!parser.isMatch("}")){
314 std::cerr << "parse_tomlCompactDico : missing '}' token to close empty dictionary of value at " << parser.getLocation() << std::endl;
316 return false;
317 }
318 }
319 }
320 return true;
321}
322
324
328bool parse_toml_varValue(ConfigNode & var, PTomlParserData & data){
329 PFileParser & parser = data.parser;
330 if(parser.isMatch("[")){ //The value is a list
331 while(!parser.isEndOfFile() && !parser.isMatch("]") && parse_toml_isParse(data)){ //Let's parse the values of the Variable
332 if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
333 else{
334 ConfigNode * subValue = var.addChild();
335 if(parse_tomlCompactDico(*subValue, data)){
336 if(!parser.isMatch(",") && !parser.isMatchRewind("]")){ //We expect one element or a comma to add more
337 std::cerr << "parse_toml_varValue : expect ',' or ']' for unclosed list of values at " << parser.getLocation() << std::endl;
339 return false;
340 }
341 }else if(parse_toml_varValue(*subValue, data)){
342 if(!parser.isMatch(",") && !parser.isMatchRewind("]")){ //We expect one element or a comma to add more
343 std::cerr << "parse_toml_varValue : expect ',' or ']' for unclosed list of values at " << parser.getLocation() << std::endl;
345 return false;
346 }
347 }else{
348 if(!parser.isMatch("]")){
349 std::cerr << "parse_toml_varValue : missing ']' token to close empty list of value at " << parser.getLocation() << std::endl;
351 return false;
352 }
353 }
354 }
355 }
356 }else{
357 PString strValue("");
358 if(parse_generic_string(strValue, parser)){
359 var.setValue(strValue);
360 }else if(parser.isMatch("true")){
361 var.setValue("true");
362 }else if(parser.isMatch("false")){
363 var.setValue("false");
364 }else{
365 PString valueNumber(parser.getStrComposedOf("0123456789.-+e"));
366 if(valueNumber != ""){
367 var.setValue(valueNumber);
368 }else{
369 std::cerr << "parse_toml_varValue : missing value of variable '"<<var.getName()<<"' at " << parser.getLocation() << std::endl;
371 return false;
372 }
373 }
374 }
375 return true;
376}
377
379
383bool parse_toml_var(ConfigNode & parent, PTomlParserData & data){
384 PFileParser & parser = data.parser;
385 PString varName("");
386 if(!parse_toml_varName(varName, parser)){return false;}
387 if(!parser.isMatch("=")){
388 std::cerr << "parse_toml_var : missing '=' token to define value of variable '"<<varName<<"' at " << parser.getLocation() << std::endl;
390 return false;
391 }
392 ConfigNode * var = parent.addChild(varName);
393 var->setLineCol(parser.getLocation());
394 bool b(true);
395 if(parse_tomlCompactDico(*var, data)){}
396 else if(parse_toml_varValue(*var, data)){}
397 else{b = false;}
398 return b;
399}
400
402
406ConfigNode * parse_get_parent_dico(ConfigNode & parent, const PVecString & vecDicoName){
407 ConfigNode * output = &parent;
408 for(PVecString::const_iterator it(vecDicoName.begin()); it != vecDicoName.end(); ++it){
409 ConfigNode * next = output->getChild(it->eraseFirstLastChar("\"'"));
410 if(next == NULL){
411 next = output->addChild(*it);
412 }
413 output = next;
414 output->setName(*it);
415 }
416 return output;
417}
418
420
424bool parse_toml_dico_def(ConfigNode & parent, PTomlParserData & data){
425 PFileParser & parser = data.parser;
426 if(!parser.isMatch("[")){return false;}
427 PString dicoName(parser.getUntilKeyWithoutPatern("]"));
428 PVecString vecDicoName = dicoName.split('.');
429 ConfigNode * dicoDef = parse_get_parent_dico(parent, vecDicoName);
430 dicoDef->setLineCol(parser.getLocation());
431 while(!parser.isEndOfFile() && parse_toml_isParse(data) && !parser.isMatchRewind("[")){ //Let's parse the vatiables of the Dico
432 if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
433 else if(parse_toml_var(*dicoDef, data)){}
434 }
435 return true;
436}
437
439
443bool parse_toml_table_def(ConfigNode & parent, PTomlParserData & data){
444 PFileParser & parser = data.parser;
445 if(!parser.isMatch("[[")){return false;}
446 PString dicoName(parser.getUntilKeyWithoutPatern("]]"));
447 PVecString vecDicoName = dicoName.split('.');
448 ConfigNode * dicoDef = parse_get_parent_dico(parent, vecDicoName);
449 dicoDef->setLineCol(parser.getLocation());
450 ConfigNode * table = dicoDef->addChild();
451 table->setLineCol(parser.getLocation());
452 while(!parser.isEndOfFile() && parse_toml_isParse(data) && !parser.isMatchRewind("[")){ //Let's parse the vatiables of the Dico
453 if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
454 else if(parse_toml_var(*table, data)){}
455 }
456 return true;
457}
458
460
464bool parser_toml_fileParser(ConfigNode & node, PTomlParserData & data){
465 PFileParser & parser = data.parser;
466 parser.getStrComposedOf(" \t\n"); //Skip all blank characters
467 while(!parser.isEndOfFile() && parse_toml_isParse(data)){
468 if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
469 else if(parse_toml_table_def(node, data)){}
470 else if(parse_toml_dico_def(node, data)){}
471 else if(parse_toml_var(node, data)){}
472 else{
473 PString nextToken(parser.getNextToken());
474 if(nextToken.size() != 0lu){ //If the token is empty, we are at the end of the file
475 std::cerr << "parser_toml_fileParser : error at " << parser.getLocation() << std::endl;
476 std::cerr << "\tunexpected token '"<<nextToken<<"'" << std::endl;
478 }
479 }
480 }
481 return data.isRun;
482}
483
485
489bool parser_toml(ConfigNode & node, const PPath & fileName){
491 PFileParser & parser = data.parser;
492 parser.setWhiteSpace(" \n\t");
493 parser.setSeparator(":-'\",{}[]>|");
494 parser.setEscapeChar('\\');
495 if(!parser.open(fileName)){
496 std::cerr << "parser_toml : cannot open file '"<<fileName<<"'" << std::endl;
497 return false;
498 }
499 node.setFileName(fileName);
500 bool b(parser_toml_fileParser(node, data));
501 return b;
502}
503
505
509bool parser_tomlString(ConfigNode & node, const PString & fileContent){
511 PFileParser & parser = data.parser;
512 parser.setWhiteSpace(" \n\t");
513 parser.setSeparator(":-'\",{}[]>|");
514 parser.setEscapeChar('\\');
515 parser.setFileContent(fileContent);
516 bool b(parser_toml_fileParser(node, data));
517 return b;
518}
519
520
521
522
void parse_toml_stopParsing(PTomlParserData &data)
Stop the file parsing.
DicoValue * parse_get_parent_dico(DicoValue &parent, const PVecString &vecDicoName)
Get the parent dictionary by respect to the vecDicoName.
bool parse_toml_all(DicoValue &parent, PTomlParserData &data)
bool parser_toml_fileParser(DicoValue &dico, PTomlParserData &data)
Parse a yml file and update the given VecValue.
bool parse_toml_isParse(const PTomlParserData &data)
Say if the file parsing is enable.
bool parse_tomlCompactDico(DicoValue &parent, PTomlParserData &data)
Parse a compact dico definition.
bool parse_toml_varName(PString &varName, PFileParser &parser)
Parse a toml var name.
bool parse_toml_dico_def(DicoValue &parent, PTomlParserData &data)
Parse a dico definition.
PTomlParserData default_PTomlParserData()
Default value of PTomlParserData.
bool parser_toml(DicoValue &dico, const PPath &fileName)
Parse a toml file and update the given DicoValue.
bool parse_toml_varBase(DicoValue &var, PTomlParserData &data)
Parse a toml var name.
bool parse_toml_var(DicoValue &dico, PTomlParserData &data)
Parse a toml var name.
bool parse_toml_varTable(DicoValue &dico, PTomlParserData &data)
Parse a toml var name.
bool parser_tomlString(ConfigNode &node, const PString &fileContent)
Parse a toml string.
bool parse_toml_varValue(DicoValue &var, PTomlParserData &data)
Parse a toml var name.
bool parse_toml_table_def(DicoValue &parent, PTomlParserData &data)
Parse a dico definition.
Data used to parse a toml file.
bool isRun
True to continue the parsing, false to stop.
PFileParser parser
Parser to be used.