os/ossrv/ossrv_pub/boost_apis/boost/spirit/symbols/symbols.hpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 /*=============================================================================
     2     Copyright (c) 2001-2003 Joel de Guzman
     3     http://spirit.sourceforge.net/
     4 
     5     Use, modification and distribution is subject to the Boost Software
     6     License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
     7     http://www.boost.org/LICENSE_1_0.txt)
     8 =============================================================================*/
     9 #ifndef BOOST_SPIRIT_SYMBOLS_HPP
    10 #define BOOST_SPIRIT_SYMBOLS_HPP
    11 
    12 ///////////////////////////////////////////////////////////////////////////////
    13 #include <string>
    14 
    15 #include <boost/ref.hpp>
    16 
    17 #include <boost/spirit/core/parser.hpp>
    18 #include <boost/spirit/core/composite/directives.hpp>
    19 
    20 #include <boost/spirit/symbols/symbols_fwd.hpp>
    21 
    22 
    23 ///////////////////////////////////////////////////////////////////////////////
    24 namespace boost { namespace spirit {
    25 
    26 ///////////////////////////////////////////////////////////////////////////////
    27 //
    28 //  symbols class
    29 //
    30 //      This class implements a symbol table. The symbol table holds a
    31 //      dictionary of symbols where each symbol is a sequence of CharTs.
    32 //      The template class can work efficiently with 8, 16 and 32 bit
    33 //      characters. Mutable data of type T is associated with each
    34 //      symbol.
    35 //
    36 //      The class is a parser. The parse member function returns
    37 //      additional information in the symbol_match class (see below).
    38 //      The additional data is a pointer to some data associated with
    39 //      the matching symbol.
    40 //
    41 //      The actual set implementation is supplied by the SetT template
    42 //      parameter. By default, this uses the tst class (see tst.ipp).
    43 //
    44 //      Symbols are added into the symbol table statically using the
    45 //      construct:
    46 //
    47 //          sym = a, b, c, d ...;
    48 //
    49 //      where sym is a symbol table and a..d are strings. Example:
    50 //
    51 //          sym = "pineapple", "orange", "banana", "apple";
    52 //
    53 //      Alternatively, symbols may be added dynamically through the
    54 //      member functor 'add' (see symbol_inserter below). The member
    55 //      functor 'add' may be attached to a parser as a semantic action
    56 //      taking in a begin/end pair:
    57 //
    58 //          p[sym.add]
    59 //
    60 //      where p is a parser (and sym is a symbol table). On success,
    61 //      the matching portion of the input is added to the symbol table.
    62 //
    63 //      'add' may also be used to directly initialize data. Examples:
    64 //
    65 //          sym.add("hello", 1)("crazy", 2)("world", 3);
    66 //
    67 ///////////////////////////////////////////////////////////////////////////////
    68 template <typename T, typename CharT, typename SetT>
    69 class symbols
    70 :   private SetT
    71 ,   public parser<symbols<T, CharT, SetT> >
    72 {
    73 public:
    74 
    75     typedef parser<symbols<T, CharT, SetT> > parser_base_t;
    76     typedef symbols<T, CharT, SetT> self_t;
    77     typedef self_t const& embed_t;
    78     typedef T symbol_data_t;
    79     typedef boost::reference_wrapper<T> symbol_ref_t;
    80 
    81     symbols();
    82     symbols(symbols const& other);
    83     ~symbols();
    84 
    85     symbols&
    86     operator=(symbols const& other);
    87 
    88     symbol_inserter<T, SetT> const&
    89     operator=(CharT const* str);
    90 
    91     template <typename ScannerT>
    92     struct result
    93     {
    94         typedef typename match_result<ScannerT, symbol_ref_t>::type type;
    95     };
    96 
    97     template <typename ScannerT>
    98     typename parser_result<self_t, ScannerT>::type
    99     parse_main(ScannerT const& scan) const
   100     {
   101         typedef typename ScannerT::iterator_t iterator_t;
   102         iterator_t first = scan.first;
   103         typename SetT::search_info result = SetT::find(scan);
   104 
   105         if (result.data)
   106             return scan.
   107                 create_match(
   108                     result.length,
   109                     symbol_ref_t(*result.data),
   110                     first,
   111                     scan.first);
   112         else
   113             return scan.no_match();
   114     }
   115 
   116     template <typename ScannerT>
   117     typename parser_result<self_t, ScannerT>::type
   118     parse(ScannerT const& scan) const
   119     {
   120         typedef typename parser_result<self_t, ScannerT>::type result_t;
   121         return impl::implicit_lexeme_parse<result_t>
   122             (*this, scan, scan);
   123     }
   124 
   125     template < typename ScannerT >
   126     T* find(ScannerT const& scan) const
   127     { return SetT::find(scan).data; }
   128 
   129     symbol_inserter<T, SetT> const add;
   130 };
   131 
   132 ///////////////////////////////////////////////////////////////////////////////
   133 //
   134 //  Symbol table utilities
   135 //
   136 //  add
   137 //
   138 //      adds a symbol 'sym' (string) to a symbol table 'table' plus an
   139 //      optional data 'data' associated with the symbol. Returns a pointer to
   140 //      the data associated with the symbol or NULL if add failed (e.g. when
   141 //      the symbol is already added before).
   142 //
   143 //  find
   144 //
   145 //      finds a symbol 'sym' (string) from a symbol table 'table'. Returns a
   146 //      pointer to the data associated with the symbol or NULL if not found
   147 //
   148 ///////////////////////////////////////////////////////////////////////////////
   149 template <typename T, typename CharT, typename SetT>
   150 T*  add(symbols<T, CharT, SetT>& table, CharT const* sym, T const& data = T());
   151 
   152 template <typename T, typename CharT, typename SetT>
   153 T*  find(symbols<T, CharT, SetT> const& table, CharT const* sym);
   154 
   155 ///////////////////////////////////////////////////////////////////////////////
   156 //
   157 //  symbol_inserter class
   158 //
   159 //      The symbols class holds an instance of this class named 'add'.
   160 //      This can be called directly just like a member function,
   161 //      passing in a first/last iterator and optional data:
   162 //
   163 //          sym.add(first, last, data);
   164 //
   165 //      Or, passing in a C string and optional data:
   166 //
   167 //          sym.add(c_string, data);
   168 //
   169 //      where sym is a symbol table. The 'data' argument is optional.
   170 //      This may also be used as a semantic action since it conforms
   171 //      to the action interface (see action.hpp):
   172 //
   173 //          p[sym.add]
   174 //
   175 ///////////////////////////////////////////////////////////////////////////////
   176 template <typename T, typename SetT>
   177 class symbol_inserter
   178 {
   179 public:
   180 
   181     symbol_inserter(SetT& set_)
   182     : set(set_) {}
   183 
   184     typedef symbol_inserter const & result_type;
   185 
   186     template <typename IteratorT>
   187     symbol_inserter const&
   188     operator()(IteratorT first, IteratorT const& last, T const& data = T()) const
   189     {
   190         set.add(first, last, data);
   191         return *this;
   192     }
   193 
   194     template <typename CharT>
   195     symbol_inserter const&
   196     operator()(CharT const* str, T const& data = T()) const
   197     {
   198         CharT const* last = str;
   199         while (*last)
   200             last++;
   201         set.add(str, last, data);
   202         return *this;
   203     }
   204 
   205     template <typename CharT>
   206     symbol_inserter const&
   207     operator,(CharT const* str) const
   208     {
   209         CharT const* last = str;
   210         while (*last)
   211             last++;
   212         set.add(str, last, T());
   213         return *this;
   214     }
   215 
   216 private:
   217 
   218     SetT& set;
   219 };
   220 
   221 ///////////////////////////////////////////////////////////////////////////////
   222 }} // namespace boost::spirit
   223 
   224 #include <boost/spirit/symbols/impl/symbols.ipp>
   225 #endif