IT++ Logo
parser.cpp
Go to the documentation of this file.
1 
31 #include <itpp/base/parser.h>
32 #include <fstream>
33 #include <sstream>
34 
35 
36 using std::cout;
37 using std::endl;
38 
39 namespace itpp
40 {
41 
43 {
44  VERBOSE = true;
45 }
46 
47 Parser::Parser(const std::string &filename)
48 {
49  VERBOSE = true;
50  init(filename);
51 }
52 
53 Parser::Parser(int argc, char *argv[])
54 {
55  VERBOSE = true;
56  init(argc, argv);
57 }
58 
59 Parser::Parser(const std::string &filename, int argc, char *argv[])
60 {
61  VERBOSE = true;
62  init(filename, argc, argv);
63 }
64 
66 {
67  VERBOSE = true;
68  init(setup);
69 }
70 
71 void Parser::pre_parsing(void)
72 {
73  int i, j, n, k;
74  int count = 0;
75  int size = SetupStrings.size();
76  bool cont_line;
77  std::string Line, NewLine;
78  Array<std::string> TempSetupStrings;
79 
80  // Remove lines starting with '%' or have zero length:
81  for (i = 0; i < size; i++) {
82  Line = SetupStrings(i);
83  if ((Line.length() != 0) && (Line[0] != '%')) {
84  SetupStrings(count) = Line;
85  count++;
86  }
87  }
88  SetupStrings.set_size(count, true);
89  size = SetupStrings.size();
90 
91  //Check for '...' continuation as in Matlab:
92  count = 0;
93  NewLine = "";
94  for (i = 0; i < SetupStrings.size(); i++) {
95  Line = SetupStrings(i);
96  n = int(Line.size());
97  cont_line = false;
98  for (k = 0; k < (n - 2); k++) {
99  if ((Line[k] == '.') && (Line[k+1] == '.') && (Line[k+2] == '.')) {
100  cont_line = true;
101  break;
102  }
103  }
104  if (cont_line) {
105  for (j = 0; j < k; j++) { NewLine += Line[j]; }
106  }
107  else {
108  NewLine += Line;
109  SetupStrings(count) = NewLine;
110  count++;
111  NewLine = "";
112  }
113  }
114  SetupStrings.set_size(count, true);
115 
116  //Strip unneccesary blanks, tabs, and newlines:
117  size = SetupStrings.size();
118  for (i = 0; i < size; i++) {
119  NewLine = "";
120  Line = SetupStrings(i);
121  n = int(Line.length());
122  j = 0; //counter in Line
123  while (j < n) {
124  switch (Line[j]) {
125  case '\n':
126  //Remove newlines
127  j++;
128  break;
129  case ' ':
130  //Remove blanks
131  j++;
132  break;
133  case '\t':
134  //Remove tabs
135  j++;
136  break;
137  case '[':
138  //Don't remove blanks between '[' and ']'
139  while ((j < n) && (Line[j] != ']')) { NewLine += Line[j]; j++; }
140  if (j < n) { NewLine += Line[j]; j++; }
141  break;
142  case '{':
143  //Don't remove blanks between '{' and '}'
144  while ((j < n) && (Line[j] != '}')) { NewLine += Line[j]; j++; }
145  if (j < n) { NewLine += Line[j]; j++; }
146  break;
147  case '"':
148  //Don't remove blanks between '"' and '"'
149  NewLine += Line[j];
150  j++; //Read in the first '"'
151  while ((j < n) && (Line[j] != '"')) { NewLine += Line[j]; j++; }
152  NewLine += Line[j];
153  j++;
154  break;
155  case '\'':
156  //Don't remove blanks between '\'' and '\''
157  NewLine += Line[j];
158  j++; //Read in the first '\''
159  while ((j < n) && (Line[j] != '\'')) { NewLine += Line[j]; j++; }
160  NewLine += Line[j];
161  j++;
162  break;
163  case '%':
164  //Remove trailing comments
165  j = n;
166  break;
167  default:
168  //Keep the current character:
169  NewLine += Line[j];
170  j++;
171  break;
172  }
173  }
174  SetupStrings(i) = NewLine;
175  }
176 
177  // Split lines with several expressions (i.e. a=3;b=[1 2 3],c="Hello World") on the same line
178  // (separated by comma or semicolon)
179  TempSetupStrings.set_size(size, false);
180  count = 0; //Counter in TempSetupStrings
181  for (i = 0; i < size; i++) {
182 
183  NewLine = "";
184  Line = SetupStrings(i);
185  n = int(Line.length());
186  j = 0;
187 
188  while (j < n) {
189 
190  switch (Line[j]) {
191 
192  case '[':
193  //A vector or a matrix
194  while ((j < n) && (Line[j] != ']')) { NewLine += Line[j]; j++; }
195  if (Line[j] == ']') { NewLine += Line[j]; j++; }
196  if (j == n) {
197  if (count >= TempSetupStrings.size()) { TempSetupStrings.set_size(2*count, true); }
198  TempSetupStrings(count) = NewLine;
199  NewLine = "";
200  count++;
201  }
202  break;
203 
204  case '"':
205  //A string
206  NewLine += Line[j];
207  j++; //Read in the first '"'
208  while ((j < n) && (Line[j] != '"')) { NewLine += Line[j]; j++; }
209  if (Line[j] == '"') { NewLine += Line[j]; j++; }
210  if (j == n) {
211  if (count >= TempSetupStrings.size()) { TempSetupStrings.set_size(2*count, true); }
212  TempSetupStrings(count) = NewLine;
213  NewLine = "";
214  count++;
215  }
216  break;
217 
218 
219  case '\'':
220  //A string
221  NewLine += Line[j];
222  j++; //Read in the first '\''
223  while ((j < n) && (Line[j] != '\'')) { NewLine += Line[j]; j++; }
224  if (Line[j] == '\'') { NewLine += Line[j]; j++; }
225  if (j == n) {
226  if (count >= TempSetupStrings.size()) { TempSetupStrings.set_size(2*count, true); }
227  TempSetupStrings(count) = NewLine;
228  NewLine = "";
229  count++;
230  }
231  break;
232 
233  case ',':
234  //Expression ends here
235  if (count >= TempSetupStrings.size()) { TempSetupStrings.set_size(2*count, true); }
236  TempSetupStrings(count) = NewLine;
237  NewLine = "";
238  count++;
239  j++;
240  break;
241 
242  case ';':
243  //Expression ends here
244  if (count >= TempSetupStrings.size()) { TempSetupStrings.set_size(2*count, true); }
245  TempSetupStrings(count) = NewLine + ';';
246  NewLine = "";
247  count++;
248  j++;
249  break;
250 
251  default:
252  //Copy the current character:
253  NewLine += Line[j];
254  j++;
255  if (j == n) {
256  if (count >= TempSetupStrings.size()) { TempSetupStrings.set_size(2*count, true); }
257  TempSetupStrings(count) = NewLine;
258  NewLine = "";
259  count++;
260  }
261  break;
262 
263  }
264 
265  }
266 
267  }
268  TempSetupStrings.set_size(count, true);
269  SetupStrings = TempSetupStrings;
270 }
271 
272 void Parser::init(const std::string &filename)
273 {
274  std::string Line;
275  SetupStrings.set_size(0, false);
276  std::ifstream SetupFile(filename.c_str());
277  it_assert(SetupFile.is_open(),
278  "Parser::init(): Could not open `" + filename + "' file");
279 
280  while (getline(SetupFile, Line, '\n')) {
281  SetupStrings.set_size(SetupStrings.size() + 1, true);
282  SetupStrings(SetupStrings.size() - 1) = Line;
283  }
284 
285  SetupFile.close();
286  pre_parsing();
287 }
288 
289 void Parser::init(int argc, char *argv[])
290 {
291  SetupStrings.set_size(argc);
292  int i;
293 
294  for (i = 0; i < argc; i++) {
295  SetupStrings(i) = argv[i];
296  }
297  pre_parsing();
298 }
299 
300 void Parser::init(const std::string &filename, int argc, char *argv[])
301 {
302  std::string Line;
303  int i;
304  std::ifstream SetupFile(filename.c_str());
305  it_assert(SetupFile.is_open(),
306  "Parser::init(): Could not open `" + filename + "' file");
307 
308  //Read the command line parameters:
309  SetupStrings.set_size(argc);
310  for (i = 0; i < argc; i++) {
311  SetupStrings(i) = argv[i];
312  }
313 
314  //Read the file parameters:
315  while (getline(SetupFile, Line, '\n')) {
316  SetupStrings.set_size(SetupStrings.size() + 1, true);
317  SetupStrings(SetupStrings.size() - 1) = Line;
318  }
319 
320  SetupFile.close();
321  pre_parsing();
322 }
323 
325 {
326  SetupStrings = setup;
327  pre_parsing();
328 }
329 
331 {
332  VERBOSE = !v;
333 }
334 
335 bool Parser::exist(const std::string &name)
336 {
337  bool error_flag, print_flag;
338  std::string temp = findname(name, error_flag, print_flag);
339  if (error_flag) {
340  return false;
341  }
342  else {
343  return true;
344  }
345 }
346 
347 template<>
348 bool Parser::get(std::string &var, const std::string &name, int num)
349 {
350  bool error_flag, print_flag;
351  std::string str = findname(name, error_flag, print_flag, num);
352  if (error_flag) {
353  if (VERBOSE) {
354  cout << name << " = '" << var << "';" << endl;
355  }
356  }
357  else {
358  var = str;
359  if (print_flag) {
360  cout << name << " = '" << var << "'" << endl;
361  }
362  else if (VERBOSE) {
363  cout << name << " = '" << var << "';" << endl;
364  }
365  }
366  return !error_flag;
367 }
368 
369 template<>
370 bool Parser::get(int &var, const std::string &name, int num)
371 {
372  ivec out;
373  bool error_flag, print_flag;
374  out = ivec(findname(name, error_flag, print_flag, num));
375  if (error_flag) {
376  if (VERBOSE) {
377  cout << name << " = " << var << ";" << endl;
378  }
379  }
380  else {
381  it_assert(out.size() == 1, "Parser::get(int): Improper variable string: "
382  + name);
383  var = out(0);
384  if (print_flag) {
385  cout << name << " = " << var << endl;
386  }
387  else if (VERBOSE) {
388  cout << name << " = " << var << ";" << endl;
389  }
390  }
391  return !error_flag;
392 }
393 
394 template<>
395 bool Parser::get(bool &var, const std::string &name, int num)
396 {
397  std::string ss;
398  bool error_flag, print_flag;
399  ss = findname(name, error_flag, print_flag, num);
400  if (error_flag) {
401  if (VERBOSE) {
402  cout << name << " = " << var << ";" << endl;
403  }
404  }
405  else {
406  if ((ss == "true") || (ss == "1")) {
407  var = true;
408  }
409  else if ((ss == "false") || (ss == "0")) {
410  var = false;
411  }
412  else {
413  it_error("Parser::get(bool): Improper variable string: " + name);
414  }
415  if (print_flag) {
416  cout << name << " = " << var << endl;
417  }
418  else if (VERBOSE) {
419  cout << name << " = " << var << ";" << endl;
420  }
421  }
422  return !error_flag;
423 }
424 
425 bool Parser::get_bool(const std::string &name, int num)
426 {
427  std::string ss;
428  bool out = false;
429  bool error_flag, print_flag;
430  ss = findname(name, error_flag, print_flag, num);
431  it_assert(!error_flag, "Parser::get_bool(): Can not find variable: " + name);
432  if ((ss == "true") || (ss == "1")) {
433  out = true;
434  }
435  else if ((ss == "false") || (ss == "0")) {
436  out = false;
437  }
438  else {
439  it_error("Parser::get_bool(): Improper variable string: " + name);
440  }
441  if (print_flag) { cout << "Parsing bool : " << name << " = " << out << endl; }
442  return out;
443 }
444 
445 int Parser::get_int(const std::string &name, int num)
446 {
447  ivec out;
448  bool error_flag, print_flag;
449  out = ivec(findname(name, error_flag, print_flag, num));
450  it_assert(!error_flag, "Parser::get_int(): Can not find variable: " + name);
451  it_assert(out.size() == 1, "Parser::get_int(): Improper variable string: "
452  + name);
453  if (print_flag) {
454  cout << "Parsing int : " << name << " = " << out(0) << endl;
455  }
456  return out(0);
457 }
458 
459 double Parser::get_double(const std::string &name, int num)
460 {
461  double out;
462  bool error_flag, print_flag;
463  std::istringstream ss(findname(name, error_flag, print_flag, num));
464  ss >> out;
465  if (error_flag) { it_error("Parser: Can not find variable: " + name); }
466  if (print_flag) { cout << "Parsing double: " << name << " = " << out << endl; }
467  return out;
468 }
469 
470 std::string Parser::get_string(const std::string &name, int num)
471 {
472  std::string out;
473  bool error_flag, print_flag;
474  out = findname(name, error_flag, print_flag, num);
475  if (error_flag) { it_error("Parser: Can not find variable: " + name); }
476  if (print_flag) { cout << "Parsing string: " << name << " = " << out << endl; }
477  return out;
478 }
479 
480 vec Parser::get_vec(const std::string &name, int num)
481 {
482  vec out;
483  bool error_flag, print_flag;
484  out = vec(findname(name, error_flag, print_flag, num));
485  if (error_flag) { it_error("Parser: Can not find variable: " + name); }
486  if (print_flag) { cout << "Parsing vec : " << name << " = " << out << endl; }
487  return out;
488 }
489 
490 ivec Parser::get_ivec(const std::string &name, int num)
491 {
492  ivec out;
493  bool error_flag, print_flag;
494  out = ivec(findname(name, error_flag, print_flag, num));
495  if (error_flag) { it_error("Parser: Can not find variable: " + name); }
496  if (print_flag) { cout << "Parsing ivec : " << name << " = " << out << endl; }
497  return out;
498 }
499 
500 svec Parser::get_svec(const std::string &name, int num)
501 {
502  svec out;
503  bool error_flag, print_flag;
504  out = svec(findname(name, error_flag, print_flag, num));
505  if (error_flag) { it_error("Parser: Can not find variable: " + name); }
506  if (print_flag) { cout << "Parsing svec : " << name << " = " << out << endl; }
507  return out;
508 }
509 
510 bvec Parser::get_bvec(const std::string &name, int num)
511 {
512  bvec out;
513  bool error_flag, print_flag;
514  out = bvec(findname(name, error_flag, print_flag, num));
515  if (error_flag) { it_error("Parser: Can not find variable: " + name); }
516  if (print_flag) { cout << "Parsing bvec : " << name << " = " << out << endl; }
517  return out;
518 }
519 
520 mat Parser::get_mat(const std::string &name, int num)
521 {
522  mat out;
523  bool error_flag, print_flag;
524  out = mat(findname(name, error_flag, print_flag, num));
525  if (error_flag) { it_error("Parser: Can not find variable: " + name); }
526  if (print_flag) { cout << "Parsing mat : " << name << " = " << out << endl; }
527  return out;
528 }
529 
530 imat Parser::get_imat(const std::string &name, int num)
531 {
532  imat out;
533  bool error_flag, print_flag;
534  out = imat(findname(name, error_flag, print_flag, num));
535  if (error_flag) { it_error("Parser: Can not find variable: " + name); }
536  if (print_flag) { cout << "Parsing imat : " << name << " = " << out << endl; }
537  return out;
538 }
539 
540 smat Parser::get_smat(const std::string &name, int num)
541 {
542  smat out;
543  bool error_flag, print_flag;
544  out = smat(findname(name, error_flag, print_flag, num));
545  if (error_flag) { it_error("Parser: Can not find variable: " + name); }
546  if (print_flag) { cout << "Parsing smat : " << name << " = " << out << endl; }
547  return out;
548 }
549 
550 bmat Parser::get_bmat(const std::string &name, int num)
551 {
552  bmat out;
553  bool error_flag, print_flag;
554  out = bmat(findname(name, error_flag, print_flag, num));
555  if (error_flag) { it_error("Parser: Can not find variable: " + name); }
556  if (print_flag) { cout << "Parsing bmat : " << name << " = " << out << endl; }
557  return out;
558 }
559 
560 std::string Parser::findname(const std::string &name, bool &error_flag, bool &print_flag, int num, bool keep_brackets)
561 {
562  std::string Name, Out, Line, Temp;
563  int n, j = 0, i = 0, index = -1;
564  bool found = false, vec_mat = false;
565 
566  error_flag = false;
567  print_flag = false;
568  if (num < 0) { num = 0; }
569  Name = "";
570 
571  // Go through all words in input string to find a match
572  while (i < SetupStrings.size()) {
573  Line = SetupStrings(i);
574  i++;
575 
576  // Find equal sign "=", and take the left part to be the Name
577  if (Line.find_first_of("=") != std::string::npos) {
578  Name = Line.substr(0, Line.find_first_of("="));
579  }
580  else {
581  Name = "";
582  }
583 
584  if (Name == name) {
585  if (found) {
586  //cout << "Parser Warning: Duplicate Entry of variable " << name << endl;
587  } else {
588  found = true;
589  index = i - 1;
590  }
591  }
592  }
593 
594  // if we have a match
595  if ((found) && (index + num <= SetupStrings.size())) {
596  Line = SetupStrings(index + num);
597  if (num != 0) {
598  Temp = Line;
599  }
600  else {
601  Temp = Line.substr(Line.find_first_of("=") + 1);
602  }
603  }
604  else {
605  error_flag = true;
606  return "";
607  }
608 
609  //Remove [, ],",' and ending ;. Set the print_flag:
610  n = int(Temp.size());
611  Out = "";
612  for (i = 0; i < n; i++) {
613  switch (Temp[i]) {
614  case '[':
615  vec_mat = true;
616  if (keep_brackets) { Out += Temp[i]; }
617  if (i == (n - 1)) { print_flag = true; }
618  break;
619  case ']':
620  if (keep_brackets) { Out += Temp[i]; }
621  if (i == (n - 1)) { print_flag = true; }
622  break;
623  case '"':
624  if (i == (n - 1)) { print_flag = true; }
625  break;
626  case '\'':
627  if (i == (n - 1)) { print_flag = true; }
628  break;
629  case ';':
630  if (i == (n - 1)) { print_flag = false; }
631  else { Out += Temp[i]; }
632  break;
633  default:
634  Out += Temp[i];
635  if (i == (n - 1)) { print_flag = true; }
636  break;
637  }
638  }
639 
640  //Final parsing of vectors and matrices:
641  if (vec_mat) {
642 
643  Temp = Out;
644  Out = "";
645  n = int(Temp.size());
646  j = 0;
647 
648  while ((Temp[j] == ' ') || (Temp[j] == '\t') || (Temp[j] == '\n')) { j++; } //Remove spaces/tabs/newline in beginning
649  while ((Temp[n-1] == ' ') || (Temp[n-1] == '\t') || (Temp[n-1] == '\n')) { n--; } //Remove spaces/tabs/newline at the end
650 
651  while (j < n) {
652 
653  //Read in data element:
654  while ((j < n) && (Temp[j] != ' ') && (Temp[j] != '\t') && (Temp[j] != '\n') && (Temp[j] != ',') && (Temp[j] != ';')) {
655  Out += Temp[j];
656  j++;
657  }
658 
659  //Read separator:
660  if (j < (n - 1)) {
661  //Remove spaces before separator
662  while ((j < n) && ((Temp[j] == ' ') || (Temp[j] == '\t') || (Temp[j] == '\n'))) { j++; }
663  //Insert Separator:
664  if (j < n) {
665  if (Temp[j] == ';') { Out += ';'; j++; }
666  else if (Temp[j] == ',') { Out += ' '; j++; }
667  else if (Temp[j] == '+') { Out += ' '; Out += Temp[j]; j++; }
668  else if (Temp[j] == '-') { Out += ' '; Out += Temp[j]; j++; }
669  else { Out += ' '; }
670  }
671  //Remove spaces after separator:
672  while ((j < n) && ((Temp[j] == ' ') || (Temp[j] == '\t') || (Temp[j] == '\n'))) { j++; }
673  }
674 
675  }
676 
677  }
678  if (!VERBOSE) print_flag = false;
679  return Out;
680 }
681 
682 } // namespace itpp
SourceForge Logo

Generated on Sat Jul 6 2013 10:54:21 for IT++ by Doxygen 1.8.2