Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r75910 - in trunk: boost/spirit/home/lex/lexer/lexertl boost/spirit/home/support/detail/lexer libs/spirit/test libs/spirit/test/lex
From: hartmut.kaiser_at_[hidden]
Date: 2011-12-11 19:48:42


Author: hkaiser
Date: 2011-12-11 19:48:40 EST (Sun, 11 Dec 2011)
New Revision: 75910
URL: http://svn.boost.org/trac/boost/changeset/75910

Log:
Spirit: fixed #6253: lex::lexertl::generate_static_dfa compiler errors if lexer has wchar_t as underlying stream type
Added:
   trunk/libs/spirit/test/lex/regression_static_wide_6253.cpp (contents, props changed)
Text files modified:
   trunk/boost/spirit/home/lex/lexer/lexertl/generate_static.hpp | 208 ++++++++++++++++++++++++++-------------
   trunk/boost/spirit/home/lex/lexer/lexertl/lexer.hpp | 110 ++++++++++----------
   trunk/boost/spirit/home/support/detail/lexer/rules.hpp | 20 +++
   trunk/libs/spirit/test/Jamfile | 1
   4 files changed, 214 insertions(+), 125 deletions(-)

Modified: trunk/boost/spirit/home/lex/lexer/lexertl/generate_static.hpp
==============================================================================
--- trunk/boost/spirit/home/lex/lexer/lexertl/generate_static.hpp (original)
+++ trunk/boost/spirit/home/lex/lexer/lexertl/generate_static.hpp 2011-12-11 19:48:40 EST (Sun, 11 Dec 2011)
@@ -1,7 +1,7 @@
 // Copyright (c) 2008-2009 Ben Hanson
 // Copyright (c) 2008-2011 Hartmut Kaiser
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
 #if !defined(BOOST_SPIRIT_LEX_LEXERTL_GENERATE_CPP_FEB_10_2008_0855PM)
@@ -22,33 +22,83 @@
 #include <boost/lexical_cast.hpp>
 
 ///////////////////////////////////////////////////////////////////////////////
-namespace boost { namespace spirit { namespace lex { namespace lexertl
+namespace boost { namespace spirit { namespace lex { namespace lexertl
 {
     namespace detail
     {
 
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename CharT>
+ struct string_lit;
+
+ template <>
+ struct string_lit<char>
+ {
+ static char get(char c) { return c; }
+ static std::string get(char const* str = "") { return str; }
+ };
+
+ template <>
+ struct string_lit<wchar_t>
+ {
+ static wchar_t get(char c)
+ {
+ typedef std::ctype<wchar_t> ctype_t;
+ return std::use_facet<ctype_t>(std::locale()).widen(c);
+ }
+ static std::basic_string<wchar_t> get(char const* source = "")
+ {
+ using namespace std; // some systems have size_t in ns std
+ size_t len = strlen(source);
+ std::auto_ptr<wchar_t> result (new wchar_t[len+1]);
+ result.get()[len] = '\0';
+
+ // working with wide character streams is supported only if the
+ // platform provides the std::ctype<wchar_t> facet
+ BOOST_ASSERT(std::has_facet<std::ctype<wchar_t> >(std::locale()));
+
+ std::use_facet<std::ctype<wchar_t> >(std::locale())
+ .widen(source, source + len, result.get());
+ return result.get();
+ }
+ };
+
+ template <typename Char>
+ inline Char L(char c)
+ {
+ return string_lit<Char>::get(c);
+ }
+
+ template <typename Char>
+ inline std::basic_string<Char> L(char const* c = "")
+ {
+ return string_lit<Char>::get(c);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Char>
     inline bool
- generate_delimiter(std::ostream &os_)
+ generate_delimiter(std::basic_ostream<Char> &os_)
     {
- os_ << std::string(80, '/') << "\n";
+ os_ << std::basic_string<Char>(80, '/') << "\n";
         return os_.good();
     }
 
     ///////////////////////////////////////////////////////////////////////////
- // Generate a table of the names of the used lexer states, which is a bit
- // tricky, because the table stored with the rules is sorted based on the
+ // Generate a table of the names of the used lexer states, which is a bit
+ // tricky, because the table stored with the rules is sorted based on the
     // names, but we need it sorted using the state ids.
     template <typename Char>
- inline bool
+ inline bool
     generate_cpp_state_info (boost::lexer::basic_rules<Char> const& rules_
- , std::ostream &os_, char const* name_suffix)
+ , std::basic_ostream<Char> &os_, Char const* name_suffix)
     {
- // we need to re-sort the state names in ascending order of the state
+ // we need to re-sort the state names in ascending order of the state
         // ids, filling possible gaps in between later
- typedef typename
+ typedef typename
             boost::lexer::basic_rules<Char>::string_size_t_map::const_iterator
         state_iterator;
- typedef std::map<std::size_t, char const*> reverse_state_map_type;
+ typedef std::map<std::size_t, Char const*> reverse_state_map_type;
 
         reverse_state_map_type reverse_state_map;
         state_iterator send = rules_.statemap().end();
@@ -60,7 +110,8 @@
 
         generate_delimiter(os_);
         os_ << "// this table defines the names of the lexer states\n";
- os_ << "char const* const lexer_state_names"
+ os_ << boost::lexer::detail::strings<Char>::char_name()
+ << " const* const lexer_state_names"
             << (name_suffix[0] ? "_" : "") << name_suffix
             << "[" << rules_.statemap().size() << "] = \n{\n";
 
@@ -73,7 +124,9 @@
             {
                 os_ << " 0, // \"<undefined state>\"\n";
             }
- os_ << " \"" << (*rit).second << "\"";
+ os_ << " "
+ << boost::lexer::detail::strings<Char>::char_prefix()
+ << "\"" << (*rit).second << "\"";
             if (++rit != rend)
                 os_ << ",\n";
             else
@@ -83,17 +136,18 @@
 
         generate_delimiter(os_);
         os_ << "// this variable defines the number of lexer states\n";
- os_ << "std::size_t const lexer_state_count"
+ os_ << "std::size_t const lexer_state_count"
             << (name_suffix[0] ? "_" : "") << name_suffix
             << " = " << rules_.statemap().size() << ";\n\n";
         return os_.good();
     }
 
- inline bool
- generate_cpp_state_table (std::ostream &os_, char const* name_suffix
- , bool bol, bool eol)
+ template <typename Char>
+ inline bool
+ generate_cpp_state_table (std::basic_ostream<Char> &os_
+ , Char const* name_suffix, bool bol, bool eol)
     {
- std::string suffix(name_suffix[0] ? "_" : "");
+ std::basic_string<Char> suffix(L<Char>(name_suffix[0] ? "_" : ""));
         suffix += name_suffix;
 
         generate_delimiter(os_);
@@ -102,7 +156,8 @@
         os_ << " // version number and feature-set of compatible static lexer engine\n";
         os_ << " enum\n";
         os_ << " {\n static_version = "
- << boost::lexical_cast<std::string>(SPIRIT_STATIC_LEXER_VERSION) << ",\n";
+ << boost::lexical_cast<std::basic_string<Char> >(SPIRIT_STATIC_LEXER_VERSION)
+ << ",\n";
         os_ << " supports_bol = " << std::boolalpha << bol << ",\n";
         os_ << " supports_eol = " << std::boolalpha << eol << "\n";
         os_ << " };\n\n";
@@ -110,13 +165,14 @@
         os_ << " static std::size_t state_count()\n";
         os_ << " {\n return lexer_state_count" << suffix << "; \n }\n\n";
         os_ << " // return the name of the lexer state as given by 'idx'\n";
- os_ << " static char const* state_name(std::size_t idx)\n";
+ os_ << " static " << boost::lexer::detail::strings<Char>::char_name()
+ << " const* state_name(std::size_t idx)\n";
         os_ << " {\n return lexer_state_names" << suffix << "[idx]; \n }\n\n";
         os_ << " // return the next matched token\n";
         os_ << " template<typename Iterator>\n";
         os_ << " static std::size_t next(std::size_t &start_state_, bool& bol_\n";
         os_ << " , Iterator &start_token_, Iterator const& end_, std::size_t& unique_id_)\n";
- os_ << " {\n return next_token" << suffix
+ os_ << " {\n return next_token" << suffix
             << "(start_state_, bol_, start_token_, end_, unique_id_);\n }\n";
         os_ << "};\n\n";
         return os_.good();
@@ -125,8 +181,8 @@
     ///////////////////////////////////////////////////////////////////////////
     // generate function body based on traversing the DFA tables
     template <typename Char>
- bool generate_function_body_dfa(std::ostream & os_
- , boost::lexer::basic_state_machine<Char> const &sm_)
+ bool generate_function_body_dfa(std::basic_ostream<Char>& os_
+ , boost::lexer::basic_state_machine<Char> const &sm_)
     {
         std::size_t const dfas_ = sm_.data()._dfa->size();
         std::size_t const lookups_ = sm_.data()._lookup->front()->size();
@@ -147,7 +203,7 @@
                 std::size_t const* lookup_ = &sm_.data()._lookup[state_]->front();
                 std::size_t const* dfa_ = &sm_.data()._dfa[state_]->front();
 
- os_ << " static std::size_t const lookup" << state_
+ os_ << " static std::size_t const lookup" << state_
                     << "_[" << lookups_ << "] = {\n ";
                 for (/**/; i_ < count_; ++i_)
                 {
@@ -203,7 +259,7 @@
             std::size_t count_ = sm_.data()._dfa_alphabet.size();
             std::size_t i_ = 1;
 
- os_ << " static std::size_t const* lookup_arr_[" << count_
+ os_ << " static std::size_t const* lookup_arr_[" << count_
                 << "] = { lookup0_";
             for (i_ = 1; i_ < count_; ++i_)
             {
@@ -211,7 +267,7 @@
             }
             os_ << " };\n";
 
- os_ << " static std::size_t const dfa_alphabet_arr_["
+ os_ << " static std::size_t const dfa_alphabet_arr_["
                 << count_ << "] = { ";
             os_ << sm_.data()._dfa_alphabet.front ();
             for (i_ = 1; i_ < count_; ++i_)
@@ -220,7 +276,7 @@
             }
             os_ << " };\n";
 
- os_ << " static std::size_t const* dfa_arr_[" << count_
+ os_ << " static std::size_t const* dfa_arr_[" << count_
                 << "] = { ";
             os_ << "dfa0_";
             for (i_ = 1; i_ < count_; ++i_)
@@ -255,9 +311,9 @@
             }
             os_ << " };\n";
 
- os_ << " static std::size_t const dfa_alphabet_ = "
+ os_ << " static std::size_t const dfa_alphabet_ = "
                 << sm_.data()._dfa_alphabet.front () << ";\n";
- os_ << " static std::size_t const dfa_["
+ os_ << " static std::size_t const dfa_["
                 << sm_.data()._dfa[0]->size () << "] = {\n ";
             count_ = sm_.data()._dfa[0]->size () / 8;
             for (i_ = 0; i_ < count_; ++i_)
@@ -534,10 +590,10 @@
 
     ///////////////////////////////////////////////////////////////////////////
     template <typename Char>
- inline std::string get_charlit(Char ch)
+ inline std::basic_string<Char> get_charlit(Char ch)
     {
         std::basic_string<Char> result;
- boost::lexer::basic_string_token<Char>::escape_char (ch, result);
+ boost::lexer::basic_string_token<Char>::escape_char(ch, result);
         return result;
     }
 
@@ -573,8 +629,8 @@
 
     ///////////////////////////////////////////////////////////////////////////
     template <typename Char>
- bool generate_function_body_switch(std::ostream & os_
- , boost::lexer::basic_state_machine<Char> const &sm_)
+ bool generate_function_body_switch(std::basic_ostream<Char> & os_
+ , boost::lexer::basic_state_machine<Char> const &sm_)
     {
         typedef typename boost::lexer::basic_state_machine<Char>::iterator
             iterator_type;
@@ -622,7 +678,7 @@
         os_ << " Iterator end_token_ = start_token_;\n";
         os_ << '\n';
 
- os_ << " " << ((lookups_ == 256) ? "char" : "wchar_t")
+ os_ << " " << ((lookups_ == 256) ? "char" : "wchar_t")
             << " ch_ = 0;\n\n";
 
         if (dfas_ > 1)
@@ -679,7 +735,7 @@
                     if (transitions_) os_ << '\n';
                 }
 
- if (t_ < transitions_ ||
+ if (t_ < transitions_ ||
                     iter_->bol_index != boost::lexer::npos ||
                     iter_->eol_index != boost::lexer::npos)
                 {
@@ -687,12 +743,12 @@
                     os_ << " ch_ = *curr_;\n";
                     if (iter_->bol_index != boost::lexer::npos)
                     {
- os_ << "\n if (bol) goto state" << dfa_ << '_'
+ os_ << "\n if (bol) goto state" << dfa_ << '_'
                             << iter_->bol_index << ";\n";
                     }
                     if (iter_->eol_index != boost::lexer::npos)
                     {
- os_ << "\n if (ch_ == '\n') goto state" << dfa_
+ os_ << "\n if (ch_ == '\n') goto state" << dfa_
                             << '_' << iter_->eol_index << ";\n";
                     }
                     os_ << " ++curr_;\n";
@@ -700,10 +756,10 @@
 
                 for (/**/; t_ < transitions_; ++t_)
                 {
- char const *ptr_ = iter_->token._charset.c_str();
- char const *end_ = ptr_ + iter_->token._charset.size();
- char start_char_ = 0;
- char curr_char_ = 0;
+ Char const *ptr_ = iter_->token._charset.c_str();
+ Char const *end_ = ptr_ + iter_->token._charset.size();
+ Char start_char_ = 0;
+ Char curr_char_ = 0;
                     bool range_ = false;
                     bool first_char_ = true;
 
@@ -727,7 +783,7 @@
                             {
                                 os_ << ((iter_->token._negated) ? " && " : " || ");
                             }
- else
+ else
                             {
                                 first_char_ = false;
                             }
@@ -738,20 +794,20 @@
                                     os_ << "!";
                                 }
                                 os_ << "(ch_ >= '" << get_charlit(start_char_)
- << "' && ch_ <= '"
+ << "' && ch_ <= '"
                                     << get_charlit(curr_char_) << "')";
                                 range_ = false;
                             }
                             else
                             {
- os_ << "ch_ "
+ os_ << "ch_ "
                                     << ((iter_->token._negated) ? "!=" : "==")
                                     << " '" << get_charlit(curr_char_) << "'";
                             }
                         }
                     }
 
- os_ << ") goto state" << dfa_ << '_' << iter_->goto_state
+ os_ << ") goto state" << dfa_ << '_' << iter_->goto_state
                         << ";\n";
                     ++iter_;
                 }
@@ -818,10 +874,11 @@
     ///////////////////////////////////////////////////////////////////////////
     // Generate a tokenizer for the given state machine.
     template <typename Char, typename F>
- inline bool
+ inline bool
     generate_cpp (boost::lexer::basic_state_machine<Char> const& sm_
       , boost::lexer::basic_rules<Char> const& rules_
- , std::ostream &os_, char const* name_suffix, F generate_function_body)
+ , std::basic_ostream<Char> &os_, Char const* name_suffix
+ , F generate_function_body)
     {
         if (sm_.data()._lookup->empty())
             return false;
@@ -838,14 +895,14 @@
             "http://www.boost.org/LICENSE_1_0.txt)\n\n";
         os_ << "// Auto-generated by boost::lexer, do not edit\n\n";
 
- std::string guard(name_suffix);
- guard += name_suffix[0] ? "_" : "";
- guard += __DATE__ "_" __TIME__;
- std::string::size_type p = guard.find_first_of(": ");
- while (std::string::npos != p)
+ std::basic_string<Char> guard(name_suffix);
+ guard += L<Char>(name_suffix[0] ? "_" : "");
+ guard += L<Char>(__DATE__ "_" __TIME__);
+ std::basic_string<Char>::size_type p = guard.find_first_of(L<Char>(": "));
+ while (std::string::npos != p)
         {
- guard.replace(p, 1, "_");
- p = guard.find_first_of(": ", p);
+ guard.replace(p, 1, L<Char>("_"));
+ p = guard.find_first_of(L<Char>(": "), p);
         }
         boost::to_upper(guard);
 
@@ -868,14 +925,14 @@
         generate_delimiter(os_);
         os_ << "// this function returns the next matched token\n";
         os_ << "template<typename Iterator>\n";
- os_ << "std::size_t next_token" << (name_suffix[0] ? "_" : "")
+ os_ << "std::size_t next_token" << (name_suffix[0] ? "_" : "")
             << name_suffix << " (";
 
         if (dfas_ > 1)
         {
             os_ << "std::size_t& start_state_, ";
         }
- else
+ else
         {
             os_ << "std::size_t& /*start_state_*/, ";
         }
@@ -883,7 +940,7 @@
         {
             os_ << "bool& bol_, ";
         }
- else
+ else
         {
             os_ << "bool& /*bol_*/, ";
         }
@@ -896,7 +953,7 @@
             return false;
         os_ << "}\n\n";
 
- if (!generate_cpp_state_table(os_, name_suffix
+ if (!generate_cpp_state_table<Char>(os_, name_suffix
             , sm_.data()._seen_BOL_assertion, sm_.data()._seen_EOL_assertion))
         {
             return false;
@@ -913,9 +970,10 @@
 
     ///////////////////////////////////////////////////////////////////////////
     template <typename Lexer, typename F>
- inline bool
- generate_static(Lexer const& lexer, std::ostream& os
- , char const* name_suffix, F f)
+ inline bool
+ generate_static(Lexer const& lexer
+ , std::basic_ostream<typename Lexer::char_type>& os
+ , typename Lexer::char_type const* name_suffix, F f)
     {
         if (!lexer.init_dfa(true)) // always minimize DFA for static lexers
             return false;
@@ -924,12 +982,14 @@
     }
 
     ///////////////////////////////////////////////////////////////////////////
- // deprecated function, will be removed in the future (this has been
+ // deprecated function, will be removed in the future (this has been
     // replaced by the function generate_static_dfa - see below).
     template <typename Lexer>
- inline bool
- generate_static(Lexer const& lexer, std::ostream& os
- , char const* name_suffix = "")
+ inline bool
+ generate_static(Lexer const& lexer
+ , std::basic_ostream<typename Lexer::char_type>& os
+ , typename Lexer::char_type const* name_suffix =
+ detail::L<typename Lexer::char_type>())
     {
         return generate_static(lexer, os, name_suffix
           , &detail::generate_function_body_dfa<typename Lexer::char_type>);
@@ -937,9 +997,11 @@
 
     ///////////////////////////////////////////////////////////////////////////
     template <typename Lexer>
- inline bool
- generate_static_dfa(Lexer const& lexer, std::ostream& os
- , char const* name_suffix = "")
+ inline bool
+ generate_static_dfa(Lexer const& lexer
+ , std::basic_ostream<typename Lexer::char_type>& os
+ , typename Lexer::char_type const* name_suffix =
+ detail::L<typename Lexer::char_type>())
     {
         return generate_static(lexer, os, name_suffix
           , &detail::generate_function_body_dfa<typename Lexer::char_type>);
@@ -947,9 +1009,11 @@
 
     ///////////////////////////////////////////////////////////////////////////
     template <typename Lexer>
- inline bool
- generate_static_switch(Lexer const& lexer, std::ostream& os
- , char const* name_suffix = "")
+ inline bool
+ generate_static_switch(Lexer const& lexer
+ , std::basic_ostream<typename Lexer::char_type>& os
+ , typename Lexer::char_type const* name_suffix =
+ detail::L<typename Lexer::char_type>())
     {
         return generate_static(lexer, os, name_suffix
           , &detail::generate_function_body_switch<typename Lexer::char_type>);

Modified: trunk/boost/spirit/home/lex/lexer/lexertl/lexer.hpp
==============================================================================
--- trunk/boost/spirit/home/lex/lexer/lexertl/lexer.hpp (original)
+++ trunk/boost/spirit/home/lex/lexer/lexertl/lexer.hpp 2011-12-11 19:48:40 EST (Sun, 11 Dec 2011)
@@ -1,6 +1,6 @@
 // Copyright (c) 2001-2011 Hartmut Kaiser
-//
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
 #if !defined(BOOST_SPIRIT_LEX_LEXER_MAR_17_2007_0139PM)
@@ -28,13 +28,13 @@
 #include <boost/foreach.hpp>
 
 namespace boost { namespace spirit { namespace lex { namespace lexertl
-{
+{
     ///////////////////////////////////////////////////////////////////////////
     namespace detail
     {
         ///////////////////////////////////////////////////////////////////////
         // The must_escape function checks if the given character value needs
- // to be preceded by a backslash character to disable its special
+ // to be preceded by a backslash character to disable its special
         // meaning in the context of a regular expression
         ///////////////////////////////////////////////////////////////////////
         template <typename Char>
@@ -60,15 +60,15 @@
         }
 
         ///////////////////////////////////////////////////////////////////////
- // The escape function returns the string representation of the given
- // character value, possibly escaped with a backslash character, to
+ // The escape function returns the string representation of the given
+ // character value, possibly escaped with a backslash character, to
         // allow it being safely used in a regular expression definition.
         ///////////////////////////////////////////////////////////////////////
         template <typename Char>
- inline std::basic_string<Char> escape(Char ch)
- {
+ inline std::basic_string<Char> escape(Char ch)
+ {
             std::basic_string<Char> result(1, ch);
- if (detail::must_escape(ch))
+ if (detail::must_escape(ch))
             {
                 typedef typename std::basic_string<Char>::size_type size_type;
                 result.insert((size_type)0, 1, '\\');
@@ -77,7 +77,7 @@
         }
 
         ///////////////////////////////////////////////////////////////////////
- //
+ //
         ///////////////////////////////////////////////////////////////////////
         inline boost::lexer::regex_flags map_flags(unsigned int flags)
         {
@@ -93,31 +93,33 @@
 
     ///////////////////////////////////////////////////////////////////////////
     template <typename Lexer, typename F>
- bool generate_static(Lexer const&, std::ostream&, char const*, F);
+ bool generate_static(Lexer const&
+ , std::basic_ostream<typename Lexer::char_type>&
+ , typename Lexer::char_type const*, F);
 
     ///////////////////////////////////////////////////////////////////////////
     //
- // Every lexer type to be used as a lexer for Spirit has to conform to
+ // Every lexer type to be used as a lexer for Spirit has to conform to
     // the following public interface:
     //
- // typedefs:
+ // typedefs:
     // iterator_type The type of the iterator exposed by this lexer.
- // token_type The type of the tokens returned from the exposed
+ // token_type The type of the tokens returned from the exposed
     // iterators.
     //
     // functions:
     // default constructor
- // Since lexers are instantiated as base classes
- // only it might be a good idea to make this
+ // Since lexers are instantiated as base classes
+ // only it might be a good idea to make this
     // constructor protected.
     // begin, end Return a pair of iterators, when dereferenced
- // returning the sequence of tokens recognized in
- // the input stream given as the parameters to the
+ // returning the sequence of tokens recognized in
+ // the input stream given as the parameters to the
     // begin() function.
- // add_token Should add the definition of a token to be
+ // add_token Should add the definition of a token to be
     // recognized by this lexer.
     // clear Should delete all current token definitions
- // associated with the given state of this lexer
+ // associated with the given state of this lexer
     // object.
     //
     // template parameters:
@@ -126,25 +128,25 @@
     // Token The type of the tokens to be returned from the
     // exposed token iterator.
     // Functor The type of the InputPolicy to use to instantiate
- // the multi_pass iterator type to be used as the
+ // the multi_pass iterator type to be used as the
     // token iterator (returned from begin()/end()).
     //
     ///////////////////////////////////////////////////////////////////////////
 
     ///////////////////////////////////////////////////////////////////////////
     //
- // The lexer class is a implementation of a Spirit.Lex lexer on
- // top of Ben Hanson's lexertl library as outlined above (For more
+ // The lexer class is a implementation of a Spirit.Lex lexer on
+ // top of Ben Hanson's lexertl library as outlined above (For more
     // information about lexertl go here: http://www.benhanson.net/lexertl.html).
     //
- // This class is supposed to be used as the first and only template
+ // This class is supposed to be used as the first and only template
     // parameter while instantiating instances of a lex::lexer class.
     //
     ///////////////////////////////////////////////////////////////////////////
     template <typename Token = token<>
       , typename Iterator = typename Token::iterator_type
       , typename Functor = functor<Token, lexertl::detail::data, Iterator> >
- class lexer
+ class lexer
     {
     private:
         struct dummy { void true_() {} };
@@ -156,13 +158,13 @@
         operator safe_bool() const
             { return initialized_dfa_ ? &dummy::true_ : 0; }
 
- typedef typename boost::detail::iterator_traits<Iterator>::value_type
+ typedef typename boost::detail::iterator_traits<Iterator>::value_type
             char_type;
         typedef std::basic_string<char_type> string_type;
 
         typedef boost::lexer::basic_rules<char_type> basic_rules_type;
 
- // Every lexer type to be used as a lexer for Spirit has to conform to
+ // Every lexer type to be used as a lexer for Spirit has to conform to
         // a public interface .
         typedef Token token_type;
         typedef typename Token::id_type id_type;
@@ -170,7 +172,7 @@
 
     private:
         // this type is purely used for the iterator_type construction below
- struct iterator_data_type
+ struct iterator_data_type
         {
             typedef typename Functor::semantic_actions_type semantic_actions_type;
 
@@ -195,7 +197,7 @@
         // tokens.
         iterator_type begin(Iterator& first, Iterator const& last
           , char_type const* initial_state = 0) const
- {
+ {
             if (!init_dfa()) // never minimize DFA for dynamic lexers
                 return iterator_type();
 
@@ -203,16 +205,16 @@
             return iterator_type(iterator_data, first, last, initial_state);
         }
 
- // Return the end iterator usable to stop iterating over the generated
+ // Return the end iterator usable to stop iterating over the generated
         // tokens.
         iterator_type end() const
- {
- return iterator_type();
+ {
+ return iterator_type();
         }
 
     protected:
         // Lexer instances can be created by means of a derived class only.
- lexer(unsigned int flags)
+ lexer(unsigned int flags)
           : flags_(detail::map_flags(flags))
           , rules_(flags_)
           , initialized_dfa_(false)
@@ -220,7 +222,7 @@
 
     public:
         // interface for token definition management
- std::size_t add_token(char_type const* state, char_type tokendef,
+ std::size_t add_token(char_type const* state, char_type tokendef,
             std::size_t token_id, char_type const* targetstate)
         {
             add_state(state);
@@ -234,7 +236,7 @@
                 add_state(targetstate);
             return rules_.add(state, detail::escape(tokendef), token_id, targetstate);
         }
- std::size_t add_token(char_type const* state, string_type const& tokendef,
+ std::size_t add_token(char_type const* state, string_type const& tokendef,
             std::size_t token_id, char_type const* targetstate)
         {
             add_state(state);
@@ -269,7 +271,7 @@
         }
         std::size_t add_state(char_type const* state)
         {
- if (state == all_states())
+ if (state == all_states())
                 return all_states_id;
 
             std::size_t stateid = rules_.state(state);
@@ -279,12 +281,12 @@
             }
             return stateid;
         }
- string_type initial_state() const
- {
+ string_type initial_state() const
+ {
             return string_type(rules_.initial());
         }
- string_type all_states() const
- {
+ string_type all_states() const
+ {
             return string_type(rules_.all_states());
         }
 
@@ -293,14 +295,14 @@
         void add_action(std::size_t unique_id, std::size_t state, F act)
         {
             // If you see an error here stating add_action is not a member of
- // fusion::unused_type then you are probably having semantic actions
+ // fusion::unused_type then you are probably having semantic actions
             // attached to at least one token in the lexer definition without
             // using the lex::lexertl::actor_lexer<> as its base class.
             typedef typename Functor::wrap_action_type wrapper_type;
             if (state == all_states_id) {
                 // add the action to all known states
- typedef typename
- basic_rules_type::string_size_t_map::value_type
+ typedef typename
+ basic_rules_type::string_size_t_map::value_type
                 state_type;
 
                 std::size_t states = rules_.statemap().size();
@@ -320,8 +322,8 @@
 // actions_.add_action(unique_id, add_state(state), wrapper_type::call(act));
 // }
 
- // We do not minimize the state machine by default anymore because
- // Ben said: "If you can afford to generate a lexer at runtime, there
+ // We do not minimize the state machine by default anymore because
+ // Ben said: "If you can afford to generate a lexer at runtime, there
         // is little point in calling minimise."
         // Go figure.
         bool init_dfa(bool minimize = false) const
@@ -356,26 +358,28 @@
         mutable bool initialized_dfa_;
 
         // generator functions must be able to access members directly
- template <typename Lexer, typename F>
- friend bool generate_static(Lexer const&, std::ostream&, char const*, F);
+ template <typename Lexer, typename F>
+ friend bool generate_static(Lexer const&
+ , std::basic_ostream<typename Lexer::char_type>&
+ , typename Lexer::char_type const*, F);
     };
 
     ///////////////////////////////////////////////////////////////////////////
     //
- // The actor_lexer class is another implementation of a Spirit.Lex
- // lexer on top of Ben Hanson's lexertl library as outlined above (For
- // more information about lexertl go here:
+ // The actor_lexer class is another implementation of a Spirit.Lex
+ // lexer on top of Ben Hanson's lexertl library as outlined above (For
+ // more information about lexertl go here:
     // http://www.benhanson.net/lexertl.html).
     //
     // The only difference to the lexer class above is that token_def
- // definitions may have semantic (lexer) actions attached while being
+ // definitions may have semantic (lexer) actions attached while being
     // defined:
     //
     // int w;
     // token_def word = "[^ \t\n]+";
     // self = word[++ref(w)]; // see example: word_count_lexer
     //
- // This class is supposed to be used as the first and only template
+ // This class is supposed to be used as the first and only template
     // parameter while instantiating instances of a lex::lexer class.
     //
     ///////////////////////////////////////////////////////////////////////////
@@ -386,7 +390,7 @@
     {
     protected:
         // Lexer instances can be created by means of a derived class only.
- actor_lexer(unsigned int flags)
+ actor_lexer(unsigned int flags)
           : lexer<Token, Iterator, Functor>(flags) {}
     };
 

Modified: trunk/boost/spirit/home/support/detail/lexer/rules.hpp
==============================================================================
--- trunk/boost/spirit/home/support/detail/lexer/rules.hpp (original)
+++ trunk/boost/spirit/home/support/detail/lexer/rules.hpp 2011-12-11 19:48:40 EST (Sun, 11 Dec 2011)
@@ -44,6 +44,16 @@
         {
             return "*";
         }
+
+ static const char *char_name ()
+ {
+ return "char";
+ }
+
+ static const char *char_prefix ()
+ {
+ return "";
+ }
     };
 
     template <>
@@ -63,6 +73,16 @@
         {
             return L"*";
         }
+
+ static const char *char_name ()
+ {
+ return "wchar_t";
+ }
+
+ static const char *char_prefix ()
+ {
+ return "L";
+ }
     };
 }
 

Modified: trunk/libs/spirit/test/Jamfile
==============================================================================
--- trunk/libs/spirit/test/Jamfile (original)
+++ trunk/libs/spirit/test/Jamfile 2011-12-11 19:48:40 EST (Sun, 11 Dec 2011)
@@ -297,6 +297,7 @@
      [ run lex/regression_file_iterator2.cpp : : : : lex_regression_file_iterator2 ]
      [ run lex/regression_file_iterator3.cpp : : : : lex_regression_file_iterator3 ]
      [ run lex/regression_file_iterator4.cpp : : : : lex_regression_file_iterator4 ]
+ [ run lex/regression_static_wide_6253.cpp : : : : regression_static_wide_6253 ]
 
     ;
 

Added: trunk/libs/spirit/test/lex/regression_static_wide_6253.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/spirit/test/lex/regression_static_wide_6253.cpp 2011-12-11 19:48:40 EST (Sun, 11 Dec 2011)
@@ -0,0 +1,44 @@
+// Copyright (c) 2001-2011 Hartmut Kaiser
+// Copyright (c) 2011 Ryan Molden
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/config/warning_disable.hpp>
+
+#include <boost/spirit/include/lex_lexertl.hpp>
+#include <boost/spirit/include/lex_generate_static_lexertl.hpp>
+#include <boost/spirit/include/lex_static_lexertl.hpp>
+
+#include <fstream>
+
+using namespace std;
+using namespace boost::spirit;
+
+template <typename BaseLexer>
+struct my_lexer : boost::spirit::lex::lexer<BaseLexer>
+{
+ my_lexer()
+ {
+ token = L"Yay winning!";
+ this->self = token;
+ }
+
+ lex::token_def<lex::unused_type, wchar_t> token;
+};
+
+int main(int argc, char* argv[])
+{
+ typedef lex::lexertl::token<wchar_t const*> token_type;
+ typedef lex::lexertl::lexer<token_type> lexer_type;
+
+ my_lexer<lexer_type> lexer;
+
+ basic_ofstream<wchar_t> output_dfa("test_dfa.hpp");
+ BOOST_TEST(lex::lexertl::generate_static_dfa(lexer, output_dfa, L"test_dfa"));
+
+ basic_ofstream<wchar_t> output_switch("test_switch.hpp");
+ BOOST_TEST(lex::lexertl::generate_static_switch(lexer, output_switch, L"test_switch"));
+ return boost::report_errors();
+}


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk