Vcsn  2.3
Be Rational
edit-automaton.cc
Go to the documentation of this file.
1 #include <cctype>
2 #include <regex>
3 
6 #include <vcsn/dyn/algos.hh>
7 #include <vcsn/dyn/automaton.hh>
8 #include <vcsn/dyn/registries.hh>
9 #include <vcsn/misc/builtins.hh>
10 
11 namespace vcsn
12 {
13 
14  namespace
15  {
16  using labelset_type = lazy_automaton_editor::labelset_type;
17 
18  labelset_type type(lazy_automaton_editor::string_t lbl)
19  {
20  if (lbl.get().empty())
21  return labelset_type::empty;
22  else if (lbl == "\\e")
23  return labelset_type::lan;
24  else if (1 < lbl.get().size())
25  return labelset_type::law;
26  else
27  return labelset_type::lal;
28  }
29 
30  std::string to_string(labelset_type l)
31  {
32  switch (l)
33  {
34  case labelset_type::empty: return {};
35  case labelset_type::lal: return "lal<char>";
36  case labelset_type::lan: return "lan<char>";
37  case labelset_type::law: return "law<char>";
38  }
40  }
41 
44  {
45  if (s == "\\e"
46  || s.get().size() == 1 && std::isalnum(s.get()[0]))
47  return s;
48  else
49  {
50  // Backslash backslashes and quotes.
51  static auto re = std::regex{"['\\\\]"};
52  return ("'"
53  + std::regex_replace(s.get(), re, "\\$&")
54  + "'");
55  }
56  }
57  }
58 
59 
60  /*------------------------.
61  | lazy_automaton_editor. |
62  `------------------------*/
63 
64  void
66  {
67  if (!w.get().empty())
68  {
69  weighted_ = true;
70  if (!real_
71  && w.get().find('.') != std::string::npos)
72  real_ = true;
73  }
74  }
75 
76  void
78  {
79  initial_states_.emplace_back(s, w);
81  }
82 
83  void
85  {
86  final_states_.emplace_back(s, w);
88  }
89 
90 
91 
93  void
95  string_t dst,
96  string_t lbl1,
97  string_t lbl2,
99  {
100  input_type_ = std::max(input_type_, type(lbl1));
101 
102  if (lbl2.get().empty())
103  lbl1 = quote(lbl1);
104  else
105  {
106  // Turn into a multiple-tape label.
107  output_type_ = std::max(output_type_, type(lbl2));
108  lbl1 = quote(lbl1) + "|" + quote(lbl2);
109  }
110  transitions_.emplace_back(src, dst, lbl1, weight);
111 
112  register_weight_(weight);
113  }
114 
116  void
118  string_t dst,
119  string_t lbl,
121  {
122  add_transition(src, dst, lbl, string_t{}, weight);
123  }
124 
125  bool
127  {
128  std::swap(open_, o);
129  return o;
130  }
131 
132  void
134  {
135  transitions_.clear();
136  final_states_.clear();
137  initial_states_.clear();
138  }
139 
141  {
142  // If there are no transitions (e.g., standard("\e")), consider
143  // the labelset is a plain lal.
144  auto res
147  : input_type_);
149  res = "lat<" + res + "," + to_string(output_type_) + '>';
150  res += ", ";
151  switch (weightset_type_)
152  {
154  res += "log";
155  break;
157  res += (real_ ? "r"
158  : weighted_ ? "z"
159  : "b");
160  break;
162  res += (real_ ? "rmin"
163  : weighted_ ? "zmin"
164  : "b");
165  break;
166  }
167  return res;
168  }
169 
171  {
172  auto c = vcsn::dyn::make_context(ctx.empty() ? result_context() : ctx);
173  auto edit = vcsn::dyn::make_automaton_editor(c);
174  edit->open(open_);
175 
176  for (auto t: transitions_)
177  edit->add_transition(std::get<0>(t), std::get<1>(t),
178  std::get<2>(t), std::get<3>(t));
179 
180  for (auto p: initial_states_)
181  edit->add_initial(p.first, p.second);
182 
183  for (auto p: final_states_)
184  edit->add_final(p.first, p.second);
185  return edit->result();
186  }
187 }
value_impl< detail::weight_tag > weight
Definition: fwd.hh:28
context make_context(const std::string &name)
Build a context from its name.
Definition: others.cc:97
bool open_
Whether the labelset is open.
std::string type(const automaton &a)
The implementation type of a.
Definition: others.cc:231
bool weighted_
Whether we saw a non-empty weight.
#define BUILTIN_UNREACHABLE()
Definition: builtins.hh:13
void add_initial(string_t s, string_t w=string_t{})
Add s as an initial state.
labelset_type
Labelset types, increasing generality.
void register_weight_(string_t w)
Record that this weight was seen.
bool real_
Whether we saw a period in a the weight.
void add_transition(string_t src, string_t dst, string_t lbl, string_t w=string_t{})
Add an acceptor transition from src to dst, labeled by lbl.
void add_final(string_t s, string_t w=string_t{})
Add s as a final state.
automaton_editor::string_t string_t
A hash-cons'ed string type.
void reset()
Get ready to build another automaton.
return res
Definition: multiply.hh:398
std::vector< std::pair< string_t, string_t > > initial_states_
The collected initial states: (State, Weight).
labelset_type output_type_
Labelset type for output tape.
bool open(bool o)
Whether unknown letters should be added, or rejected.
Definition: a-star.hh:8
labelset_type input_type_
Labelset type for input tape.
A dyn automaton.
Definition: automaton.hh:17
automaton_editor * make_automaton_editor(const context &ctx)
Build an automatonset from its context.
std::vector< transition_t > transitions_
std::vector< std::pair< string_t, string_t > > final_states_
The collected final states: (State, Weight).
std::string to_string(direction d)
Conversion to string.
Definition: direction.cc:7
std::string quote(const std::string &s)
Turn a label into a parsable label: escape special characters.
Definition: trie.hh:23
std::string result_context() const
Return the context that was inferred.
weightset_type weightset_type_
The weightset scale.
dyn::automaton result(const std::string &ctx={})
Return the built automaton.