krat_exp_parser.hxx

00001 // krat_exp_parser.hxx: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 2008 The Vaucanson Group.
00006 //
00007 // This program is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2
00010 // of the License, or (at your option) any later version.
00011 //
00012 // The complete GNU General Public Licence Notice can be found as the
00013 // `COPYING' file in the root directory.
00014 //
00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
00016 //
00017 
00018 #ifndef VCSN_ALGEBRA_IMPLEMENTATION_SERIES_KRAT_EXP_PARSER_HXX
00019 # define VCSN_ALGEBRA_IMPLEMENTATION_SERIES_KRAT_EXP_PARSER_HXX
00020 # include <map>
00021 # include <queue>
00022 # include <set>
00023 # include <vaucanson/algebra/implementation/series/krat_exp_parser.hh>
00024 # include <vaucanson/algebra/implementation/series/krat_exp_proxy.hh>
00025 # include <vaucanson/algebra/concept/monoid_base.hh>
00026 
00027 // Declaration to link with libkrat_exp
00028 namespace yy
00029 {
00030   struct token_queue;
00031 
00032   // WARNING: this struct declaration is also in
00033   //   lib/krat_exp/krat_exp_bison.yy
00034   // until someone factors these, you have to update both.
00035   struct krat_exp_parser
00036   {
00037     krat_exp_parser();
00038     ~krat_exp_parser();
00039     void insert_word(vcsn::algebra::krat_exp_virtual* rexp);
00040     void insert_weight(vcsn::algebra::semiring_virtual* sem);
00041     void insert_one(vcsn::algebra::krat_exp_virtual* rexp);
00042     void insert_zero(vcsn::algebra::krat_exp_virtual* rexp);
00043     void insert_token(int i, std::string* str);
00044     int parse(vcsn::algebra::krat_exp_virtual& rexp, std::string& error);
00045 
00046     // Attributs
00047     token_queue* tok_q_;
00048    }; // krat_exp_parser
00049 } // yy
00050 
00051 namespace vcsn
00052 {
00053   namespace algebra
00054   {
00055 
00056     template <class S, class T>
00057     struct Lexer
00058     {
00059       typedef typename Element<S, T>::monoid_elt_t monoid_elt_t;
00060       typedef typename Element<S, T>::semiring_elt_t semiring_elt_t;
00061       Lexer(const std::string& from,
00062             Element<S, T>& e,
00063             yy::krat_exp_parser& parser,
00064             bool lex_trace,
00065             const token_representation<typename S::monoid_t::letter_t> tok_rep,
00066             std::string& error) :
00067         from_(from),
00068         e_(e),
00069         parser_(parser),
00070         lex_trace_(lex_trace),
00071         close_weight_("}"),
00072         token_tab_(9),
00073         error_(error)
00074       {
00075         precondition(!tok_rep.open_par.empty());
00076         precondition(!tok_rep.close_par.empty());
00077         precondition(!tok_rep.plus.empty());
00078         precondition(!tok_rep.times.empty());
00079         precondition(!tok_rep.star.empty());
00080         precondition(!tok_rep.one.empty());
00081         precondition(!tok_rep.zero.empty());
00082         precondition(!tok_rep.open_weight.empty());
00083         precondition(!tok_rep.close_weight.empty());
00084 
00085         token_tab_[0] = tok_rep.open_par;
00086         token_tab_[1] = tok_rep.close_par;
00087         token_tab_[2] = tok_rep.plus;
00088         token_tab_[3] = tok_rep.times;
00089         token_tab_[4] = tok_rep.star;
00090         token_tab_[5] = tok_rep.one;
00091         token_tab_[6] = tok_rep.zero;
00092         token_tab_[7] = tok_rep.open_weight;
00093         close_weight_ = tok_rep.close_weight;
00094         for (unsigned i = 0; i < tok_rep.spaces.size(); i++)
00095         {
00096           assertion(!tok_rep.spaces[i].empty());
00097           token_tab_[8 + i] = tok_rep.spaces[i];
00098         }
00099 
00100         std::string::const_iterator sit;
00101         semiring_elt_t ww(e_.structure().semiring());
00102         sit = close_weight_.begin();
00103         if (parse_weight(ww, close_weight_, sit))
00104           error_ += "Warning : the token '" + close_weight_ +
00105                     + "' is already defined as a weight.\n";
00106         sit = token_tab_[7].begin();
00107         if (parse_weight(ww, token_tab_[7], sit))
00108           error_ += "Warning : the token '" + token_tab_[7]
00109                     + "' is already defined as a weight.\n";
00110         for (unsigned i = 0; i < token_tab_.size(); i++)
00111         {
00112           sit = token_tab_[i].begin();
00113           monoid_elt_t w(e_.structure().monoid());
00114           if (parse_word(w, token_tab_[i], sit, std::set<char>()))
00115             error_ +=  "Warning : the token '" + token_tab_[i]
00116                        + "' is already defined as a word.\n";
00117         }
00118 
00119       }
00120 
00121       bool
00122       lex()
00123       {
00124         size_t curr = 0;
00125         size_t size = from_.size();
00126         size_t it = curr;
00127         while (it < size)
00128         {
00129           for (size_t i = 0; i < token_tab_.size(); i++)
00130           {
00131             if (!from_.compare(it, token_tab_[i].size(), token_tab_[i]))
00132             {
00133               if (curr != it)
00134                 if (!insert_word(curr, it))
00135                   return false;
00136               if (i == 7)
00137               {
00138                 if (!insert_weight(it))
00139                   return false;
00140               }
00141               else
00142               {
00143                 if (i < 7)
00144                   insert_token(i);
00145                 it += token_tab_[i].size();
00146               }
00147               curr = it--;
00148               break;
00149             }
00150           }
00151           it++;
00152         }
00153         if (curr != it)
00154           if (!insert_word(curr, it))
00155             return false;
00156         return true;
00157       }
00158 
00159       private:
00160       bool
00161       insert_word(size_t curr, size_t it)
00162       {
00163         monoid_elt_t w(e_.structure().monoid());
00164         std::string s = from_.substr(curr, it - curr);
00165         std::string::const_iterator sit = s.begin();
00166         if (parse_word(w, s, sit, std::set<char>()))
00167         {
00168           Element<S, T> ww = Element<S, T>(e_.structure(), w.value());
00169           krat_exp_proxy<S, T>* rexp = new krat_exp_proxy<S, T>(ww);
00170           parser_.insert_word(rexp);
00171         }
00172         else
00173         {
00174           error_ += "Lexer error : " + s
00175                     + " some characters are not part of the alphabet\n";
00176           return false;
00177         }
00178         return true;
00179       }
00180 
00181       bool
00182       insert_weight(size_t& it)
00183       {
00184         it += token_tab_[7].size();
00185         size_t bg = it;
00186         size_t size = from_.size();
00187         unsigned cpt = 1;
00188         for (; it < size; it++)
00189         {
00190           if (!from_.compare(it, token_tab_[7].size(), token_tab_[7]))
00191             cpt++;
00192           else
00193             if (!from_.compare(it, close_weight_.size(), close_weight_))
00194             {
00195               if (cpt == 1)
00196               {
00197                 semiring_elt_t w(e_.structure().semiring());
00198                 std::string s = from_.substr(bg, it - bg);
00199                 std::string::const_iterator sit = s.begin();
00200                 if (parse_weight(w, s, sit))
00201                 {
00202                   semiring_proxy<S, T>* sem = new semiring_proxy<S, T>(w);
00203                   parser_.insert_weight(sem);
00204                 }
00205                 else
00206                 {
00207                   error_ += "Lexer error : " + s + " is not a weight\n";
00208                   return false;
00209                 }
00210                 it += close_weight_.size();
00211                 return true;
00212               }
00213               else
00214                 cpt--;
00215             }
00216         }
00217         error_ += "Lexer error : Expected " + close_weight_
00218                   + "instead of END\n";
00219         return false;
00220       }
00221 
00222       void
00223       insert_token(int i)
00224       {
00225         if (i == 5)
00226         {
00227           Element<S, T> w = identity_as<T>::of(e_.structure());
00228           krat_exp_proxy<S, T>* rexp = new krat_exp_proxy<S, T>(w);
00229           parser_.insert_one(rexp);
00230         }
00231         else
00232           if (i == 6)
00233           {
00234             Element<S, T> w = zero_as<T>::of(e_.structure());
00235             krat_exp_proxy<S, T>* rexp = new krat_exp_proxy<S, T>(w);
00236             parser_.insert_zero(rexp);
00237           }
00238           else
00239           {
00240             std::string* str = new std::string(token_tab_[i]);
00241             parser_.insert_token(i, str);
00242           }
00243       }
00244 
00245       const std::string& from_;
00246       Element<S, T>& e_;
00247       yy::krat_exp_parser& parser_;
00248       bool lex_trace_;
00249       std::string close_weight_;
00250       std::vector<std::string> token_tab_;
00251       std::string& error_;
00252     }; // Lexer
00253 
00254     template <class S, class T>
00255     std::pair<bool, std::string>
00256     parse(const std::string& from,
00257         Element<S, T>& exp,
00258         const token_representation<typename S::monoid_t::letter_t> tok_rep
00259         = token_representation<typename S::monoid_t::letter_t>(),
00260         bool lex_trace = false,
00261         bool parse_trace = false)
00262     {
00263       parse_trace = parse_trace;
00264       std::string error;
00265       yy::krat_exp_parser parser;
00266       Lexer<S, T> lex(from, exp, parser, lex_trace, tok_rep, error);
00267       if (!lex.lex())
00268         return std::make_pair(true, error);
00269       krat_exp_proxy<S, T> rexp(exp);
00270       if (parser.parse(rexp, error))
00271         return std::make_pair(true, error);
00272       exp = rexp.self;
00273       return std::make_pair(false, error);
00274     }
00275 
00276   } // algebra
00277 
00278 } // vcsn
00279 
00280 #endif // ! VCSN_ALGEBRA_IMPLEMENTATION_SERIES_KRAT_EXP_PARSER_HXX

Generated on Thu Oct 9 20:22:37 2008 for Vaucanson by  doxygen 1.5.1