Vcsn  2.2
Be Rational
driver.cc
Go to the documentation of this file.
1 #include <sstream>
2 
3 #include <boost/algorithm/string/predicate.hpp> // boost::algorithm::contains
4 
5 #include <lib/vcsn/rat/driver.hh>
6 #include <lib/vcsn/rat/parse.hh>
7 #include <lib/vcsn/rat/scan.hh>
8 #include <vcsn/dyn/algos.hh> // make_context
9 #include <vcsn/misc/stream.hh> // fail_reading
10 
11 namespace vcsn
12 {
13  namespace rat
14  {
15 
17  : scanner_(new yyFlexLexer)
18  , ids_(ids)
19  {
20  context(ctx);
21  }
22 
24  {}
25 
27  {
28  return tape_ctx_[tapes_.back()];
29  }
30 
32  {
33  ctx_ = ctx;
34  tape_ctx_.clear();
35  auto n = dyn::num_tapes(ctx_);
36  if (n)
37  for (size_t t = 0; t < n; ++t)
38  tape_ctx_.emplace_back(dyn::project(ctx_, t));
39  else
40  tape_ctx_.emplace_back(ctx_);
41  }
42 
43  void driver::context(const std::string& ctx)
44  {
46  }
47 
49  {
50  return ids_;
51  }
52 
54  {
55  tapes_.push_back(tapes_.back());
56  }
57 
59  {
60  tapes_.pop_back();
61  }
62 
63  void driver::tape_inc(const location& l)
64  {
65  if (tapes_.back() + 1 < tape_ctx_.size())
66  ++tapes_.back();
67  else
68  throw parser::syntax_error(l, "too many tapes");
69  }
70 
71  void driver::error(const location& l, const std::string& m)
72  {
73  std::ostringstream er;
74  er << l << ": " << m;
75  if (!!getenv("YYDEBUG"))
76  std::cerr << er.str() << std::endl;
77  errors += (errors.empty() ? "" : "\n") + er.str();
78  }
79 
80  void driver::invalid(const location& l, const std::string& s)
81  {
82  error(l, "invalid input: " + s);
83  }
84 
87  static int
89  {
90  int res = 0;
91  if (const char* cp = getenv("YYDEBUG"))
92  {
93  res = 1;
94  std::istringstream s{cp};
95  s >> res;
96  }
97  return res;
98  }
99 
100  auto
101  driver::parse(std::istream& is, const location& l)
102  -> dyn::expression
103  {
104  scanner_->scan_open_(is);
105  location_ = l;
106  // Parser.
107  parser p(*this);
108  // If the number of nested parser invocations is less than
109  // $YYDEBUG, be verbose. Recursive parsings are used for
110  // weights; for instance "<<a>b>c" uses three (nested) parsers.
111  static int debug_level = debug_level_();
112  static int nesting = 0;
113  p.set_debug_level(debug_level && nesting < debug_level);
114  ++nesting;
115  if (p.parse())
116  result_ = nullptr;
117  scanner_->scan_close_();
118  --nesting;
119 
120  return std::move(result_);
121  }
122 
123  dyn::label
124  driver::make_label(const location& loc, const std::string& s,
125  const dyn::context& ctx)
126  {
127  try
128  {
129  std::istringstream is{s};
130  auto res = dyn::read_label(ctx, is, "text");
131  require(is.peek() == -1,
132  "unexpected trailing characters in: ", s, ": ", is);
133  return res;
134  }
135  catch (const std::exception& e)
136  {
137  throw parser::syntax_error(loc, e.what());
138  }
139  }
140 
142  driver::make_atom(const location& loc, const std::string& s)
143  {
144  // If there are commas in the label, then have it read as a full
145  // label, not a one-tape label.
146  //
147  // FIXME: Remove once the tuple approach works perfectly. And
148  // simplify make_label accordingly (no dyn::context argument
149  // needed).
150  if (boost::algorithm::contains(s, ","))
151  return dyn::to_expression(ctx_, ids_,
152  make_label(loc, s, ctx_));
153  else
154  return dyn::to_expression(context(), ids_,
155  make_label(loc, s, context()));
156  }
157 
160  const class_t& c, bool accept = true)
161  {
162  try
163  {
164  // If there are commas in the labels, then have it read as a full
165  // label, not a one-tape label.
166  //
167  // FIXME: Remove once the tuple approach works perfectly.
168  if (!c.empty()
169  && boost::algorithm::contains(detail::front(c).first, ","))
170  return dyn::to_expression(ctx_, ids_, c, accept);
171  else
172  return dyn::to_expression(context(), ids_, c, accept);
173  }
174  catch (const std::exception& e)
175  {
176  throw parser::syntax_error(loc, e.what());
177  }
178  }
179 
181  driver::make_weight(const location& loc, const std::string& s)
182  {
183  try
184  {
185  std::istringstream is{s};
186  auto res = dyn::read_weight(ctx_, is);
187  require(is.peek() == -1,
188  "unexpected trailing characters in: ", s, ": ", is);
189  return res;
190  }
191  catch (const std::exception& e)
192  {
193  throw parser::syntax_error(loc, e.what());
194  }
195  }
196  }
197 }
weight read_weight(const context &ctx, std::istream &is)
Read a weight from a stream.
Definition: read.hh:95
std::set< std::pair< std::string, std::string >> class_t
A set of label ranges.
Definition: fwd.hh:12
void set_debug_level(debug_level_type l)
Set the current debugging level.
Definition: parse.cc:552
dyn::context ctx_
The context used to read the expression.
Definition: driver.hh:78
rat::identities ids_
The identities to apply.
Definition: driver.hh:80
std::shared_ptr< const detail::weight_base > weight
Definition: fwd.hh:88
An expressionset can implement several different sets of identities on expressions.
Definition: identities.hh:21
std::size_t num_tapes(const context &ctx)
The number of input tapes.
dyn::expression make_atom(const location &loc, const std::string &s)
From a string, generate an expression.
Definition: driver.cc:142
Definition: a-star.hh:8
void require(Bool b, Args &&...args)
If b is not verified, raise an error with args as message.
Definition: raise.hh:78
rat::identities identities() const
Get the identities.
Definition: driver.cc:48
virtual int parse()
Parse.
Definition: parse.cc:581
std::string errors
The error messages.
Definition: driver.hh:54
std::vector< unsigned > tapes_
The stack of tape numbers.
Definition: driver.hh:89
void error(const location &l, const std::string &m)
Report an error m at l.
Definition: driver.cc:71
dyn::expression parse(std::istream &is, const location &l=location{})
Parse this stream.
Definition: driver.cc:101
dyn::label make_label(const location &loc, const std::string &s, const dyn::context &ctx)
From a string, generate a label.
Definition: driver.cc:124
dyn::expression make_expression(const location &loc, const class_t &c, bool accept)
From a label class, generate an expression.
Definition: driver.cc:159
A Bison parser.
Definition: parse.hh:299
std::shared_ptr< const detail::label_base > label
Definition: fwd.hh:61
Abstract a location.
Definition: location.hh:47
driver(const dyn::context &ctx, rat::identities ids)
Definition: driver.cc:16
std::shared_ptr< const detail::context_base > context
A dyn::context.
Definition: fwd.hh:43
void tape_pop()
Pop the tape stack.
Definition: driver.cc:58
automaton project(const automaton &aut, unsigned tape)
Keep a single tape from a multiple-tape automaton.
Definition: others.cc:115
static int debug_level_()
The nesting limit for parser traces, as specified per $YYDEBUG.
Definition: driver.cc:88
void tape_inc(const location &l)
Increment the top most tape.
Definition: driver.cc:63
void tape_push()
Push a new tape number on the stack.
Definition: driver.cc:53
expression to_expression(const automaton &aut, rat::identities ids={}, const std::string &algo="auto")
An expression denoting the language of aut.
Define the vcsn::rat::parser class.
std::istringstream is
The input stream: the specification to translate.
Definition: translate.cc:380
context make_context(const std::string &name)
Build a context from its name.
Definition: others.cc:99
dyn::weight make_weight(const location &loc, const std::string &s)
From a string, generate a weight.
Definition: driver.cc:181
std::vector< dyn::context > tape_ctx_
The context for each tape. If single-tape, [0] is ctx_.
Definition: driver.hh:91
static dyn::context ctx(const driver &d)
Get the context of the driver.
Definition: parse.cc:82
Container::value_type front(const Container &container)
The first member of this Container.
Definition: algorithm.hh:58
static int debug_level()
Debug level set in the user's environment.
Definition: debug-level.hh:11
std::shared_ptr< detail::expression_base > expression
Definition: expression.hh:92
void invalid(const location &l, const std::string &s)
The string s is invalid at l.
Definition: driver.cc:80
static identities ids(const driver &d)
Get the identities of the driver.
Definition: parse.cc:89
Syntax errors thrown from user actions.
Definition: parse.hh:338
dyn::context context() const
Get the current context.
Definition: driver.cc:26
label read_label(const context &ctx, std::istream &is, const std::string &format="default")
Read a label from a stream.
Definition: read.cc:84