Vaucanson  1.4.1
fmp.hxx
1 // fmp.hxx: this file is part of the Vaucanson project.
2 //
3 // Vaucanson, a generic library for finite state machines.
4 //
5 // Copyright (C) 2007, 2008, 2010 The Vaucanson Group.
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
11 //
12 // The complete GNU General Public Licence Notice can be found as the
13 // `COPYING' file in the root directory.
14 //
15 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
16 //
17 
18 #ifndef VCSN_XML_CONTEXTS_FMP_HXX
19 # define VCSN_XML_CONTEXTS_FMP_HXX
20 
21 # include <vaucanson/xml/builders.hh>
22 
23 namespace vcsn
24 {
25  namespace xml
26  {
30  template <typename T>
32  Handler& root,
33  T& monoid)
34  : Handler(parser, root),
35  monoid_(monoid),
36  unsuph_(parser, *this),
37  first_(true)
38  {
39  }
40 
41  template <typename T>
42  void
43  FreeMonoidProductHandler<T>::start (const XMLCh* const,
44  const XMLCh* const localname,
45  const XMLCh* const,
46  const xercesc::Attributes& attrs)
47  {
48  if (xercesc::XMLString::equals(eq_.monoid, localname))
49  {
50  if (first_)
51  {
52  monoidh_ = builders::create_monoidh(monoid_.first_monoid(), attrs, parser_, *this);
53  first_ = false;
54  }
55  else
56  {
57  delete monoidh_;
58  monoidh_ = builders::create_monoidh(monoid_.second_monoid(), attrs, parser_, *this);
59  }
60  parser_->setContentHandler(monoidh_);
61  }
62  else if (xercesc::XMLString::equals(eq_.writingData, localname))
63  {
64  algebra::MonoidRep<T> rep;
65  if (tools::has_attribute(attrs, eq_.identitySymbol))
66  rep.empty = xmlstr(tools::get_attribute(attrs, eq_.identitySymbol));
67  if (tools::has_attribute(attrs, eq_.concat))
68  rep.concat = xmlstr(tools::get_attribute(attrs, eq_.concat));
69  monoid_.set_representation(rep);
70  parser_->setContentHandler(&unsuph_);
71  }
72  else
73  error::token(localname);
74  }
75 
76  template <typename T>
77  void
78  FreeMonoidProductHandler<T>::end (const XMLCh* const,
79  const XMLCh* const localname,
80  const XMLCh* const)
81  {
82  delete monoidh_;
83  if (xercesc::XMLString::equals(eq_.monoid, localname))
84  parser_->setContentHandler(&root_);
85  else
86  error::token(localname);
87  }
88 
92  template <typename S, typename M1, typename M2>
94  SeriesRepresentationHandler(xercesc::SAX2XMLReader* parser,
95  Handler& root,
96  FMPsreptype& srep)
97  : Handler(parser, root),
98  rep_(srep),
99  reph_(0),
100  unsuph_(parser, *this),
101  first_(true)
102  {
103  }
104 
105  template <typename S, typename M1, typename M2>
106  void
108  const XMLCh* const localname,
109  const XMLCh* const,
110  const xercesc::Attributes& attrs)
111  {
112  if (xercesc::XMLString::equals(eq_.writingData, localname))
113  {
114  if (first_)
115  {
116  reph_ = builders::create_series_representationh(rep_.first_representation(), attrs, parser_, *this, eq_);
117  first_ = false;
118  }
119  else
120  {
121  delete reph_;
122  reph_ = builders::create_series_representationh(rep_.second_representation(), attrs, parser_, *this, eq_);
123  }
124  parser_->setContentHandler(reph_);
125  }
126  else
127  error::token(localname);
128  }
129 
130  template <typename S, typename M1, typename M2>
131  void
132  SeriesRepresentationHandler<FMPsreptype>::end(const XMLCh* const,
133  const XMLCh* const localname,
134  const XMLCh* const)
135  {
136  using namespace xercesc;
137 
138  delete reph_;
139  if (XMLString::equals(eq_.writingData, localname))
140  parser_->setContentHandler(&root_);
141  else
142  error::token(localname);
143  }
144 
145  namespace builders
146  {
147  TParamFMP
148  typename FMPtype::monoid_t*
149  create_monoid (FMPtype& param,
150  const XMLCh* const localname,
151  const xercesc::Attributes& attrs,
152  XMLEq& eq)
153  {
154  typename FMPtype::monoid_t::first_monoid_t::alphabet_t at1;
155  typename FMPtype::monoid_t::second_monoid_t::alphabet_t at2;
156  typename FMPtype::monoid_t::first_monoid_t md1(at1);
157  typename FMPtype::monoid_t::second_monoid_t md2(at2);
158  typedef typename FMPtype::monoid_t monoid_t;
159 
160  monoid_t* monoid = new monoid_t(md1, md2);
161  builders::check_monoid_consistency(param, localname, attrs, eq);
162  return monoid;
163  }
164 
165  template <typename M1, typename M2>
166  Handler*
167  create_monoidh (vcsn::algebra::FreeMonoidProduct<M1, M2>& monoid,
168  const xercesc::Attributes&,
169  xercesc::SAX2XMLReader* parser,
170  Handler& root)
171  {
172  typedef typename vcsn::algebra::FreeMonoidProduct<M1, M2> monoid_t;
173  return new FreeMonoidProductHandler<monoid_t>(parser, root, monoid);
174  }
175  } // !builders
176 
177  /*
178  * ProdMonElmtHandler
179  */
180  template <typename T>
181  ProdMonElmtHandler<T>::ProdMonElmtHandler (xercesc::SAX2XMLReader* parser,
182  Handler& root,
183  T param)
184  : RegexpHandler<T>(parser, root, param),
185  in_(1),
186  count_(1),
187  m1_(param.structure().monoid().first_monoid()),
188  m2_(param.structure().monoid().second_monoid())
189  {
190  end_ = eq_.monElmt;
191  }
192 
193  template <typename T>
194  void
195  ProdMonElmtHandler<T>::start(const XMLCh* const,
196  const XMLCh* const localname,
197  const XMLCh* const,
198  const xercesc::Attributes& attrs)
199  {
200  using namespace xercesc;
201 
202  typedef typename T::set_t::monoid_t monoid_t;
203  typedef typename monoid_t::first_monoid_t first_monoid_t;
204  typedef typename monoid_t::second_monoid_t second_monoid_t;
205  typedef typename first_monoid_t::alphabet_t first_alphabet_t;
206  typedef typename second_monoid_t::alphabet_t second_alphabet_t;
207  typedef typename first_alphabet_t::letter_t first_letter_t;
208  typedef typename second_alphabet_t::letter_t second_letter_t;
209 
210  if (XMLString::equals(eq_.monElmt, localname))
211  {
212  in_++;
213  count_++;
214  if (in_ > 2)
215  error::token(localname);
216  }
217  else if (XMLString::equals(eq_.one, localname) && (in_ == 1))
218  {
219  in_++;
220  count_++;
221  if (count_ == 2)
222  m1_ = algebra::identity_as<typename T::monoid_elt_t::first_monoid_elt_value_t>
223  ::of(param_.structure().monoid().first_monoid());
224  else if (count_ == 3)
225  m2_ = algebra::identity_as<typename T::monoid_elt_t::second_monoid_elt_value_t>
226  ::of(param_.structure().monoid().second_monoid());
227  else
228  error::token(localname);
229  }
230  else if (XMLString::equals(eq_.monGen, localname))
231  {
232  const std::string val(xmlstr(tools::get_attribute(attrs, "value")));
233  if (in_ == 2 && count_ == 2)
234  {
235  std::pair<bool, first_letter_t> tmp =
236  parse_letter(m1_.structure().alphabet(), val);
237  if (tmp.first)
238  m1_ *= tmp.second;
239  else
240  error::attrs(localname, "value", val);
241  }
242  else if (in_ == 2 && count_ == 3)
243  {
244  std::pair<bool, second_letter_t> tmp =
245  parse_letter(m2_.structure().alphabet(), val);
246  if (tmp.first)
247  m2_ *= tmp.second;
248  else
249  error::attrs(localname, "value", val);
250  }
251  else
252  error::token(localname);
253  }
254  else
255  error::token(localname);
256  }
257 
258  template <typename T>
259  void
260  ProdMonElmtHandler<T>::end (const XMLCh* const,
261  const XMLCh* const localname,
262  const XMLCh* const)
263  {
264  using namespace xercesc;
265  if (XMLString::equals(end_, localname))
266  {
267  if (in_ == 1 && count_ == 3)
268  {
269  // FIXME awful... but didn't find an easier way.
270  typename T::monoid_elt_value_t m(m1_.value(), m2_.value());
271  typename T::semiring_elt_value_t w =
272  algebra::identity_as<typename T::semiring_elt_value_t>::of(param_.structure().semiring()).value();
273  param_.assoc(m, w);
274  parser_->setContentHandler(&root_);
275  }
276  in_--;
277  }
278  else if (XMLString::equals(eq_.one, localname))
279  in_--;
280  else if (!XMLString::equals(eq_.monGen, localname))
281  error::token(localname);
282  }
283 
284 
285  namespace builders
286  {
287  SParamFMP
288  RegexpHandler<FMPseries >*
289  create_monElmth(xercesc::SAX2XMLReader* parser,
290  RegexpHandler<FMPseries >& root,
291  FMPseries param)
292  {
293  return new ProdMonElmtHandler<FMPseries >(parser, root,
294  algebra::zero_as<typename FMPseries::value_t>::of(param.structure()));
295  }
296  } // !builders
297 
301  namespace builders
302  {
303  TParamFMP
304  void
305  check_monoid_consistency (FMPtype&,
306  const XMLCh* const localname,
307  const xercesc::Attributes& attrs,
308  XMLEq&)
309  {
310  std::string val(xmlstr(tools::get_attribute(attrs, "type")));
311  if (val != "product")
312  error::attrs(localname, "type", val);
313  val = xmlstr(tools::get_attribute(attrs, "prodDim"));
314  if (val != "2")
315  error::attrs(localname, "prodDim", val);
316  };
317  } // !builders
318 
322  namespace builders
323  {
324 
325 
326  template <typename S>
327  void
328  do_create_type_writingData_node(const S& s,
329  xercesc::DOMDocument* doc,
330  xercesc::DOMElement* root)
331  {
332  xercesc::DOMElement* writingData = tools::create_element(doc, "writingData");
333  tools::set_attribute(writingData, "plusSym", s.representation()->plus);
334  tools::set_attribute(writingData, "timesSym", s.representation()->times);
335  tools::set_attribute(writingData, "starSym", s.representation()->star);
336  tools::set_attribute(writingData, "zeroSym", s.representation()->zero);
337  tools::set_attribute(writingData, "weightOpening", s.representation()->open_weight);
338  tools::set_attribute(writingData, "weightClosing", s.representation()->close_weight);
339  tools::set_attribute(writingData, "openPar", s.representation()->open_par);
340  tools::set_attribute(writingData, "closePar", s.representation()->close_par);
341  tools::set_attribute(writingData, "spacesSym", s.representation()->spaces.front());
342 
343  xercesc::DOMElement* firstWritingData = tools::create_element(doc, "writingData");
344  tools::set_attribute(firstWritingData, "plusSym",
345  s.representation()->first_representation().plus);
346  tools::set_attribute(firstWritingData, "timesSym",
347  s.representation()->first_representation().times);
348  tools::set_attribute(firstWritingData, "starSym",
349  s.representation()->first_representation().star);
350  tools::set_attribute(firstWritingData, "zeroSym",
351  s.representation()->first_representation().zero);
352  tools::set_attribute(firstWritingData, "weightOpening",
353  s.representation()->first_representation().open_weight);
354  tools::set_attribute(firstWritingData, "weightClosing",
355  s.representation()->first_representation().close_weight);
356  tools::set_attribute(firstWritingData, "openPar",
357  s.representation()->first_representation().open_par);
358  tools::set_attribute(firstWritingData, "closePar",
359  s.representation()->first_representation().close_par);
360  tools::set_attribute(firstWritingData, "spacesSym",
361  s.representation()->first_representation().spaces.front());
362  writingData->appendChild(firstWritingData);
363 
364  xercesc::DOMElement* secondWritingData = tools::create_element(doc, "writingData");
365  tools::set_attribute(secondWritingData, "plusSym",
366  s.representation()->second_representation().plus);
367  tools::set_attribute(secondWritingData, "timesSym",
368  s.representation()->second_representation().times);
369  tools::set_attribute(secondWritingData, "starSym",
370  s.representation()->second_representation().star);
371  tools::set_attribute(secondWritingData, "zeroSym",
372  s.representation()->second_representation().zero);
373  tools::set_attribute(secondWritingData, "weightOpening",
374  s.representation()->second_representation().open_weight);
375  tools::set_attribute(secondWritingData, "weightClosing",
376  s.representation()->second_representation().close_weight);
377  tools::set_attribute(secondWritingData, "openPar",
378  s.representation()->second_representation().open_par);
379  tools::set_attribute(secondWritingData, "closePar",
380  s.representation()->second_representation().close_par);
381  tools::set_attribute(secondWritingData, "spacesSym",
382  s.representation()->second_representation().spaces.front());
383  writingData->appendChild(secondWritingData);
384 
385  root->appendChild(writingData);
386  }
387 
388  TParamFMP
389  void
390  create_type_writingData_node(const FMPtype& aut,
391  xercesc::DOMDocument* doc,
392  xercesc::DOMElement* root)
393  {
394  do_create_type_writingData_node(aut.series(), doc, root);
395  }
396 
397  TParamFMP
398  void
399  create_type_writingData_node(const FMPseries& s,
400  xercesc::DOMDocument* doc,
401  xercesc::DOMElement* root)
402  {
403  do_create_type_writingData_node(s.series(), doc, root);
404  }
405 
406  TParamFMP
407  void
408  do_create_monoid_node(const vcsn::algebra::Series<S, vcsn::algebra::FreeMonoidProduct<M1, M2> >& s,
409  xercesc::DOMDocument* doc,
410  xercesc::DOMElement* root)
411  {
412  xercesc::DOMElement* node = tools::create_element(doc, "monoid");
413  tools::set_attribute(node, "type", "product");
414  tools::set_attribute(node, "prodDim", "2");
415  root->appendChild(node);
416 
417  xercesc::DOMElement* writingData = tools::create_element(doc, "writingData");
418  tools::set_attribute(writingData, "identitySym", s.monoid().representation()->empty);
419  tools::set_attribute(writingData, "timesSym", s.monoid().representation()->concat);
420  node->appendChild(writingData);
421 
422  xercesc::DOMElement* first = tools::create_element(doc, "monoid");
423  tools::set_attribute(first, "type", "free");
424  tools::set_attribute(first, "genDescrip", "enum");
425  tools::set_attribute(first, "genKind", algebra::letter_traits<typename M1::alphabet_t::letter_t>::kind());
426  node->appendChild(first);
427 
428  xercesc::DOMElement* writingData1 = tools::create_element(doc, "writingData");
429  tools::set_attribute(writingData1, "identitySym", s.monoid().first_monoid().representation()->empty);
430  tools::set_attribute(writingData1, "timesSym", s.monoid().first_monoid().representation()->concat);
431  first->appendChild(writingData1);
432 
433  typedef typename M1::alphabet_t::const_iterator first_alphabet_iterator;
434  for_all_letters_(first_, l, s.monoid().first_monoid().alphabet())
435  {
436  std::ostringstream letter;
437  xercesc::DOMElement* gen = tools::create_element(doc, "monGen");
438  letter << *l;
439  tools::set_attribute(gen, "value", letter.str());
440  first->appendChild(gen);
441  }
442  tools::set_attribute(first, "genSort", get_monoid_gen_sort(*(s.monoid().first_monoid().alphabet().begin())));
443  xercesc::DOMElement* second = tools::create_element(doc, "monoid");
444  tools::set_attribute(second, "type", "free");
445  tools::set_attribute(second, "genDescrip", "enum");
446  tools::set_attribute(second, "genKind", algebra::letter_traits<typename M2::alphabet_t::letter_t>::kind());
447  node->appendChild(second);
448 
449  xercesc::DOMElement* writingData2 = tools::create_element(doc, "writingData");
450  tools::set_attribute(writingData2, "identitySym", s.monoid().second_monoid().representation()->empty);
451  tools::set_attribute(writingData2, "timesSym", s.monoid().second_monoid().representation()->concat);
452  second->appendChild(writingData2);
453 
454  typedef typename M2::alphabet_t::const_iterator second_alphabet_iterator;
455  for_all_letters_(second_, l, s.monoid().second_monoid().alphabet())
456  {
457  std::ostringstream letter;
458  xercesc::DOMElement* gen = tools::create_element(doc, "monGen");
459  letter << *l;
460  tools::set_attribute(gen, "value", letter.str());
461  second->appendChild(gen);
462  }
463  tools::set_attribute(second, "genSort", get_monoid_gen_sort(*(s.monoid().second_monoid().alphabet().begin())));
464  }
465 
466  TParamFMP
467  void
468  create_monoid_node(const FMPtype& aut,
469  xercesc::DOMDocument* doc,
470  xercesc::DOMElement* root)
471  {
472  do_create_monoid_node<S,T,M1,M2>(aut.series(), doc, root);
473  }
474 
475  TParamFMP
476  void
477  create_monoid_node(const FMPseries& s,
478  xercesc::DOMDocument* doc,
479  xercesc::DOMElement* root)
480  {
481  do_create_monoid_node<S,T,M1,M2>(s.series(), doc, root);
482  }
483 
484 
485 
486  /* FIXME there should not be 2 but one function here... however,
487  ** when we add a template T instead of int the function is not called
488  ** anymore... there is a probleme in the dispatch */
489  template <>
490  void
491  create_monElmt_node(const std::pair<std::string, std::string>& m,
492  xercesc::DOMDocument* doc,
493  xercesc::DOMElement* root)
494  {
495  xercesc::DOMElement* node;
496  if (m.first.empty() && m.second.empty())
497  node = tools::create_element(doc, "one");
498  else
499  {
500  node = tools::create_element(doc, "monElmt");
501  create_monElmt_node(m.first, doc, node);
502  create_monElmt_node(m.second, doc, node);
503  }
504  root->appendChild(node);
505  }
506 
507  template <>
508  void
509  create_monElmt_node(const std::pair<std::basic_string<int>, std::basic_string<int> >& m,
510  xercesc::DOMDocument* doc,
511  xercesc::DOMElement* root)
512  {
513  xercesc::DOMElement* node;
514  if (m.first.empty() && m.second.empty())
515  node = tools::create_element(doc, "one");
516  else
517  {
518  node = tools::create_element(doc, "monElmt");
519  create_monElmt_node(m.first, doc, node);
520  create_monElmt_node(m.second, doc, node);
521  }
522  root->appendChild(node);
523  }
524  } // !builders
525  } // !xml
526 } // !vcsn
527 
528 #endif // !VCSN_XML_CONTEXTS_FMP_HXX