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" || w ==
"seriesset")
137 else if (w ==
"polynomialset")
139 else if (w ==
"std::tuple")
153 res = std::make_shared<other>(w);
171 return genset_(
"char_letters");
176 std::shared_ptr<const genset>
genset_(std::string letter_type)
178 if (letter_type ==
"char" || letter_type ==
"string")
179 letter_type +=
"_letters";
185 while ((c =
is_.get()) != EOF && c !=
')')
191 require(c != EOF,
"unexpected end of file");
197 return std::make_shared<const genset>(letter_type, gens);
221 return std::make_shared<context>(ls, ws);
231 std::shared_ptr<ast_node>
labelset_(
const std::string& ls)
233 if (ls ==
"lal_char")
234 return std::make_shared<letterset>(
genset_(
"char_letters"));
235 else if (ls ==
"lan")
237 return std::make_shared<nullableset>(std::make_shared<letterset>
239 else if (ls ==
"lan_char")
240 return std::make_shared<nullableset>(std::make_shared<letterset>
242 else if (ls ==
"lao")
243 return std::make_shared<oneset>();
244 else if (ls ==
"lat")
246 else if (ls ==
"law_char")
247 return std::make_shared<wordset>(
genset_(
"char_letters"));
248 else if (ls ==
"lal" || ls ==
"letterset")
249 return std::make_shared<letterset>(
genset_());
250 else if (ls ==
"law" || ls ==
"wordset")
251 return std::make_shared<wordset>(
genset_());
252 else if (ls ==
"nullableset")
258 res = std::make_shared<nullableset>(
res);
261 else if (ls ==
"expressionset" || ls ==
"seriesset")
264 raise(
"invalid labelset name: ",
str_escape(ls));
277 return std::make_shared<weightset>(ws);
278 else if (ws ==
"expressionset" || ws ==
"seriesset")
280 else if (ws ==
"polynomialset")
282 else if (ws ==
"lat")
285 raise(
"invalid weightset name: ",
str_escape(ws));
297 auto res = std::shared_ptr<automaton>{};
299 if (prefix ==
"focus_automaton")
302 res = std::make_shared<automaton>(
prefix,
303 std::make_shared<other>(
word_()));
309 else if (prefix ==
"delay_automaton" 310 || prefix ==
"expression_automaton" 311 || prefix ==
"filter_automaton" 312 || prefix ==
"insplit_automaton" 313 || prefix ==
"lazy_proper_automaton" 314 || prefix ==
"name_automaton" 315 || prefix ==
"pair_automaton" 316 || prefix ==
"partition_automaton" 317 || prefix ==
"permutation_automaton" 318 || prefix ==
"scc_automaton" 319 || prefix ==
"synchronized_automaton" 320 || prefix ==
"transpose_automaton")
327 else if (prefix ==
"determinized_automaton")
332 res->get_content().emplace_back(
any_());
334 res->get_content().emplace_back(
any_());
338 else if (prefix ==
"mutable_automaton")
345 else if (prefix ==
"derived_term_automaton")
352 else if (prefix ==
"compose_automaton" 353 || prefix ==
"product_automaton" 354 || prefix ==
"tuple_automaton")
358 if (prefix !=
"tuple_automaton")
363 res = std::make_shared<automaton>(
prefix,
365 if (prefix !=
"tuple_automaton")
367 auto& c =
res->get_content();
368 c.insert(c.begin(), std::make_shared<other>(w));
370 while (
peek_() ==
',')
378 raise(
"invalid automaton name: ",
str_escape(prefix));
387 res.emplace_back(
any_());
388 while (
peek_() ==
',')
391 res.emplace_back(
any_());
394 return std::make_shared<tuple>(
res);
403 while (
peek_() ==
',')
409 return std::make_shared<tupleset>(
res);
423 require(w ==
"expressionset" || w ==
"seriesset",
424 "invalid expressionset type: ", w,
425 " expected expressionset or seriesset");
437 return std::make_shared<expressionset>(
context,
ids);
453 auto res = std::make_shared<polynomialset>(
context_());
469 else if (w ==
"expressionset" || w ==
"seriesset")
476 raise(
"invalid weightset or labelset name: " + w);
515 std::istringstream is{ctx};
521 catch (
const std::runtime_error& e)
523 raise(e,
" while reading context: ",
ctx);
529 std::istringstream is{type};
533 return parser.
parse();
535 catch (
const std::runtime_error& e)
537 raise(e,
" while reading type: ",
type);
std::set< std::string > weightsets_
The set of terminal weightset names.
ATTRIBUTE_PURE bool has(const boost::container::flat_set< Key, Compare, Allocator > &s, const Key &e)
Whether e is member of s.
void skip_space(std::istream &is)
Ignore spaces.
Indentation relative functions.
std::shared_ptr< ast_node > weightset_()
<WeightSet>.
std::set< std::string > labelsets_
The set of weightset names.
std::shared_ptr< automaton > automaton_()
<Automaton> "<" <Context> ">".
std::shared_ptr< ast_node > labelset_()
<LabelSet>.
std::shared_ptr< tupleset > tupleset_()
"<" (<LabelSet> | <WeightSet> ",")+ ">".
std::shared_ptr< ast_node > parse_type(const std::string &type)
Parse a type, and return its AST.
std::shared_ptr< ast_node > parse()
Accept anything.
std::shared_ptr< automaton > automaton_(std::string prefix)
<Automaton> "<" <Context> ">".
std::shared_ptr< expressionset > expressionset_(const std::string &w)
"expressionset" "<" <Context> ">", possibly followed by identities.
std::shared_ptr< ast_node > labelset_or_weightset_(const std::string &w)
<LabelSet> | <WeightSet>
void check_eof_(std::shared_ptr< ast_node > res)
We managed to read res in is, check that is_ is finished.
std::vector< std::shared_ptr< ast_node > > value_t
An expressionset can implement several different sets of identities on expressions.
std::shared_ptr< ast_node > labelset_or_weightset_()
<LabelSet> | <WeightSet>
std::shared_ptr< const genset > genset_(std::string letter_type)
A generator set (e.g., char_letters(abc) or char).
Linear plus distribution. Used for series identities.
std::shared_ptr< tuple > tuple_()
"<" (<Any> ",")* ">".
std::shared_ptr< expansionset > expansionset_()
"expansionset" "<" <Expressionset> ">".
std::shared_ptr< const genset > genset_()
An optional generator set in brackets (e.g., <char_letters(abc)> or <char>).
std::shared_ptr< ast_node > any_()
Accept anything.
static identities ids(const driver &d)
Get the identities of the driver.
std::istringstream & is_
The stream we are parsing.
std::shared_ptr< ast_node > weightset_(const std::string &ws)
<WeightSet>.
std::shared_ptr< polynomialset > polynomialset_()
"polynomialset" "<" <Context> ">".
std::ostream & str_escape(std::ostream &os, const std::string &str, const char *special=nullptr)
Output a string, escaping special characters.
std::shared_ptr< context > context_(std::string w)
<LabelSet>, <WeightSet>.
std::shared_ptr< context > context_()
<LabelSet>, <WeightSet>.
std::vector< std::shared_ptr< ast_node > > value_t
char eat_(char c)
Accept this character, possibly preceded by spaces.
std::string parameters_()
The next parameters in the stream.
std::shared_ptr< ast_node > labelset_(const std::string &ls)
<LabelSet>.
char eat(std::istream &is, char c)
Check lookahead character and advance.
const std::string & eat_(const std::string &s)
Accept this string, possibly preceded by spaces.
std::string type(const automaton &a)
The implementation type of a.
void require(Bool b, Args &&... args)
If b is not verified, raise an error with args as message.
context_parser(std::istringstream &is)
auto prefix(const Aut &aut) -> decltype(::vcsn::copy(aut))
std::string word_()
The next word in the stream.
std::shared_ptr< expressionset > expressionset_()
("expressionset"|"seriesset") "<" <Context> ">", possibly followed by identities. ...
ATTRIBUTE_NORETURN void fail_reading(std::istream &is, Args &&... args)
Throw an exception after failing to read from is.
int peek_()
The next character, possibly preceded by spaces.
std::shared_ptr< ast_node > parse_context()
Accept only a valid context.