couple_letter.hxx

00001 // couple_letter.hxx: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2008 The Vaucanson
00006 // Group.
00007 //
00008 // This program is free software; you can redistribute it and/or
00009 // modify it under the terms of the GNU General Public License
00010 // as published by the Free Software Foundation; either version 2
00011 // of the License, or (at your option) any later version.
00012 //
00013 // The complete GNU General Public Licence Notice can be found as the
00014 // `COPYING' file in the root directory.
00015 //
00016 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
00017 //
00018 #ifndef VCSN_ALGEBRA_IMPLEMENTATION_LETTER_COUPLE_LETTER_HXX
00019 # define VCSN_ALGEBRA_IMPLEMENTATION_LETTER_COUPLE_LETTER_HXX
00020 
00021 # include <stdexcept>
00022 # include <sstream>
00023 
00024 # include <vaucanson/algebra/implementation/letter/couple_letter.hh>
00025 
00026 namespace vcsn {
00027 
00028   namespace algebra {
00029 
00030     template <typename U, typename V>
00031     struct letter_traits< std::pair<U, V> >
00032     {
00033       // we only consider letters of the form (u, v)
00034       typedef misc::true_t is_char_letter;
00035 
00036       enum
00037       {
00038         /*
00039          * Theoretically   cardinal     should   be   the   product   of
00040          * letter_traits<U>::cardinal and letter_traits<V>::cardinal.
00041          * But to  avoid overflows and for
00042          * practical reasons, it is better to consider it infinite.
00043          *
00044          * FIXME: Maybe doing this is not a good idea?
00045          */
00046         cardinal = INT_MAX
00047       };
00048 
00049       // A pair letter has two projections available: U and V.
00050       typedef U first_projection_t;
00051       typedef V second_projection_t;
00052 
00053       LETTER_DEFAULT(open_par, "[")
00054       LETTER_DEFAULT(close_par, "]")
00055       LETTER_DEFAULT(plus, "+")
00056       LETTER_DEFAULT(times, ".")
00057       LETTER_DEFAULT(star, "*")
00058       LETTER_DEFAULT(epsilon, "_e")
00059       LETTER_DEFAULT(zero, "_z")
00060       LETTER_DEFAULT(open_weight, "{")
00061       LETTER_DEFAULT(close_weight, "}")
00062       LETTER_DEFAULT(space, " ")
00063 
00064       static
00065       std::pair<U, V>
00066       literal_to_letter(const std::string& str)
00067       {
00068         std::stringstream sstr(str);
00069         std::pair<U, V> ret;
00070         sstr >> ret;
00071         return ret;
00072       }
00073 
00074       static
00075       std::string
00076       letter_to_literal(const std::pair<U, V>& c)
00077       {
00078         std::stringstream sstr;
00079         sstr << c;
00080         return sstr.str();
00081       }
00082 
00083       // A pair is a "tuple" with dimension 2.
00084       static std::string kind() { return "tuple"; }
00085       static int dim() { return 2; }
00086 
00087     };
00088 
00089 # define COUPLE_LETTER_DEFAULT(name, val, type1, type2) \
00090     template <> \
00091     inline std::string \
00092     letter_traits<std::pair<type1, type2> >::default_##name () { return val; }
00093 
00094     COUPLE_LETTER_DEFAULT(epsilon, "1", char, char)
00095     COUPLE_LETTER_DEFAULT(zero, "0", char, char)
00096 
00097     COUPLE_LETTER_DEFAULT(epsilon, "e", int, int)
00098     COUPLE_LETTER_DEFAULT(zero, "z", int, int)
00099 
00100 # undef COUPLE_LETTER_DEFAULT
00101 
00102     // Specialization for pairs.
00103     // FIXME: we should share the taf-kit parser with letters op_parse.
00104     // FIXME: this parser is very weak.
00105     template <typename S, typename U, typename V, typename CharContainer>
00106     bool op_parse(const algebra::FreeMonoidBase<S>& set,
00107                   std::basic_string< std::pair<U, V> >& v,
00108                   const std::string& s,
00109                   typename std::string::const_iterator& i,
00110                   const CharContainer&)
00111     {
00112       while (i != s.end())
00113       {
00114         if (*i != '(')
00115           break ;
00116 
00117         std::string sub(i, s.end());
00118         std::stringstream is(sub);
00119 
00120         std::pair<U,V> p;
00121         is >> p;
00122         int pos = is.tellg();
00123 
00124         // We didn't parse anything.
00125         if (pos == 0)
00126           break;
00127 
00128         // Unknown letter.
00129         if (!set.alphabet().contains(p))
00130         {
00131           std::stringstream sstr;
00132           sstr << p;
00133           throw std::logic_error(std::string("Letter not in the alphabet: ") + sstr.str());
00134         }
00135 
00136         // Advance the iterator.
00137         for (int k = 0; k < pos; ++k)
00138           ++i;
00139 
00140         // Concatenate the letter.
00141         v += p;
00142       }
00143 
00144       return (i == s.end());
00145     }
00146 
00147   } // ! algebra
00148 
00149 } // ! vcsn
00150 
00151 namespace std
00152 {
00153 
00154   template <typename U, typename V>
00155   std::ostream& operator<< (std::ostream& o, std::pair<U, V> p)
00156   {
00157     return o << "(" << p.first << "," << p.second << ")";
00158   }
00159 
00160   template <typename U, typename V, class Traits, class Allocator>
00161   std::ostream& operator<< (std::ostream& o,
00162                             std::basic_string<std::pair<U, V>, Traits, Allocator> s)
00163   {
00164     typename
00165       std::basic_string<std::pair<U, V>, Traits, Allocator>::const_iterator i;
00166     for (i = s.begin (); i != s.end (); ++i)
00167       o << "(" << i->first << "," << i->second << ")";
00168     return o;
00169   }
00170 
00171   template <typename U, typename V>
00172   std::istream& operator>> (std::istream& i, std::pair<U, V>& p)
00173   {
00174     char c = i.get ();
00175     if (c != '(')
00176       i.unget ();
00177     i >> p.first;
00178     c = i.get ();
00179     if (c != ',')
00180       i.unget ();
00181     i >> p.second;
00182     c = i.get ();
00183     if (c != ')')
00184       i.unget ();
00185     return i;
00186   }
00187 
00188 } // ! std
00189 
00190 #endif // ! VCSN_ALGEBRA_IMPLEMENTATION_LETTER_COUPLE_LETTER_HXX

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