Vcsn  2.0
Be Rational
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
context-parser.cc
Go to the documentation of this file.
3 
4 #include <vcsn/misc/escape.hh>
5 #include <vcsn/misc/indent.hh>
6 #include <vcsn/misc/raise.hh>
7 
8 namespace vcsn
9 {
10  namespace ast
11  {
12 
15  static void check_eof(std::istream& is, std::shared_ptr<ast_node> res)
16  {
17  if (is.peek() != -1)
18  {
19  std::ostringstream o;
20  signature_printer printer(o, true);
21  res->accept(printer);
23  "unexpected trailing characters after '" +
24  o.str() + "'");
25  }
26  }
27 
28  std::shared_ptr<ast_node> context_parser::parse()
29  {
30  auto res = any_();
31  check_eof(is_, res);
32  return res;
33  }
34 
35  std::shared_ptr<ast_node> context_parser::parse_context()
36  {
37  auto res = context_();
38  check_eof(is_, res);
39  return res;
40  }
41 
42  std::shared_ptr<ast_node> context_parser::any_()
43  {
44  std::string w = word_();
45  if (w == "blind_automaton"
46  || w == "determinized_automaton"
47  || w == "detweighted_automaton"
48  || w == "filter_automaton"
49  || w == "mutable_automaton"
50  || w == "pair_automaton"
51  || w == "partition_automaton"
52  || w == "permutation_automaton"
53  || w == "product_automaton"
54  || w == "ratexp_automaton"
55  || w == "transpose_automaton"
56  || w == "tuple_automaton")
57  return automaton_(w);
58  else if (has(labelsets_, w)
59  || w == "ratexpset"
60  || w == "seriesset")
61  {
62  std::shared_ptr<ast_node> res = labelset_(w);
63  if (is_.peek() == ',')
64  return context_(res);
65  return res;
66  }
67  else if (w == "lat")
68  {
69  std::shared_ptr<tupleset> res = tupleset_();
70  if (is_.peek() == ',')
71  return context_(res);
72  return res;
73  }
74  else if (has(weightsets_, w))
75  return weightset_(w);
76  else if (w == "polynomialset")
77  {
78  eat(is_, '<');
79  auto res = std::make_shared<polynomialset>(context_());
80  eat(is_, '>');
81  return res;
82  }
83  // std::integral_constant<unsigned, 2>.
84  else if (w == "std::integral_constant")
85  {
86  w += eat(is_, '<');
87  w += word_();
88  w += eat(is_, ',');
89  w += word_();
90  w += eat(is_, '>');
91  return std::make_shared<other>(w);
92  }
93  // std::vector<unsigned>.
94  else if (w == "const std::vector")
95  {
96  w += eat(is_, '<');
97  w += word_();
98  w += eat(is_, '>');
99  return std::make_shared<other>(w);
100  }
101  else
102  return std::make_shared<other>(w);
103  }
104 
105  std::shared_ptr<ast_node>
107  {
108  return labelset_or_weightset_(word_());
109  }
110 
111  std::shared_ptr<ast_node>
113  {
114  if (w == "lat")
115  return tupleset_();
116  else if (w == "ratexpset")
117  return ratexpset_();
118  else if (w == "seriesset")
119  return ratexpset_series_();
120  else if (has(labelsets_, w))
121  return labelset_(w);
122  else if (has(weightsets_, w))
123  return weightset_(w);
124  else
125  raise("invalid weightset or labelset name: " + w);
126  }
127 
128  std::string context_parser::word_()
129  {
130  std::string res;
131  int c;
132  while (is_.peek() == ' ')
133  is_.get();
134  while ((c = is_.get()) != EOF)
135  if (c == '<' || c == ',' || c == '>' || c == '(')
136  {
137  is_.unget();
138  break;
139  }
140  else
141  res += c;
142  return res;
143  }
144 
145  std::shared_ptr<const genset>
146  context_parser::genset_(const std::string& letter_type)
147  {
148  std::string gens;
149  if (is_.peek() == '(')
150  {
151  gens += '(';
152  int c = is_.get();
153  while ((c = is_.get()) != EOF)
154  {
155  gens += c;
156  if (c == ')')
157  break;
158  }
159  }
160  return std::make_shared<const genset>(letter_type, gens);
161  }
162 
163  std::shared_ptr<const genset> context_parser::genset_()
164  {
165  return genset_(word_());
166  }
167 
168  std::shared_ptr<context> context_parser::context_()
169  {
170  return context_(word_());
171  }
172 
173  std::shared_ptr<context>
174  context_parser::context_(const std::shared_ptr<ast_node>& ls)
175  {
176  eat(is_, ',');
177  while (isspace(is_.peek()))
178  is_.ignore();
179  return std::make_shared<context>(ls, weightset_());
180  }
181 
182  std::shared_ptr<context>
183  context_parser::context_(const std::string& word)
184  {
185  return context_(labelset_(word));
186  }
187 
188  std::shared_ptr<ast_node> context_parser::labelset_()
189  {
190  return labelset_(word_());
191  }
192 
193  std::shared_ptr<ast_node>
194  context_parser::labelset_(const std::string& ls)
195  {
196  if (ls == "lal_char")
197  return std::make_shared<letterset>(genset_("char_letters"));
198  else if (ls == "lan")
199  {
200  eat(is_, '<');
201  auto res = labelset_();
202  if (!res->has_one())
203  res = std::make_shared<nullableset>(res);
204  eat(is_, '>');
205  return res;
206  }
207  else if (ls == "lan_char")
208  return std::make_shared<nullableset>(std::make_shared<letterset>
209  (genset_("char_letters")));
210  else if (ls == "lao")
211  return std::make_shared<oneset>();
212  else if (ls == "lat")
213  return tupleset_();
214  else if (ls == "law_char")
215  return std::make_shared<wordset>(genset_("char_letters"));
216  else if (ls == "letterset")
217  {
218  eat(is_, '<');
219  auto gs = genset_();
220  eat(is_, '>');
221  return std::make_shared<letterset>(gs);
222  }
223  else if (ls == "wordset")
224  {
225  eat(is_, '<');
226  auto gs = genset_();
227  eat(is_, '>');
228  return std::make_shared<wordset>(gs);
229  }
230  else if (ls == "ratexpset")
231  return ratexpset_();
232  else if (ls == "seriesset")
233  return ratexpset_series_();
234  raise("invalid labelset name: ", str_escape(ls));
235  }
236 
237  std::shared_ptr<ast_node> context_parser::weightset_()
238  {
239  return weightset_(word_());
240  }
241 
242  std::shared_ptr<ast_node>
243  context_parser::weightset_(const std::string& ws)
244  {
245  if (has(weightsets_, ws))
246  return std::make_shared<weightset>(ws);
247  else if (ws == "ratexpset")
248  return ratexpset_();
249  else if (ws == "seriesset")
250  return ratexpset_series_();
251  else if (ws == "polynomialset")
252  return polynomialset_();
253  else if (ws == "lat")
254  return tupleset_();
255  else
256  raise("invalid weightset name: ", str_escape(ws));
257  }
258 
259  std::shared_ptr<automaton>
261  {
262  std::shared_ptr<automaton> res = nullptr;
263  // blind_automaton<TapeNum, Aut>.
264  if (prefix == "blind_automaton")
265  {
266  eat(is_, '<');
267  res = std::make_shared<automaton>(prefix,
268  std::make_shared<other>(word_()));
269  eat(is_, ',');
270  res->get_content().emplace_back(automaton_(word_()));
271  eat(is_, '>');
272  }
273  // xxx_automaton<Aut>.
274  else if (prefix == "determinized_automaton"
275  || prefix == "detweighted_automaton"
276  || prefix == "filter_automaton"
277  || prefix == "pair_automaton"
278  || prefix == "partition_automaton"
279  || prefix == "permutation_automaton"
280  || prefix == "ratexp_automaton"
281  || prefix == "transpose_automaton")
282  {
283  eat(is_, '<');
284  res = std::make_shared<automaton>(prefix,
285  automaton_(word_()));
286  eat(is_, '>');
287  }
288  // mutable_automaton<Context>.
289  else if (prefix == "mutable_automaton")
290  {
291  eat(is_, '<');
292  res = std::make_shared<automaton>(prefix,
293  context_());
294  eat(is_, '>');
295  }
296  // xxx_automaton<Aut...>.
297  else if (prefix == "product_automaton"
298  || prefix == "tuple_automaton")
299  {
300  eat(is_, '<');
301  res = std::make_shared<automaton>(prefix,
302  automaton_(word_()));
303  while (is_.peek() == ',')
304  {
305  eat(is_, ',');
306  res->get_content().emplace_back(automaton_(word_()));
307  }
308  eat(is_, '>');
309  }
310  else
311  raise("invalid automaton name: ", str_escape(prefix));
312  return res;
313  }
314 
315  std::shared_ptr<tupleset>
317  {
318  eat(is_, '<');
319  typename tupleset::value_t res;
320  res.emplace_back(labelset_or_weightset_());
321  while (is_.peek() == ',')
322  {
323  eat(is_, ',');
324  res.emplace_back(labelset_or_weightset_());
325  }
326  eat(is_, '>');
327  return std::make_shared<tupleset>(res);
328  }
329 
330  std::shared_ptr<ratexpset>
332  {
333  eat(is_, '<');
334  auto context = context_();
335  eat(is_, '>');
337  if (is_.peek() == '(')
338  {
339  eat(is_, '(');
340  is_ >> identities;
341  eat(is_, ')');
342  }
343  return std::make_shared<ratexpset>(context, identities);
344  }
345 
346  std::shared_ptr<ratexpset>
348  {
349  eat(is_, '<');
350  auto context = context_();
351  eat(is_, '>');
352  return std::make_shared<ratexpset>(context, rat::identities::series);
353  }
354 
355  std::shared_ptr<polynomialset> context_parser::polynomialset_()
356  {
357  eat(is_, '<');
358  auto res = std::make_shared<polynomialset>(context_());
359  eat(is_, '>');
360  return res;
361  }
362  }
363 }
static void check_eof(std::istream &is, std::shared_ptr< ast_node > res)
We managed to read res in is, check that is is finished.
std::shared_ptr< const genset > genset_()
A generator set (e.g., "char(abc)" or "char").
std::string word_()
Return the next word in the stream.
Indentation relative functions.
std::shared_ptr< tupleset > tupleset_()
std::shared_ptr< automaton > automaton_(std::string prefix)
"\<" "\>".
Trivial identities only.
std::shared_ptr< ast_node > any_()
Accept anything.
std::shared_ptr< ast_node > weightset_()
.
std::ostream & str_escape(std::ostream &os, const std::string &str)
Output a string, escaping special characters.
Definition: escape.cc:43
std::shared_ptr< ratexpset > ratexpset_series_()
std::set< std::string > weightsets_
The set of terminal weightset names.
std::shared_ptr< ast_node > labelset_or_weightset_()
|
Trivial identities plus series identities.
std::shared_ptr< ast_node > parse()
Accept anything.
std::set< std::string > labelsets_
The set of weightset names.
std::shared_ptr< context > context_()
, .
std::istringstream is
The input stream: the specification to translate.
Definition: translate.cc:329
std::shared_ptr< ratexpset > ratexpset_()
"ratexpset" "\<" "\>".
std::istringstream & is_
The stream we are parsing.
std::vector< std::shared_ptr< ast_node >> value_t
Definition: type-ast.hh:64
std::shared_ptr< const detail::context_base > context
Definition: context.hh:71
std::shared_ptr< polynomialset > polynomialset_()
"polynomialset" "\<" "\>".
char eat(std::istream &is, char c)
Check lookahead character and advance.
Definition: stream.cc:37
ATTRIBUTE_NORETURN void fail_reading(std::istream &is, std::string explanation)
Throw an exception after failing to read from is.
Definition: stream.cc:107
std::shared_ptr< ast_node > parse_context()
Accept only a valid context.
std::shared_ptr< ast_node > labelset_()
.
identities
A ratexpset can implement several different sets of identities on expressions.
Definition: identities.hh:17
bool has(const std::map< Key, Value, Compare, Alloc > &s, const Key &e)
Definition: map.hh:35
auto prefix(const Aut &aut) -> decltype(::vcsn::copy(aut))
Definition: prefix.hh:72