aGrUM  0.14.2
O3prmReader_tpl.h
Go to the documentation of this file.
1 /**************************************************************************
2  * Copyright (C) 2005 by Pierre-Henri WUILLEMIN et Christophe GONZALES *
3  * {prenom.nom}_at_lip6.fr *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the GNU General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the GNU General Public License *
16  * along with this program; if not, write to the *
17  * Free Software Foundation, Inc., *
18  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19  ***************************************************************************/
20 
29 
30 namespace gum {
31  namespace prm {
32  namespace o3prm {
33 
34  template < typename GUM_SCALAR >
35  INLINE std::string
36  O3prmReader< GUM_SCALAR >::__clean(std::string text) const {
37  // This could be way more faster with regex but there are not implemented
38  // with gcc-4.8 !
39  text = replace(text, "Syntax error", "Error");
40 
41  text = replace(text, "LABEL_OR_STAR_LIST", "declaration");
42 
43  text = replace(text, "ARRAY_REFERENCE_SLOT", "declaration");
44  text = replace(text, "FLOAT_AS_LABEL", "declaration");
45  text = replace(text, "FLOAT_OR_INT", "declaration");
46  text = replace(text, "INTEGER_AS_FLOAT", "declaration");
47  text = replace(text, "INTEGER_AS_LABEL", "declaration");
48  text = replace(text, "INT_TYPE_DECLARATION", "declaration");
49  text = replace(text, "LABEL_OR_INT", "declaration");
50  text = replace(text, "LABEL_OR_STAR", "declaration");
51  text = replace(text, "NAMED_CLASS_ELEMENT", "declaration");
52  text = replace(text, "REAL_TYPE_DECLARATION", "declaration");
53 
54  text = replace(text, "AGGREGATE_PARENTS", "declaration");
55  text = replace(text, "CLASS_BODY", "declaration");
56  text = replace(text, "CLASS_DECLARATION", "declaration");
57  text = replace(text, "CLASS_ELEMENT", "declaration");
58  text = replace(text, "CLASS_PARAMETER", "declaration");
59  text = replace(text, "CLASS_UNIT", "declaration");
60  text = replace(text, "FLOAT_LIST", "declaration");
61  text = replace(text, "FORMULA_LIST", "declaration");
62  text = replace(text, "IDENTIFIER_LIST", "declaration");
63  text = replace(text, "IMPORT_BODY", "declaration");
64  text = replace(text, "IMPORT_DECLARATION", "declaration");
65  text = replace(text, "IMPORT_UNIT", "declaration");
66  text = replace(text, "INTERFACE_BODY", "declaration");
67  text = replace(text, "INTERFACE_DECLARATION", "declaration");
68  text = replace(text, "INTERFACE_UNIT", "declaration");
69  text = replace(text, "LABEL_LIST", "declaration");
70  text = replace(text, "PARAMETER_LIST", "declaration");
71  text = replace(text, "PREFIXED_LABEL", "declaration");
72  text = replace(text, "RAW_CPT", "declaration");
73  text = replace(text, "REFERENCE_SLOT", "declaration");
74  text = replace(text, "RULE_CPT", "declaration");
75  text = replace(text, "SYSTEM_BODY", "declaration");
76  text = replace(text, "SYSTEM_DECLARATION", "declaration");
77  text = replace(text, "SYSTEM_UNIT", "declaration");
78  text = replace(text, "TYPE_DECLARATION", "declaration");
79  text = replace(text, "TYPE_LABEL", "declaration");
80  text = replace(text, "TYPE_UNIT", "declaration");
81  text = replace(text, "TYPE_VALUE_LIST", "declaration");
82 
83  text = replace(text, "AGGREGATE", "declaration");
84  text = replace(text, "ARRAY", "declaration");
85  text = replace(text, "ATTRIBUTE", "declaration");
86  text = replace(text, "CAST", "declaration");
87  text = replace(text, "CHAIN", "declaration");
88  text = replace(text, "CLASS", "declaration");
89  text = replace(text, "FLOAT", "declaration");
90  text = replace(text, "FORMULA", "declaration");
91  text = replace(text, "IDENTIFIER", "declaration");
92  text = replace(text, "INT", "declaration");
93  text = replace(text, "INTEGER", "declaration");
94  text = replace(text, "INTERFACE", "declaration");
95  text = replace(text, "LABEL", "declaration");
96  text = replace(text, "LINK", "declaration");
97  text = replace(text, "MAP", "declaration");
98  text = replace(text, "PARAMETER", "declaration");
99  text = replace(text, "REAL", "declaration");
100  text = replace(text, "RULE", "declaration");
101  text = replace(text, "TYPE", "declaration");
102  text = replace(text, "UNIT", "declaration");
103 
104  return text;
105  }
106 
107  template < typename GUM_SCALAR >
108  INLINE std::string
110  std::stringstream s;
111  s << err.filename << "|" << err.line << " col " << err.column << "| "
112  << __clean(err.msg);
113  return s.str();
114  }
115 
116  template < typename GUM_SCALAR >
117  INLINE std::string
118  O3prmReader< GUM_SCALAR >::__readStream(std::istream& inputstr) {
119  if (inputstr) {
120  inputstr.seekg(0, inputstr.end);
121  int length = int(inputstr.tellg());
122  inputstr.seekg(0, inputstr.beg);
123 
124  auto str = std::string();
125  str.resize(length, ' ');
126  auto begin = &*str.begin();
127 
128  inputstr.read(begin, length);
129 
130  return str;
131  }
132  GUM_ERROR(OperationNotAllowed, "Could not open file");
133  }
134 
135  using o3prm_scanner = gum::prm::o3prm::Scanner;
136  using o3prm_parser = gum::prm::o3prm::Parser;
137 
138  template < typename GUM_SCALAR >
140  __prm(new PRM< GUM_SCALAR >()),
141  __o3_prm(std::unique_ptr< O3PRM >(new O3PRM())) {
142  GUM_CONSTRUCTOR(O3prmReader);
143  }
144 
145  template < typename GUM_SCALAR >
147  __prm(&prm), __o3_prm(std::unique_ptr< O3PRM >(new O3PRM())) {
148  GUM_CONSTRUCTOR(O3prmReader);
149  }
150 
151  template < typename GUM_SCALAR >
153  __prm(src.__prm),
154  __o3_prm(std::unique_ptr< O3PRM >(new O3PRM(*(src.__o3_prm)))),
155  __class_path(src.__class_path), __imported(src.__imported),
156  __errors(src.__errors) {
157  GUM_CONS_CPY(O3prmReader);
158  }
159 
160  template < typename GUM_SCALAR >
162  __prm(std::move(src.__prm)), __o3_prm(std::move(src.__o3_prm)),
163  __class_path(std::move(src.__class_path)),
164  __imported(std::move(src.__imported)),
165  __errors(std::move(src.__errors)) {
166  GUM_CONS_CPY(O3prmReader);
167  }
168 
169  template < typename GUM_SCALAR >
171  GUM_DESTRUCTOR(O3prmReader);
172  }
173 
174  template < typename GUM_SCALAR >
176  operator=(const O3prmReader& src) {
177  if (this == &src) { return *this; }
178  __prm = src.__prm;
179  __o3_prm = std::unique_ptr< O3PRM >(new O3PRM(*(src.__o3_prm)));
180  __class_path = src.__class_path;
181  __imported = src.__imported;
182  __errors = src.__errors;
183  return *this;
184  }
185 
186  template < typename GUM_SCALAR >
189  if (this == &src) { return *this; }
190  __prm = std::move(src.__prm);
191  __o3_prm = std::move(src.__o3_prm);
192  __class_path = std::move(src.__class_path);
193  __imported = std::move(src.__imported);
194  __errors = std::move(src.__errors);
195  return *this;
196  }
197 
198  template < typename GUM_SCALAR >
199  void O3prmReader< GUM_SCALAR >::setClassPath(const std::string& class_path) {
200  __class_path = std::vector< std::string >();
201  size_t i = 0;
202  size_t j = class_path.find(';');
203 
204  while (j != std::string::npos) {
205  addClassPath(class_path.substr(i, j - i));
206  i = j + 1;
207 
208  if (i < class_path.size()) {
209  j = class_path.find(';', i);
210  } else {
211  j = std::string::npos;
212  }
213  }
214 
215  if (i < class_path.size()) {
216  addClassPath(class_path.substr(i, std::string::npos));
217  }
218  }
219 
220  template < typename GUM_SCALAR >
221  void O3prmReader< GUM_SCALAR >::addClassPath(const std::string& class_path) {
222  auto path = class_path;
223  if (path[path.size() - 1] != '/') { path.append("/"); }
224  auto dir = Directory(path);
225 
226  if (!dir.isValid()) {
227  __errors.addException("could not resolve class path", path);
228  } else {
229  __class_path.push_back(std::move(path));
230  }
231  }
232 
233  template < typename GUM_SCALAR >
235  return __errors.error(i).line;
236  }
237 
238  template < typename GUM_SCALAR >
240  return __errors.error(i).column;
241  }
242 
243  template < typename GUM_SCALAR >
244  INLINE std::wstring O3prmReader< GUM_SCALAR >::errFilename(Idx i) const {
245  return widen(__errors.error(i).filename);
246  }
247 
248  template < typename GUM_SCALAR >
250  return __errors.error(i).is_error;
251  }
252 
253  template < typename GUM_SCALAR >
254  INLINE std::string O3prmReader< GUM_SCALAR >::errMsg(Idx i) const {
255  return __errors.error(i).msg;
256  }
257 
258  template < typename GUM_SCALAR >
259  INLINE void
261  for (Idx i = 0; i < __errors.count(); ++i) {
262  auto err = __errors.error(i);
263  if (err.is_error) { o << __print(err) << std::endl; }
264  }
265  }
266 
267  template < typename GUM_SCALAR >
269  std::ostream& o) const {
270  for (Idx i = 0; i < __errors.count(); ++i) {
271  auto err = __errors.error(i);
272  o << __print(err) << std::endl;
273  }
274  }
275 
276  template < typename GUM_SCALAR >
277  INLINE void
279  __errors.syntheticResults(o);
280  }
281 
282  template < typename GUM_SCALAR >
284  return __errors.error_count;
285  }
286 
287  template < typename GUM_SCALAR >
289  return __errors.warning_count;
290  }
291 
292  template < typename GUM_SCALAR >
293  INLINE const ErrorsContainer&
295  return __errors;
296  }
297 
298  template < typename GUM_SCALAR >
299  INLINE Size O3prmReader< GUM_SCALAR >::readString(const std::string& str) {
300  std::stringstream sBuff(str);
301  __readStream(sBuff, "");
302  return __errors.count();
303  }
304 
305  template < typename GUM_SCALAR >
306  INLINE Size O3prmReader< GUM_SCALAR >::readFile(const std::string& file,
307  const std::string& module) {
308  try {
309  auto lastSlashIndex = file.find_last_of('/');
310 
311  auto dir = Directory(file.substr(0, lastSlashIndex + 1));
312 
313  if (!dir.isValid()) {
314  __errors.addException("could not find file", file);
315  return __errors.count();
316  }
317 
318  auto basename = file.substr(lastSlashIndex + 1);
319  auto absFilename = dir.absolutePath() + basename;
320 
321  std::ifstream input(absFilename);
322  if (input.is_open()) {
323  __readStream(input, file, module);
324  } else {
325  __errors.addException("could not open file", file);
326  }
327 
328  return __errors.count();
329 
330  } catch (gum::Exception& e) {
331  GUM_SHOWERROR(e);
332  __errors.addException(e.errorContent(), file);
333  return __errors.count();
334  } catch (...) {
335  __errors.addException("unknown error", file);
336  return __errors.count();
337  }
338  }
339 
340  template < typename GUM_SCALAR >
341  INLINE void O3prmReader< GUM_SCALAR >::parseStream(std::istream& input,
342  std::ostream& output,
343  std::string module) {
344  __readStream(input, "", module);
345 
346  showElegantErrorsAndWarnings(output);
347  }
348 
349  template < typename GUM_SCALAR >
350  INLINE void
352  const std::string& filename,
353  const std::string& module) {
354  auto sBuff = __readStream(input);
355  auto buffer = std::unique_ptr< unsigned char[] >(
356  new unsigned char[sBuff.length() + 1]);
357  strcpy((char*)buffer.get(), sBuff.c_str());
358  auto s = o3prm_scanner(buffer.get(), int(sBuff.length() + 1), filename);
359  auto p = o3prm_parser(&s);
360  p.set_prm(__o3_prm.get());
361  p.set_prefix(module);
362  p.Parse();
363  __errors += p.errors();
364  }
365 
366  template < typename GUM_SCALAR >
367  INLINE void
369  const std::string& module) {
370  if (!__imported.exists(i.import().label())) {
371  __imported.insert(i.import().label());
372 
373  auto module_path = module;
374  std::replace(module_path.begin(), module_path.end(), '.', '/');
375 
376  auto path = i.import().label();
377  std::replace(path.begin(), path.end(), '.', '/');
378 
379  auto imported = false;
380  for (const auto& cp : __class_path) {
381  auto file_path = cp + path + ".o3prm";
382  std::ifstream file(file_path);
383 
384  if (file.is_open()) {
385  __parseStream(file, file_path, i.import().label());
386  imported = true;
387  break;
388  }
389 
390  file_path = cp + module + path + ".o3prm";
391  std::ifstream file2(file_path);
392 
393  if (file2.is_open()) {
394  __parseStream(file2, file_path, module + "." + i.import().label());
395  imported = true;
396  break;
397  }
398  }
399 
400  if (!imported) {
401  const auto& pos = i.import().position();
402  std::stringstream msg;
403  msg << "Import error: could not resolve import " << i.import().label();
404  __errors.addError(msg.str(), pos.file(), pos.line(), pos.column());
405  }
406  }
407  }
408 
409  template < typename GUM_SCALAR >
410  INLINE std::vector< const O3Import* >
412  auto copy = std::vector< const O3Import* >();
413  for (const auto& i : __o3_prm->imports()) {
414  if (!__imported.exists(i->import().label())) { copy.push_back(i.get()); }
415  }
416  return copy;
417  }
418 
419  template < typename GUM_SCALAR >
420  INLINE void O3prmReader< GUM_SCALAR >::__readStream(std::istream& input,
421  const std::string& file,
422  std::string module) {
423  if (module.size() > 0 && module.back() != '.') { module.append("."); }
424 
425  __parseStream(input, file, module);
426 
427  auto imports = __copyImports();
428  do {
429  for (auto i : imports) {
430  __parseImport(*i, module);
431  }
432  imports = __copyImports();
433  } while (imports.size() > 0);
434 
435 
436  if (__errors.error_count == 0) {
437  auto solver = O3NameSolver< GUM_SCALAR >(*__prm, *__o3_prm, __errors);
438  auto type_factory =
439  O3TypeFactory< GUM_SCALAR >(*__prm, *__o3_prm, solver, __errors);
440 
441  auto interface_factory =
442  O3InterfaceFactory< GUM_SCALAR >(*__prm, *__o3_prm, solver, __errors);
443  auto class_factory =
444  O3ClassFactory< GUM_SCALAR >(*__prm, *__o3_prm, solver, __errors);
445 
446  auto system_factory =
447  O3SystemFactory< GUM_SCALAR >(*__prm, *__o3_prm, solver, __errors);
448 
449  try {
450  type_factory.build();
451  interface_factory.buildInterfaces();
452  class_factory.buildClasses();
453  interface_factory.buildElements();
454  class_factory.buildImplementations();
455  class_factory.buildParameters();
456  class_factory.buildReferenceSlots();
457  class_factory.declareAttributes();
458  class_factory.declareAggregates();
459  class_factory.completeAggregates();
460  class_factory.completeAttributes();
461  system_factory.build();
462  } catch (Exception&) {
463  if (__errors.count() == 0) {
464  __errors.addException("an unknown error occured", file);
465  }
466  // GUM_TRACE_NEWLINE;
467  // GUM_SHOWERROR( e );
468  } catch (...) {
469  __errors.addException("an unknown exception occured", file);
470  }
471  }
472  }
473  } // namespace o3prm
474  } // namespace prm
475 } // namespace gum
std::string __clean(std::string text) const
Builds gum::prm::PRMType from gum::prm::o3prm::O3Type, gum::prm::o3prm::O3IntType and gum::prm::o3prm...
Definition: O3TypeFactory.h:59
Cross-platform directory utility.
Definition: utils_dir.h:59
std::string msg
The gum::ParseError message.
O3Position & position()
Definition: O3prm.cpp:237
void __readStream(std::istream &input, const std::string &file, std::string module="")
gum::prm::o3prm::Parser o3prm_parser
#define GUM_SHOWERROR(e)
Definition: exceptions.h:58
std::string filename
The file of this gum::ParseError, default is "".
std::vector< std::string > __class_path
Definition: O3prmReader.h:146
STL namespace.
This class is used to represent parsing errors for the different parser implemented in aGrUM...
std::unique_ptr< O3PRM > __o3_prm
Definition: O3prmReader.h:145
gum::prm::o3prm::Scanner o3prm_scanner
This class is used contain and manipulate gum::ParseError.
gum is the global namespace for all aGrUM entities
Definition: agrum.h:25
The O3Import is part of the AST of the O3PRM language.
Definition: O3prm.h:866
Builds gum::prm::PRMSystem from gum::prm::o3prm::O3System.
This class read O3PRM files and creates the corresponding gum::prm::PRM.
Definition: O3prmReader.h:67
std::string & label()
Definition: O3prm.cpp:240
Bulds gum::prm:PRMInterface from gum::prm::o3prm::O3Interface.
Resolves names for the different O3PRM factories.
Definition: O3NameSolver.h:55
Headers for the O3prmReader class.
DatabaseTable readFile(const std::string &filename)
Idx line
The line of this gum::ParseError.
std::wstring widen(const std::string &str)
Cast a std::string into a std::wstring.
Base class for all aGrUM&#39;s exceptions.
Definition: exceptions.h:103
Builds gum::prm::Class from gum::prm::o3prm::O3Class.
Set< std::string > __imported
Definition: O3prmReader.h:147
This class represents a Probabilistic Relational PRMSystem<GUM_SCALAR>.
Definition: PRM.h:63
std::string __print(const ParseError &err) const
std::string absolutePath() const
Returns directory absolute path.
Definition: utils_dir.cpp:88
std::string replace(const std::string &s, const std::string &val, const std::string &new_val)
not usable for gcc 4.8 std::vector<std::string> split( const std::string& orig, const std::string& de...
Size Idx
Type for indexes.
Definition: types.h:50
The O3PRM is part of the AST of the O3PRM language.
Definition: O3prm.h:890
std::size_t Size
In aGrUM, hashed values are unsigned long int.
Definition: types.h:45
Idx column
The column of this gum::ParseError, default is 0.
const std::string errorContent() const
Returns the message content.
Definition: exceptions.h:132
PRM< GUM_SCALAR > * __prm
Definition: O3prmReader.h:144
#define GUM_ERROR(type, msg)
Definition: exceptions.h:52