1 #include <boost/algorithm/string/predicate.hpp>
2 #include <boost/algorithm/string/trim.hpp>
26 std::shared_ptr<ast_node>
parse()
57 const std::string&
eat_(
const std::string& s)
73 "unexpected trailing characters after '",
85 while ((c =
is_.peek()) != EOF)
86 if (c ==
'<' || c ==
',' || c ==
'>' || c ==
'(')
94 boost::algorithm::trim_right(res);
107 while ((c =
peek_()) != EOF)
111 else if (c ==
'>' && --nesting == 0)
121 std::shared_ptr<ast_node>
any_()
123 std::string w =
word_();
124 auto res = std::shared_ptr<ast_node>{};
125 if (boost::ends_with(w,
"_automaton"))
127 else if (w ==
"context")
129 else if (w ==
"expansionset")
131 else if (w ==
"expressionset")
137 else if (w ==
"polynomialset")
139 else if (w ==
"seriesset")
141 else if (w ==
"std::tuple")
155 res = std::make_shared<other>(w);
173 return genset_(
"char_letters");
178 std::shared_ptr<const genset>
genset_(std::string letter_type)
180 if (letter_type ==
"char" || letter_type ==
"string")
181 letter_type +=
"_letters";
187 while ((c =
is_.get()) != EOF && c !=
')')
193 require(c != EOF,
"unexpected end of file");
199 return std::make_shared<const genset>(letter_type, gens);
223 return std::make_shared<context>(ls, ws);
233 std::shared_ptr<ast_node>
labelset_(
const std::string& ls)
235 if (ls ==
"lal_char")
236 return std::make_shared<letterset>(
genset_(
"char_letters"));
237 else if (ls ==
"lan")
239 return std::make_shared<nullableset>(std::make_shared<letterset>
241 else if (ls ==
"lan_char")
242 return std::make_shared<nullableset>(std::make_shared<letterset>
244 else if (ls ==
"lao")
245 return std::make_shared<oneset>();
246 else if (ls ==
"lat")
248 else if (ls ==
"law_char")
249 return std::make_shared<wordset>(
genset_(
"char_letters"));
250 else if (ls ==
"lal" || ls ==
"letterset")
251 return std::make_shared<letterset>(
genset_());
252 else if (ls ==
"law" || ls ==
"wordset")
253 return std::make_shared<wordset>(
genset_());
254 else if (ls ==
"nullableset")
260 res = std::make_shared<nullableset>(
res);
263 else if (ls ==
"expressionset")
265 else if (ls ==
"seriesset")
268 raise(
"invalid labelset name: ",
str_escape(ls));
281 return std::make_shared<weightset>(ws);
282 else if (ws ==
"expressionset")
284 else if (ws ==
"seriesset")
286 else if (ws ==
"polynomialset")
288 else if (ws ==
"lat")
291 raise(
"invalid weightset name: ",
str_escape(ws));
303 auto res = std::shared_ptr<automaton>{};
305 if (prefix ==
"focus_automaton")
308 res = std::make_shared<automaton>(
prefix,
309 std::make_shared<other>(
word_()));
315 else if (prefix ==
"delay_automaton"
316 || prefix ==
"expression_automaton"
317 || prefix ==
"filter_automaton"
318 || prefix ==
"insplit_automaton"
319 || prefix ==
"lazy_proper_automaton"
320 || prefix ==
"name_automaton"
321 || prefix ==
"pair_automaton"
322 || prefix ==
"partition_automaton"
323 || prefix ==
"permutation_automaton"
324 || prefix ==
"scc_automaton"
325 || prefix ==
"synchronized_automaton"
326 || prefix ==
"transpose_automaton")
333 else if (prefix ==
"determinized_automaton")
338 res->get_content().emplace_back(
any_());
340 res->get_content().emplace_back(
any_());
344 else if (prefix ==
"mutable_automaton")
351 else if (prefix ==
"derived_term_automaton")
353 eat_(
"<expressionset");
358 else if (prefix ==
"compose_automaton"
359 || prefix ==
"product_automaton"
360 || prefix ==
"tuple_automaton")
364 if (prefix !=
"tuple_automaton")
369 res = std::make_shared<automaton>(
prefix,
371 if (prefix !=
"tuple_automaton")
373 auto& c =
res->get_content();
374 c.insert(c.begin(), std::make_shared<other>(w));
376 while (
peek_() ==
',')
384 raise(
"invalid automaton name: ",
str_escape(prefix));
393 res.emplace_back(
any_());
394 while (
peek_() ==
',')
397 res.emplace_back(
any_());
400 return std::make_shared<tuple>(
res);
409 while (
peek_() ==
',')
415 return std::make_shared<tupleset>(
res);
431 return std::make_shared<expressionset>(
context,
ids);
440 return std::make_shared<expressionset>(
context,
448 eat_(
"expressionset");
458 auto res = std::make_shared<polynomialset>(
context_());
474 else if (w ==
"expressionset")
476 else if (w ==
"seriesset")
483 raise(
"invalid weightset or labelset name: " + w);
522 std::istringstream is{ctx};
528 catch (
const std::runtime_error& e)
530 raise(e,
" while reading context: ",
ctx);
536 std::istringstream is{type};
540 return parser.
parse();
542 catch (
const std::runtime_error& e)
544 raise(e,
" while reading type: ",
type);
auto prefix(const Aut &aut) -> decltype(::vcsn::copy(aut))
char eat(std::istream &is, char c)
Check lookahead character and advance.
std::shared_ptr< ast_node > parse()
Accept anything.
static identities ids(const driver &d)
Get the identities of the driver.
std::shared_ptr< ast_node > labelset_()
.
std::shared_ptr< expressionset > expressionset_()
"expressionset" "\<" "\>", possibly followed by identities.
Linear plus distribution. Used for series identities.
std::vector< std::shared_ptr< ast_node >> value_t
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 ).
void require(Bool b, Args &&...args)
If b is not verified, raise an error with args as message.
std::shared_ptr< ast_node > any_()
Accept anything.
std::set< std::string > labelsets_
The set of weightset names.
std::shared_ptr< expansionset > expansionset_()
"expansionset" "\<" "\>".
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).
std::string type(const automaton &a)
The implementation type of a.
std::vector< std::shared_ptr< ast_node >> value_t
std::string word_()
The next word in the stream.
std::shared_ptr< ast_node > labelset_or_weightset_()
|
std::shared_ptr< ast_node > parse_context(const std::string &ctx)
Parse a context, and return its AST.
std::shared_ptr< ast_node > parse_type(const std::string &type)
Parse a type, and return its AST.
void skip_space(std::istream &is)
Ignore spaces.
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_()
"\<" ( | ",")+ "\>".
std::ostream & str_escape(std::ostream &os, const std::string &str, const char *special=nullptr)
Output a string, escaping special characters.
std::shared_ptr< expressionset > seriesset_()
No optional argument.
An expressionset can implement several different sets of identities on expressions.
ATTRIBUTE_NORETURN void fail_reading(std::istream &is, Args &&...args)
Throw an exception after failing to read from is.
void check_eof_(std::shared_ptr< ast_node > res)
We managed to read res in is, check that is_ is finished.
Indentation relative functions.
std::shared_ptr< context > context_()
, .
char eat_(char c)
Accept this character, possibly preceded by spaces.
std::shared_ptr< polynomialset > polynomialset_()
"polynomialset" "\<" "\>".
std::shared_ptr< automaton > automaton_()
std::shared_ptr< tuple > tuple_()
ATTRIBUTE_PURE bool has(const boost::container::flat_set< Key, Compare, Allocator > &s, const Key &e)
Whether e is member of s.
std::string parameters_()
The next parameters in the stream.
std::shared_ptr< ast_node > weightset_()
.
std::shared_ptr< ast_node > parse_context()
Accept only a valid context.