Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
context-printer.cc
Go to the documentation of this file.
2 
3 #include <boost/algorithm/string.hpp>
4 
5 #include <vcsn/dyn/type-ast.hh>
6 #include <vcsn/misc/indent.hh>
7 #include <vcsn/misc/raise.hh>
8 
9 
10 namespace vcsn
11 {
12  namespace ast
13  {
14 
15  void context_printer::header_algo(const std::string& algo)
16  {
17  // We use '-' instead of '_' in header file names.
18  auto h = boost::replace_all_copy(algo, "_", "-");
19  // We don't use any suffix in the file names.
20  for (auto s: {"-automaton",
21  "-ctx",
22  "-expansion", "-label", "-polynomial",
23  "-ratexp", "-vector", "-weight"})
24  if (boost::ends_with(h, s))
25  boost::erase_tail(h, strlen(s));
26  // Open code some mismatches between algo name, and header name.
27  //
28  // FIXME: algorithms should register this themselves.
29  if (false) {}
30 #define ALGO(In, Out) \
31  else if (h == In) \
32  h = Out
33  ALGO("ambiguous-word", "is-ambiguous");
34  ALGO("chain", "concatenate");
35  ALGO("coaccessible", "accessible");
36  ALGO("codeterminize", "determinize");
37  ALGO("cominimize", "minimize");
38  ALGO("conjunction", "product");
39  ALGO("context-of", "make-context");
40  ALGO("copy-convert", "copy");
41  ALGO("costandard", "standard");
42  ALGO("difference", "are-equivalent");
43  ALGO("eliminate-state", "to-expression");
44  ALGO("factor", "prefix");
45  ALGO("infiltration", "product");
46  ALGO("is-accessible", "accessible");
47  ALGO("is-coaccessible", "accessible");
48  ALGO("is-codeterministic", "is-deterministic");
49  ALGO("is-costandard", "standard");
50  ALGO("is-cycle-ambiguous", "is-ambiguous");
51  ALGO("is-empty", "accessible");
52  ALGO("is-normalized", "normalize");
53  ALGO("is-out-sorted", "sort");
54  ALGO("is-standard", "standard");
55  ALGO("is-synchronized-by", "synchronizing-word");
56  ALGO("is-trim", "accessible");
57  ALGO("is-useless", "accessible");
58  ALGO("list", "print");
59  ALGO("make-ratexpset", "make-context");
60  ALGO("make-word-context", "make-context");
61  ALGO("multiply", "concatenate");
62  ALGO("num-sccs", "scc");
63  ALGO("pair", "synchronizing-word");
64  ALGO("power", "product");
65  ALGO("right-mult", "left-mult");
66  ALGO("shortest", "enumerate");
67  ALGO("shuffle", "product");
68  ALGO("subword", "prefix");
69  ALGO("suffix", "prefix");
70  ALGO("trim", "accessible");
71  ALGO("union-a", "union");
72 #undef ALGO
73  // Exceptions.
74  if (algo == "is_valid_ratexp")
75  h = "is-valid-ratexp";
76 
77  h = "vcsn/algos/" + h + ".hh";
78  headers_late_.insert(h);
79  }
80 
81  void context_printer::header(const std::string& h)
82  {
83  headers_.insert(h);
84  }
85 
86  void context_printer::linkflags(const std::string& flags)
87  {
88  // We rely on this initial space when not empty.
89  linkflags_ += ' ';
90  linkflags_ += flags;
91  }
92 
93  const std::string& context_printer::linkflags() const
94  {
95  return linkflags_;
96  }
97 
98  std::ostream& context_printer::print(std::ostream& o)
99  {
100  //o << "// " << is.str() << "\n";
101  o <<
102  "#define BUILD_LIBVCSN 1\n"
103  "#define VCSN_INSTANTIATION 1\n"
104  "#define MAYBE_EXTERN\n"
105  "\n";
106  for (const auto& h: headers_)
107  o << "#include <" << h << ">\n";
108  o << '\n';
109  for (const auto& h: headers_late_)
110  o << "#include <" << h << ">\n";
111  o << "\n"
112  << os_.str();
113  return o;
114  }
115 
116 #define DEFINE(Type) \
117  void context_printer::visit(const Type& t)
118 
120  {
121  auto type = t.get_type();
122  if (type == "blind_automaton")
123  header("vcsn/algos/blind.hh");
124  else if (type == "determinized_automaton")
125  header("vcsn/algos/determinize.hh");
126  else if (type == "detweighted_automaton")
127  header("vcsn/algos/determinize.hh");
128  else if (type == "filter_automaton")
129  header("vcsn/algos/filter.hh");
130  else if (type == "mutable_automaton")
131  header("vcsn/core/mutable-automaton.hh");
132  else if (type == "pair_automaton")
133  header("vcsn/algos/synchronizing-word.hh");
134  else if (type == "partition_automaton")
135  header("vcsn/core/partition-automaton.hh");
136  else if (type == "product_automaton")
137  header("vcsn/algos/product.hh");
138  else if (type == "permutation_automaton")
139  header("vcsn/core/permutation-automaton.hh");
140  else if (type == "ratexp_automaton")
141  header("vcsn/core/ratexp-automaton.hh");
142  else if (type == "transpose_automaton")
143  header("vcsn/algos/transpose.hh");
144  else if (type == "tuple_automaton")
145  header("vcsn/core/tuple-automaton.hh");
146  else
147  raise("unsupported automaton type: ", type);
148 
149  os_ << "vcsn::" << type << '<' << incendl;
150  bool first = true;
151  for (auto c: t.get_content())
152  {
153  if (!first)
154  os_ << ',' << iendl;
155  first = false;
156  c->accept(*this);
157  }
158  os_ << decendl << '>';
159  }
160 
161  DEFINE(context)
162  {
163  header("vcsn/ctx/context.hh");
164  os_ << "vcsn::context<" << incendl;
165  t.get_labelset()->accept(*this);
166  os_ << ',' << iendl;
167  t.get_weightset()->accept(*this);
168  os_ << decendl << '>';
169  }
170 
171  DEFINE(tupleset)
172  {
173  headers_late_.insert("vcsn/labelset/tupleset.hh");
174  os_ << "vcsn::tupleset<" << incendl;
175  bool first = true;
176  for (auto v: t.get_sets())
177  {
178  if (!first)
179  os_ << ',' << iendl;
180  first = false;
181  v->accept(*this);
182  }
183  os_ << decendl << '>';
184  }
185 
186 
187  DEFINE(nullableset)
188  {
189  header("vcsn/labelset/nullableset.hh");
190  os_ << "vcsn::nullableset<" << incendl;
191  t.get_labelset()->accept(*this);
192  os_ << decendl << ">";
193  }
194 
195  DEFINE(oneset)
196  {
197  (void) t;
198  header("vcsn/labelset/oneset.hh");
199  os_ << "vcsn::oneset";
200  }
201 
202  DEFINE(genset)
203  {
204  header("vcsn/alphabets/setalpha.hh"); // set_alphabet
205  if (t.letter_type() == "char_letters")
206  header("vcsn/alphabets/char.hh");
207  os_ << "vcsn::set_alphabet<vcsn::" << t.letter_type() << '>';
208  }
209 
210  DEFINE(letterset)
211  {
212  header("vcsn/labelset/letterset.hh");
213  os_ << "vcsn::letterset<";
214  t.genset()->accept(*this);
215  os_ << '>';
216  }
217 
218  DEFINE(ratexpset)
219  {
220  os_ << "vcsn::ratexpset<" << incendl;
221  t.get_context()->accept(*this);
222  os_ << decendl << '>';
223  header("vcsn/core/rat/ratexpset.hh");
224  }
225 
226  DEFINE(weightset)
227  {
228  header("vcsn/weightset/" + t.get_type() + ".hh");
229  if (t.get_type() == "qmp")
230  linkflags("-lgmp -lgmpxx");
231  os_ << "vcsn::" << t.get_type();
232  }
233 
234  DEFINE(wordset)
235  {
236  header("vcsn/labelset/wordset.hh");
237  os_ << "vcsn::wordset<";
238  t.genset()->accept(*this);
239  os_ << '>';
240  }
241 
242  DEFINE(other)
243  {
244  os_ << t.get_type();
245  }
246 
247  DEFINE(polynomialset)
248  {
249  os_ << "vcsn::polynomialset<" << incendl;
250  t.get_content()->accept(*this);
251  os_ << decendl << '>';
252  header("vcsn/weightset/polynomialset.hh");
253  }
254 #undef DEFINE
255  }
256 }
std::ostream & iendl(std::ostream &o)
Print an end of line, then set the indentation.
Definition: indent.cc:49
std::ostream & print(std::ostream &o)
Generate the code to compile on o.
std::set< std::string > headers_
Headers to include.
Indentation relative functions.
const std::string & linkflags() const
Get the link flags.
#define DEFINE(Type)
std::ostream & incendl(std::ostream &o)
Increment the indentation, print an end of line, and set the indentation.
Definition: indent.cc:54
std::string linkflags_
Flags to pass to the linker.
#define ALGO(In, Out)
std::ostringstream & os_
void header(const std::string &h)
Record that we need an include for this header.
void header_algo(const std::string &algo)
Record that we need an include for this algorithm.
std::set< std::string > headers_late_