Vaucanson  1.4.1
krat_exp_parser.hxx
1 // krat_exp_parser.hxx: this file is part of the Vaucanson project.
2 //
3 // Vaucanson, a generic library for finite state machines.
4 //
5 // Copyright (C) 2008, 2009, 2011 The Vaucanson Group.
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
11 //
12 // The complete GNU General Public Licence Notice can be found as the
13 // `COPYING' file in the root directory.
14 //
15 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
16 //
17 
18 #ifndef VCSN_ALGEBRA_IMPLEMENTATION_SERIES_KRAT_EXP_PARSER_HXX
19 # define VCSN_ALGEBRA_IMPLEMENTATION_SERIES_KRAT_EXP_PARSER_HXX
20 # include <map>
21 # include <queue>
22 # include <set>
24 # include <vaucanson/algebra/concept/monoid_base.hh>
25 # include <vaucanson/algebra/implementation/series/krat_exp_parser_private.hh>
26 
27 namespace vcsn
28 {
29  namespace algebra
30  {
31 
32  template <class S, class T>
33  struct Lexer
34  {
35  // Type helpers.
36  typedef typename Element<S, T>::monoid_elt_t monoid_elt_t;
37  typedef typename Element<S, T>::semiring_elt_t semiring_elt_t;
38  typedef typename Element<S, T>::set_t::shared_series_rep_t
39  shared_series_rep_t;
40 
41  Lexer(const std::string& from,
42  Element<S, T>& e,
43  vcsnyy::krat_exp_parser& parser,
44  bool lex_trace,
45  std::string& error) :
46  from_(from),
47  e_(e),
48  parser_(parser),
49  lex_trace_(lex_trace),
50  close_weight_("}"),
51  // Reserve seven elements for the "visible" tokens.
52  token_tab_(7),
53  error_(error)
54  {
55  // Get the series representation.
56  const shared_series_rep_t& rep = e.structure().representation();
57 
58  token_tab_[0] = rep->open_par;
59  token_tab_[1] = rep->close_par;
60  token_tab_[2] = rep->plus;
61  token_tab_[3] = rep->times;
62  token_tab_[4] = rep->star;
63  token_tab_[5] = rep->zero;
64  token_tab_[6] = rep->open_weight;
65  close_weight_ = rep->close_weight;
66 
67  // Concat the spaces representation vector.
68  token_tab_.insert(token_tab_.end(), rep->spaces.begin(), rep->spaces.end());
69 
70  std::string::const_iterator sit;
71  semiring_elt_t ww(e_.structure().semiring());
72  sit = close_weight_.begin();
73  if (parse_weight(ww, close_weight_, sit))
74  error_ += "Warning : the token '" + close_weight_ +
75  + "' is already defined as a weight.\n";
76  sit = token_tab_[7].begin();
77  if (parse_weight(ww, token_tab_[7], sit))
78  error_ += "Warning : the token '" + token_tab_[7]
79  + "' is already defined as a weight.\n";
80  for (unsigned i = 0; i < token_tab_.size(); i++)
81  {
82  monoid_elt_t w(e_.structure().monoid());
83  if (parse_word(w, token_tab_[i]).first)
84  error_ += "Warning : the token '" + token_tab_[i]
85  + "' is already defined as a word.\n";
86  }
87 
88  }
89 
90  bool
91  lex()
92  {
93  size_t size = from_.size();
94  size_t it = 0;
95  while (it < size)
96  {
97  // Try to recognize a word.
98  monoid_elt_t w(e_.structure().monoid());
99  std::pair<bool, int> res = parse_word(w, from_.substr(it));
100  if (res.second > 0)
101  {
102  insert_word(w);
103  // If the entire input was a word there is nothing else to lex.
104  if (res.first)
105  {
106  assertion(it + res.second == size);
107  break;
108  }
109  it += res.second;
110  }
111 
112  // Try to recognize a regex token.
113  size_t i;
114  for (i = 0; i < token_tab_.size(); i++)
115  {
116  if (!from_.compare(it, token_tab_[i].size(), token_tab_[i]))
117  {
118  if (i == 6)
119  {
120  if (!insert_weight(it))
121  return false;
122  }
123  else
124  {
125  if (i < 6)
126  insert_token(i);
127  it += token_tab_[i].size();
128  }
129  break;
130  }
131  }
132  if (i >= token_tab_.size())
133  {
134  error_ += "Lexer error, unrecognized characters: "
135  + from_.substr(it) + "\n";
136  return false;
137  }
138  }
139  return true;
140  }
141 
142  private:
143  void
144  insert_word(monoid_elt_t& w)
145  {
146  Element<S, T> ww = (w.value().empty() ?
147  identity_as<T>::of(e_.structure()) :
148  Element<S, T>(e_.structure(), w.value()));
149 
150  krat_exp_proxy<S, T>* rexp = new krat_exp_proxy<S, T>(ww);
151  parser_.insert_word(rexp);
152  }
153 
154  bool
155  insert_weight(size_t& it)
156  {
157  it += token_tab_[7].size();
158  size_t bg = it;
159  size_t size = from_.size();
160  unsigned cpt = 1;
161  for (; it < size; it++)
162  {
163  if (!from_.compare(it, token_tab_[7].size(), token_tab_[7]))
164  cpt++;
165  else
166  if (!from_.compare(it, close_weight_.size(), close_weight_))
167  {
168  if (cpt == 1)
169  {
170  semiring_elt_t w(e_.structure().semiring());
171  std::string s = from_.substr(bg, it - bg);
172  std::string::const_iterator sit = s.begin();
173  if (parse_weight(w, s, sit))
174  {
175  semiring_proxy<S, T>* sem = new semiring_proxy<S, T>(w);
176  parser_.insert_weight(sem);
177  }
178  else
179  {
180  error_ += "Lexer error : " + s + " is not a weight\n";
181  return false;
182  }
183  it += close_weight_.size();
184  return true;
185  }
186  else
187  cpt--;
188  }
189  }
190  error_ += "Lexer error : Expected " + close_weight_
191  + "instead of END\n";
192  return false;
193  }
194 
195  void
196  insert_token(int i)
197  {
198  if (i == 5)
199  {
200  Element<S, T> w = zero_as<T>::of(e_.structure());
201  krat_exp_proxy<S, T>* rexp = new krat_exp_proxy<S, T>(w);
202  parser_.insert_zero(rexp);
203  }
204  else
205  {
206  std::string* str = new std::string(token_tab_[i]);
207  parser_.insert_token(i, str);
208  }
209  }
210 
211  const std::string& from_;
212  Element<S, T>& e_;
213  vcsnyy::krat_exp_parser& parser_;
214  bool lex_trace_;
215  std::string close_weight_;
216  std::vector<std::string> token_tab_;
217  std::string& error_;
218  }; // Lexer
219 
220  template <class S, class T>
221  std::pair<bool, std::string>
222  parse(const std::string& from, Element<S, T>& exp,
223  bool lex_trace, bool parse_trace)
224  {
225  parse_trace = parse_trace;
226  std::string error;
227  vcsnyy::krat_exp_parser parser;
228  Lexer<S, T> lex(from, exp, parser, lex_trace, error);
229  if (!lex.lex())
230  return std::make_pair(true, error);
231  krat_exp_proxy<S, T> rexp(exp);
232  if (parser.parse(rexp, error))
233  return std::make_pair(true, error);
234  exp = rexp.self;
235  return std::make_pair(false, error);
236  }
237 
238  } // algebra
239 
240 } // vcsn
241 
242 #endif // ! VCSN_ALGEBRA_IMPLEMENTATION_SERIES_KRAT_EXP_PARSER_HXX