PhoenixToml  1.2.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 ConfigNode * subValue = var.addChild();
333 if(parse_tomlCompactDico(*subValue, data)){
334 if(!parser.isMatch(",") && !parser.isMatchRewind("]")){ //We expect one element or a comma to add more
335 std::cerr << "parse_toml_varValue : expect ',' or ']' for unclosed list of values at " << parser.getLocation() << std::endl;
337 return false;
338 }
339 }
340 else if(parse_toml_varValue(*subValue, data)){
341 if(!parser.isMatch(",") && !parser.isMatchRewind("]")){ //We expect one element or a comma to add more
342 std::cerr << "parse_toml_varValue : expect ',' or ']' for unclosed list of values at " << parser.getLocation() << std::endl;
344 return false;
345 }
346 }else{
347 if(!parser.isMatch("]")){
348 std::cerr << "parse_toml_varValue : missing ']' token to close empty list of value at " << parser.getLocation() << std::endl;
350 return false;
351 }
352 }
353 }
354 }else{
355 PString strValue("");
356 if(parse_generic_string(strValue, parser)){
357 var.setValue(strValue);
358 }else if(parser.isMatch("true")){
359 var.setValue("true");
360 }else if(parser.isMatch("false")){
361 var.setValue("false");
362 }else{
363 PString valueNumber(parser.getStrComposedOf("0123456789.-+e"));
364 if(valueNumber != ""){
365 var.setValue(valueNumber);
366 }else{
367 std::cerr << "parse_toml_varValue : missing value of variable '"<<var.getName()<<"' at " << parser.getLocation() << std::endl;
369 return false;
370 }
371 }
372 }
373 return true;
374}
375
377
381bool parse_toml_var(ConfigNode & parent, PTomlParserData & data){
382 PFileParser & parser = data.parser;
383 PString varName("");
384 if(!parse_toml_varName(varName, parser)){return false;}
385 if(!parser.isMatch("=")){
386 std::cerr << "parse_toml_var : missing '=' token to define value of variable '"<<varName<<"' at " << parser.getLocation() << std::endl;
388 return false;
389 }
390 ConfigNode * var = parent.addChild(varName);
391 var->setLineCol(parser.getLocation());
392 bool b(true);
393 if(parse_tomlCompactDico(*var, data)){}
394 else if(parse_toml_varValue(*var, data)){}
395 else{b = false;}
396 return b;
397}
398
400
404ConfigNode * parse_get_parent_dico(ConfigNode & parent, const PVecString & vecDicoName){
405 ConfigNode * output = &parent;
406 for(PVecString::const_iterator it(vecDicoName.begin()); it != vecDicoName.end(); ++it){
407 ConfigNode * next = output->getChild(it->eraseFirstLastChar("\"'"));
408 if(next == NULL){
409 next = output->addChild(*it);
410 }
411 output = next;
412 output->setName(*it);
413 }
414 return output;
415}
416
418
422bool parse_toml_dico_def(ConfigNode & parent, PTomlParserData & data){
423 PFileParser & parser = data.parser;
424 if(!parser.isMatch("[")){return false;}
425 PString dicoName(parser.getUntilKeyWithoutPatern("]"));
426 PVecString vecDicoName = dicoName.split('.');
427 ConfigNode * dicoDef = parse_get_parent_dico(parent, vecDicoName);
428 dicoDef->setLineCol(parser.getLocation());
429 while(!parser.isEndOfFile() && parse_toml_isParse(data) && !parser.isMatchRewind("[")){ //Let's parse the vatiables of the Dico
430 if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
431 else if(parse_toml_var(*dicoDef, data)){}
432 }
433 return true;
434}
435
437
441bool parse_toml_table_def(ConfigNode & parent, PTomlParserData & data){
442 PFileParser & parser = data.parser;
443 if(!parser.isMatch("[[")){return false;}
444 PString dicoName(parser.getUntilKeyWithoutPatern("]]"));
445 PVecString vecDicoName = dicoName.split('.');
446 ConfigNode * dicoDef = parse_get_parent_dico(parent, vecDicoName);
447 dicoDef->setLineCol(parser.getLocation());
448 ConfigNode * table = dicoDef->addChild();
449 table->setLineCol(parser.getLocation());
450 while(!parser.isEndOfFile() && parse_toml_isParse(data) && !parser.isMatchRewind("[")){ //Let's parse the vatiables of the Dico
451 if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
452 else if(parse_toml_var(*table, data)){}
453 }
454 return true;
455}
456
458
462bool parser_toml_fileParser(ConfigNode & node, PTomlParserData & data){
463 PFileParser & parser = data.parser;
464 parser.getStrComposedOf(" \t\n"); //Skip all blank characters
465 while(!parser.isEndOfFile() && parse_toml_isParse(data)){
466 if(parser.isMatch("#")){parser.getUntilKeyWithoutPatern("\n");}
467 else if(parse_toml_table_def(node, data)){}
468 else if(parse_toml_dico_def(node, data)){}
469 else{
470 PString nextToken(parser.getNextToken());
471 if(nextToken.size() != 0lu){ //If the token is empty, we are at the end of the file
472 std::cerr << "parser_toml_fileParser : error at " << parser.getLocation() << std::endl;
473 std::cerr << "\tunexpected token '"<<nextToken<<"'" << std::endl;
475 }
476 }
477 }
478 return data.isRun;
479}
480
482
486bool parser_toml(ConfigNode & node, const PPath & fileName){
488 PFileParser & parser = data.parser;
489 parser.setWhiteSpace(" \n\t");
490 parser.setSeparator(":-'\",{}[]>|");
491 parser.setEscapeChar('\\');
492 if(!parser.open(fileName)){
493 std::cerr << "parser_toml : cannot open file '"<<fileName<<"'" << std::endl;
494 return false;
495 }
496 node.setFileName(fileName);
497 bool b(parser_toml_fileParser(node, data));
498 return b;
499}
500
502
506bool parser_tomlString(ConfigNode & node, const PString & fileContent){
508 PFileParser & parser = data.parser;
509 parser.setWhiteSpace(" \n\t");
510 parser.setSeparator(":-'\",{}[]>|");
511 parser.setEscapeChar('\\');
512 parser.setFileContent(fileContent);
513 bool b(parser_toml_fileParser(node, data));
514 return b;
515}
516
517
518
519
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.