4 #include <boost/algorithm/string/predicate.hpp> 5 #include <boost/algorithm/string/trim.hpp> 26 std::string read_context(std::string& line)
29 static auto re = std::regex(
"^[ \t]*(?:vcsn_)?(?:context|ctx)[ \t]*=" 30 "[ \t]*(\"?)(.*?)\\1[ \t]*(?://.*)?$");
32 static auto sub = std::regex(
"\\\\\\\\");
34 if (std::regex_match(line, m, re))
36 std::string
res = m[2];
38 res = std::regex_replace(res, sub,
"\\");
46 string_t read_quotes(std::istream& is)
48 auto res = std::string{};
50 while ((c = is.peek()) != EOF && c !=
'"')
53 raise(
"invalid daut file: missing '\"' after '",
res,
"'");
60 bool is_comment(std::istream& is,
char c)
62 if (c ==
'/' && is.peek() ==
'/')
72 string_t read_state(std::istream& is)
74 auto res = std::string{};
77 while ((c = is.get()) != EOF)
81 if ((c = is.get()) != EOF)
86 return read_quotes(is);
88 else if (c ==
'-' && is.peek() ==
'>')
99 else if (std::isalnum(c)
100 || c ==
'_' || c ==
'-' || c ==
'.' || c ==
'$')
108 boost::algorithm::trim_right(
res);
113 string_t read_entry(std::istream& is)
115 auto res = std::string{};
118 while ((c = is.get()) != EOF)
120 if (isspace(c) &&
res.empty())
122 if (is_comment(is, c))
136 res->set_separator(
',');
149 auto edit = std::shared_ptr<vcsn::automaton_editor>{};
152 auto line = std::string{};
157 std::getline(is, line,
'\n');
160 boost::algorithm::trim_right(line);
161 if (line.empty() || boost::starts_with(line,
"//"))
166 auto ctx = read_context(line);
169 edit.reset(make_editor(ctx));
171 catch (
const std::runtime_error& e)
180 std::istringstream ss{line};
181 auto s = read_state(ss);
182 auto d = read_state(ss);
192 "invalid daut file: expected destination after: ", s,
194 auto entry = read_entry(ss);
197 edit->add_entry(s ==
"$" ? pre : s,
198 d ==
"$" ? post : d, entry);
200 catch (
const std::runtime_error& e)
207 edit.reset(make_editor(
""));
208 return edit->result();
char get_char(std::istream &i)
Read a single char, with possible -escape support.
context make_context(const std::string &name)
Build a context from its name.
void skip_space(std::istream &is)
Ignore spaces.
boost::flyweight< std::string, boost::flyweights::no_tracking, boost::flyweights::intermodule_holder > symbol
An internalized string.
std::string caret(std::istream &is, const rat::location &loc)
Repeat a line with an error, underlining the error with carets.
Abstract Builder (the design pattern) for automata.
void step()
Reset initial location to final location.
automaton read_daut(std::istream &is, const location &l)
position begin
Beginning of the located region.
void lines(int count=1)
Extend the current location to the COUNT next lines.
automaton_editor * make_automaton_editor(const context &ctx)
Build an automaton editor from its context.
#define VCSN_REQUIRE(Cond,...)
A macro similar to require.