1 #include <boost/algorithm/string/predicate.hpp>
2 #include <boost/algorithm/string/trim.hpp>
26 std::shared_ptr<ast_node>
parse()
45 while (isspace(
is_.peek()))
64 const std::string&
eat_(
const std::string& s)
80 "unexpected trailing characters after '",
92 while ((c =
is_.peek()) != EOF)
93 if (c ==
'<' || c ==
',' || c ==
'>' || c ==
'(')
101 boost::algorithm::trim_right(res);
114 while ((c =
peek_()) != EOF)
118 else if (c ==
'>' && --nesting == 0)
128 std::shared_ptr<ast_node>
any_()
130 std::string w =
word_();
131 auto res = std::shared_ptr<ast_node>{};
132 if (boost::ends_with(w,
"_automaton"))
134 else if (w ==
"context")
136 else if (w ==
"expansionset")
138 else if (w ==
"expressionset")
144 else if (w ==
"polynomialset")
146 else if (w ==
"seriesset")
148 else if (w ==
"std::tuple")
162 res = std::make_shared<other>(w);
180 return genset_(
"char_letters");
185 std::shared_ptr<const genset>
genset_(std::string letter_type)
187 if (letter_type ==
"char" || letter_type ==
"string")
188 letter_type +=
"_letters";
194 while ((c =
is_.get()) != EOF && c !=
')')
200 require(c != EOF,
"unexpected end of file");
206 return std::make_shared<const genset>(letter_type, gens);
230 return std::make_shared<context>(ls, ws);
240 std::shared_ptr<ast_node>
labelset_(
const std::string& ls)
242 if (ls ==
"lal_char")
243 return std::make_shared<letterset>(
genset_(
"char_letters"));
244 else if (ls ==
"lan")
246 return std::make_shared<nullableset>(std::make_shared<letterset>
248 else if (ls ==
"lan_char")
249 return std::make_shared<nullableset>(std::make_shared<letterset>
251 else if (ls ==
"lao")
252 return std::make_shared<oneset>();
253 else if (ls ==
"lat")
255 else if (ls ==
"law_char")
256 return std::make_shared<wordset>(
genset_(
"char_letters"));
257 else if (ls ==
"lal" || ls ==
"letterset")
258 return std::make_shared<letterset>(
genset_());
259 else if (ls ==
"law" || ls ==
"wordset")
260 return std::make_shared<wordset>(
genset_());
261 else if (ls ==
"nullableset")
267 res = std::make_shared<nullableset>(
res);
270 else if (ls ==
"expressionset")
272 else if (ls ==
"seriesset")
275 raise(
"invalid labelset name: ",
str_escape(ls));
288 return std::make_shared<weightset>(ws);
289 else if (ws ==
"expressionset")
291 else if (ws ==
"seriesset")
293 else if (ws ==
"polynomialset")
295 else if (ws ==
"lat")
298 raise(
"invalid weightset name: ",
str_escape(ws));
310 auto res = std::shared_ptr<automaton>{};
312 if (prefix ==
"focus_automaton")
315 res = std::make_shared<automaton>(
prefix,
316 std::make_shared<other>(
word_()));
322 else if (prefix ==
"delay_automaton"
323 || prefix ==
"expression_automaton"
324 || prefix ==
"filter_automaton"
325 || prefix ==
"insplit_automaton"
326 || prefix ==
"lazy_proper_automaton"
327 || prefix ==
"name_automaton"
328 || prefix ==
"pair_automaton"
329 || prefix ==
"partition_automaton"
330 || prefix ==
"permutation_automaton"
331 || prefix ==
"scc_automaton"
332 || prefix ==
"synchronized_automaton"
333 || prefix ==
"transpose_automaton")
340 else if (prefix ==
"determinized_automaton")
345 res->get_content().emplace_back(
any_());
347 res->get_content().emplace_back(
any_());
351 else if (prefix ==
"mutable_automaton")
358 else if (prefix ==
"derived_term_automaton")
360 eat_(
"<expressionset");
365 else if (prefix ==
"compose_automaton"
366 || prefix ==
"product_automaton"
367 || prefix ==
"tuple_automaton")
371 if (prefix !=
"tuple_automaton")
376 res = std::make_shared<automaton>(
prefix,
378 if (prefix !=
"tuple_automaton")
380 auto& c =
res->get_content();
381 c.insert(c.begin(), std::make_shared<other>(w));
383 while (
peek_() ==
',')
391 raise(
"invalid automaton name: ",
str_escape(prefix));
400 res.emplace_back(
any_());
401 while (
peek_() ==
',')
404 res.emplace_back(
any_());
407 return std::make_shared<tuple>(
res);
416 while (
peek_() ==
',')
422 return std::make_shared<tupleset>(
res);
438 return std::make_shared<expressionset>(
context,
ids);
447 return std::make_shared<expressionset>(
context,
455 eat_(
"expressionset");
465 auto res = std::make_shared<polynomialset>(
context_());
481 else if (w ==
"expressionset")
483 else if (w ==
"seriesset")
490 raise(
"invalid weightset or labelset name: " + w);
529 std::istringstream is{ctx};
535 catch (
const std::runtime_error& e)
537 raise(e,
" while reading context: ",
ctx);
543 std::istringstream is{type};
547 return parser.
parse();
549 catch (
const std::runtime_error& e)
551 raise(e,
" while reading type: ",
type);
void skip_space_()
Skip white spaces.
std::string type(const automaton &a)
The implementation type of a.
std::vector< std::shared_ptr< ast_node >> value_t
std::shared_ptr< ast_node > parse()
Accept anything.
std::vector< std::shared_ptr< ast_node >> value_t
std::shared_ptr< ast_node > labelset_()
.
ATTRIBUTE_NORETURN void fail_reading(std::istream &is, Args &&...args)
Throw an exception after failing to read from is.
std::shared_ptr< expressionset > expressionset_()
"expressionset" "\<" "\>", possibly followed by identities.
std::ostream & str_escape(std::ostream &os, const std::string &str, const char *special=nullptr)
Output a string, escaping special characters.
const std::string & eat_(const std::string &s)
Accept this string, possibly preceded by spaces.
int peek_()
The next character, possibly preceded by spaces.
std::istringstream & is_
The stream we are parsing.
std::shared_ptr< const genset > genset_()
An optional generator set in brackets (e.g., or ).
std::shared_ptr< ast_node > any_()
Accept anything.
std::set< std::string > labelsets_
The set of weightset names.
std::shared_ptr< expansionset > expansionset_()
"expansionset" "\<" "\>".
void require(Bool b, Args &&...args)
If b is not verified, raise an error with args as message.
std::set< std::string > weightsets_
The set of terminal weightset names.
std::shared_ptr< automaton > automaton_(std::string prefix)
std::shared_ptr< ast_node > labelset_or_weightset_(const std::string &w)
|
std::shared_ptr< const genset > genset_(std::string letter_type)
A generator set (e.g., char_letters(abc) or char).
Traditional plus distribution. Used for series identities.
ATTRIBUTE_PURE bool has(const boost::container::flat_set< Key, Compare, Allocator > &s, const Key &e)
Whether e is member of s.
std::string word_()
The next word in the stream.
std::shared_ptr< ast_node > labelset_or_weightset_()
|
std::shared_ptr< ast_node > parse_type(const std::string &type)
Parse a type, and return its AST.
std::shared_ptr< ast_node > weightset_(const std::string &ws)
.
context_parser(std::istringstream &is)
std::shared_ptr< ast_node > labelset_(const std::string &ls)
.
std::shared_ptr< context > context_(std::string w)
, .
std::shared_ptr< tupleset > tupleset_()
"\<" ( | ",")+ "\>".
An expressionset can implement several different sets of identities on expressions.
Indentation relative functions.
std::shared_ptr< expressionset > seriesset_()
No optional argument.
void check_eof_(std::shared_ptr< ast_node > res)
We managed to read res in is, check that is_ is finished.
std::shared_ptr< context > context_()
, .
char eat_(char c)
Accept this character, possibly preceded by spaces.
auto prefix(const Aut &aut) -> decltype(::vcsn::copy(aut))
std::shared_ptr< polynomialset > polynomialset_()
"polynomialset" "\<" "\>".
std::shared_ptr< automaton > automaton_()
std::shared_ptr< tuple > tuple_()
std::string parameters_()
The next parameters in the stream.
static identities ids(const driver &d)
Get the identities of the driver.
std::shared_ptr< ast_node > parse_context(const std::string &ctx)
Parse a context, and return its AST.
std::shared_ptr< ast_node > weightset_()
.
std::shared_ptr< ast_node > parse_context()
Accept only a valid context.
char eat(std::istream &is, char c)
Check lookahead character and advance.