Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:02:05

0001 /*=============================================================================
0002     Copyright (c) 2001-2003 Joel de Guzman
0003     http://spirit.sourceforge.net/
0004 
0005   Distributed under the Boost Software License, Version 1.0. (See accompanying
0006   file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 =============================================================================*/
0008 #ifndef BOOST_SPIRIT_SYMBOLS_HPP
0009 #define BOOST_SPIRIT_SYMBOLS_HPP
0010 
0011 ///////////////////////////////////////////////////////////////////////////////
0012 #include <string>
0013 
0014 #include <boost/ref.hpp>
0015 
0016 #include <boost/spirit/home/classic/namespace.hpp>
0017 #include <boost/spirit/home/classic/core/parser.hpp>
0018 #include <boost/spirit/home/classic/core/composite/directives.hpp>
0019 
0020 #include <boost/spirit/home/classic/symbols/symbols_fwd.hpp>
0021 
0022 
0023 ///////////////////////////////////////////////////////////////////////////////
0024 namespace boost { namespace spirit {
0025 
0026 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN
0027 
0028 ///////////////////////////////////////////////////////////////////////////////
0029 //
0030 //  symbols class
0031 //
0032 //      This class implements a symbol table. The symbol table holds a
0033 //      dictionary of symbols where each symbol is a sequence of CharTs.
0034 //      The template class can work efficiently with 8, 16 and 32 bit
0035 //      characters. Mutable data of type T is associated with each
0036 //      symbol.
0037 //
0038 //      The class is a parser. The parse member function returns
0039 //      additional information in the symbol_match class (see below).
0040 //      The additional data is a pointer to some data associated with
0041 //      the matching symbol.
0042 //
0043 //      The actual set implementation is supplied by the SetT template
0044 //      parameter. By default, this uses the tst class (see tst.ipp).
0045 //
0046 //      Symbols are added into the symbol table statically using the
0047 //      construct:
0048 //
0049 //          sym = a, b, c, d ...;
0050 //
0051 //      where sym is a symbol table and a..d are strings. Example:
0052 //
0053 //          sym = "pineapple", "orange", "banana", "apple";
0054 //
0055 //      Alternatively, symbols may be added dynamically through the
0056 //      member functor 'add' (see symbol_inserter below). The member
0057 //      functor 'add' may be attached to a parser as a semantic action
0058 //      taking in a begin/end pair:
0059 //
0060 //          p[sym.add]
0061 //
0062 //      where p is a parser (and sym is a symbol table). On success,
0063 //      the matching portion of the input is added to the symbol table.
0064 //
0065 //      'add' may also be used to directly initialize data. Examples:
0066 //
0067 //          sym.add("hello", 1)("crazy", 2)("world", 3);
0068 //
0069 ///////////////////////////////////////////////////////////////////////////////
0070 template <typename T, typename CharT, typename SetT>
0071 class symbols
0072 :   private SetT
0073 ,   public parser<symbols<T, CharT, SetT> >
0074 {
0075 public:
0076 
0077     typedef parser<symbols<T, CharT, SetT> > parser_base_t;
0078     typedef symbols<T, CharT, SetT> self_t;
0079     typedef self_t const& embed_t;
0080     typedef T symbol_data_t;
0081     typedef boost::reference_wrapper<T> symbol_ref_t;
0082 
0083     symbols();
0084     symbols(symbols const& other);
0085     ~symbols();
0086 
0087     symbols&
0088     operator=(symbols const& other);
0089 
0090     symbol_inserter<T, SetT> const&
0091     operator=(CharT const* str);
0092 
0093     template <typename ScannerT>
0094     struct result
0095     {
0096         typedef typename match_result<ScannerT, symbol_ref_t>::type type;
0097     };
0098 
0099     template <typename ScannerT>
0100     typename parser_result<self_t, ScannerT>::type
0101     parse_main(ScannerT const& scan) const
0102     {
0103         typedef typename ScannerT::iterator_t iterator_t;
0104         iterator_t first = scan.first;
0105         typename SetT::search_info result = SetT::find(scan);
0106 
0107         if (result.data)
0108             return scan.
0109                 create_match(
0110                     result.length,
0111                     symbol_ref_t(*result.data),
0112                     first,
0113                     scan.first);
0114         else
0115             return scan.no_match();
0116     }
0117 
0118     template <typename ScannerT>
0119     typename parser_result<self_t, ScannerT>::type
0120     parse(ScannerT const& scan) const
0121     {
0122         typedef typename parser_result<self_t, ScannerT>::type result_t;
0123         return impl::implicit_lexeme_parse<result_t>
0124             (*this, scan, scan);
0125     }
0126 
0127     template < typename ScannerT >
0128     T* find(ScannerT const& scan) const
0129     { return SetT::find(scan).data; }
0130 
0131     symbol_inserter<T, SetT> const add;
0132 };
0133 
0134 ///////////////////////////////////////////////////////////////////////////////
0135 //
0136 //  Symbol table utilities
0137 //
0138 //  add
0139 //
0140 //      adds a symbol 'sym' (string) to a symbol table 'table' plus an
0141 //      optional data 'data' associated with the symbol. Returns a pointer to
0142 //      the data associated with the symbol or NULL if add failed (e.g. when
0143 //      the symbol is already added before).
0144 //
0145 //  find
0146 //
0147 //      finds a symbol 'sym' (string) from a symbol table 'table'. Returns a
0148 //      pointer to the data associated with the symbol or NULL if not found
0149 //
0150 ///////////////////////////////////////////////////////////////////////////////
0151 template <typename T, typename CharT, typename SetT>
0152 T*  add(symbols<T, CharT, SetT>& table, CharT const* sym, T const& data = T());
0153 
0154 template <typename T, typename CharT, typename SetT>
0155 T*  find(symbols<T, CharT, SetT> const& table, CharT const* sym);
0156 
0157 ///////////////////////////////////////////////////////////////////////////////
0158 //
0159 //  symbol_inserter class
0160 //
0161 //      The symbols class holds an instance of this class named 'add'.
0162 //      This can be called directly just like a member function,
0163 //      passing in a first/last iterator and optional data:
0164 //
0165 //          sym.add(first, last, data);
0166 //
0167 //      Or, passing in a C string and optional data:
0168 //
0169 //          sym.add(c_string, data);
0170 //
0171 //      where sym is a symbol table. The 'data' argument is optional.
0172 //      This may also be used as a semantic action since it conforms
0173 //      to the action interface (see action.hpp):
0174 //
0175 //          p[sym.add]
0176 //
0177 ///////////////////////////////////////////////////////////////////////////////
0178 template <typename T, typename SetT>
0179 class symbol_inserter
0180 {
0181 public:
0182 
0183     symbol_inserter(SetT& set_)
0184     : set(set_) {}
0185 
0186     typedef symbol_inserter const & result_type;
0187 
0188     template <typename IteratorT>
0189     symbol_inserter const&
0190     operator()(IteratorT first, IteratorT const& last, T const& data = T()) const
0191     {
0192         set.add(first, last, data);
0193         return *this;
0194     }
0195 
0196     template <typename CharT>
0197     symbol_inserter const&
0198     operator()(CharT const* str, T const& data = T()) const
0199     {
0200         CharT const* last = str;
0201         while (*last)
0202             last++;
0203         set.add(str, last, data);
0204         return *this;
0205     }
0206 
0207     template <typename CharT>
0208     symbol_inserter const&
0209     operator,(CharT const* str) const
0210     {
0211         CharT const* last = str;
0212         while (*last)
0213             last++;
0214         set.add(str, last, T());
0215         return *this;
0216     }
0217 
0218 private:
0219 
0220     SetT& set;
0221 };
0222 
0223 ///////////////////////////////////////////////////////////////////////////////
0224 BOOST_SPIRIT_CLASSIC_NAMESPACE_END
0225 
0226 }} // namespace BOOST_SPIRIT_CLASSIC_NS
0227 
0228 #include <boost/spirit/home/classic/symbols/impl/symbols.ipp>
0229 #endif