⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 symbols.hpp

📁 著名的Parser库Spirit在VC6上的Port
💻 HPP
📖 第 1 页 / 共 2 页
字号:
//
//      This class implements a symbol table. The symbol table holds a
//      dictionary of symbols where each symbol is a sequence of CharTs.
//      The template class can work efficiently with 8, 16 and 32 bit
//      characters. Mutable data of type T is associated with each
//      symbol.
//
//      The class is a parser. The parse member function returns
//      additional information in the symbol_match class (see below).
//      The additional data is a pointer to some data associated with
//      the matching symbol.
//
//      The actual set implementation is supplied by the SetT template
//      parameter. By default, this uses the tst class (see set.ipp).
//
//      Symbols are added into the symbol table statically using the
//      construct:
//
//          sym = a, b, c, d ...;
//
//      where sym is a symbol table and a..d are strings. Example:
//
//          sym = "pineapple", "orange", "banana", "apple";
//
//      Alternatively, symbols may be added dynamically through the
//      member functor 'add' (see symbol_inserter below). The member
//      functor 'add' may be attached to a parser as a semantic action:
//
//          p[sym.add]
//
//      where p is a parser (and sym is a symbol table). On success,
//      the matching portion of the input is added to the symbol table.
//
///////////////////////////////////////////////////////////////////////////////
template <
    typename T = int,
    typename CharT = char,
    typename SetT = tst<T, CharT> >
class symbols
:   private SetT,
    public parser<symbols<T, CharT, SetT> > {

public:

    typedef symbol_match<T> symbol_match;
    typedef T symbol_data_t;

    symbols();
    symbols(symbols const& other);
    ~symbols();

    symbol_inserter<T, SetT> const&
    operator=(CharT const* str);

    symbols&
    operator=(symbols const& other);


    template <typename IteratorT>
    symbol_match
    parse(IteratorT& first, IteratorT const& last) const
    {
      typename SetT::search_info result = tst<T, CharT>::find(first, last);

      if (result.data)
        return symbol_match(result.length, result.data);
      else
        return symbol_match();
    }

    template <typename ActionT>
    symbol_action<symbols<T, CharT, SetT>, ActionT>
    operator[](ActionT const& actor) const
    {
        //  Borland 5.5 complains if this is not defined here
        return symbol_action<symbols<T, CharT, SetT>, ActionT>(*this, actor);
    }
    symbol_inserter<T, SetT> const add;
};

///////////////////////////////////////////////////////////////////////////////
//
//  Symbol table utilities
//
//  add
//
//      adds a symbol 'sym' (string) to a symbol table 'table' plus an
//      optional data 'data' associated with the symbol. Returns a pointer to
//      the data associated with the symbol or NULL if add failed (e.g. when
//      the symbol is already added before).
//
//  find
//
//      finds a symbol 'sym' (string) from a symbol table 'table'. Returns a
//      pointer to the data associated with the symbol or NULL if not found
//
///////////////////////////////////////////////////////////////////////////////
template <typename T, typename CharT, typename SetT>
T*  add(symbols<T, CharT, SetT>& table, CharT const* sym, T const& data = T());

template <typename T, typename CharT, typename SetT>
T*  find(symbols<T, CharT, SetT>& table, CharT const* sym);

///////////////////////////////////////////////////////////////////////////////
//
//  symbol_action class
//
//      Links a symbol table with a user defined semantic action.
//      The semantic action may be a function or a functor. A function
//      should be compatible with the interface:
//
//          void f(IteratorT first, IteratorT last, T& data);
//
//      Where first points to the current input, last points to one
//      after the end of the input (same as STL algorithms) and data
//      is any information associated with the matching symbol in the
//      symbol table (see symbols class above).
//
//      A functor should have a member operator() with a compatible
//      signature as above. The matching portion is passed to the
//      function/functor. This is the default class that symbol
//      tables use when dealing with the construct:
//
//          p[f]
//
//      where p is a parser and f is a function or functor.
//
///////////////////////////////////////////////////////////////////////////////
template <typename ParserT, typename ActionT>
class symbol_action
:   public unary<ParserT>,
    public parser<symbol_action<ParserT, ActionT> > {

public:

    typedef action_parser_category parser_category;

    symbol_action(ParserT const& parser, ActionT const& actor);

    template <typename IteratorT>
    match
    parse(IteratorT& first, IteratorT const& last) const
   {
      typedef impl::strip_scanner<IteratorT> strip_scanner;
      typename strip_scanner::iterator_type
        begin = strip_scanner::get(first);

      typename ParserT::symbol_match hit = this->subject().parse(first, last);

      if (hit)
        actor(begin, strip_scanner::get(first), *hit.data());

      return hit;
   }

    ActionT const &predicate() const { return actor; }

private:

    typename embed_trait<ActionT>::type actor;
};

///////////////////////////////////////////////////////////////////////////////
//
//  symbol_match class
//
//      An instance of this class is returned by the symbols::parse
//      member function. symbol_match is a subclass of match with the
//      added T* data() member function. This is the data associated
//      with each entry in the symbol table (see symbols above). The
//      data is null on unsuccessful matches.
//
///////////////////////////////////////////////////////////////////////////////
template <typename T = int>
class symbol_match : public match {

public:
                symbol_match();
                symbol_match(unsigned length, T* info);
    T*          data() const;

private:

    T* info;
};

///////////////////////////////////////////////////////////////////////////////
//
//  ast_symbol_match class
//
//      An instance of this class is returned by the symbols::parse
//      member function. ast_symbol_match is a subclass of match with the
//      added T* data() member function. This is the data associated
//      with each entry in the symbol table (see symbols above). The
//      data is null on unsuccessful matches.
//
///////////////////////////////////////////////////////////////////////////////
template <typename MatchTraitsT, typename T = int>
class ast_symbol_match : public MatchTraitsT::match_t {

public:
                ast_symbol_match();
                ast_symbol_match(unsigned length, T* info);
    T*          data() const;

private:

    T* info;
};

///////////////////////////////////////////////////////////////////////////////
//
//  symbol_inserter class
//
//      The symbols class holds an instance of this class named 'add'.
//      This can be called directly just like a member function:
//
//          sym.add(first, last, data);
//
//      where sym is a symbol table. The third argument is optional.
//      This may also be used as a semantic action since it conforms
//      to the action interface (see action.hpp):
//
//          p[sym.add]
//
///////////////////////////////////////////////////////////////////////////////
template <typename T, typename SetT>
class symbol_inserter {

public:

    symbol_inserter(SetT& set);

    template <typename IteratorT>
    T*
    operator()(
        IteratorT           first,
        IteratorT const&    last,
        T const&            data = T()) const
       {
         return set.add(first, last, data);
       }

    template <typename CharT>
    symbol_inserter const&
    operator,(CharT const* str) const
    {
       CharT const* last = str;
       while (*last)
         last++;
       set.add(str, last, T());
       return *this;
    }

private:

    SetT& set;
};

///////////////////////////////////////////////////////////////////////////////
}   //  namespace Spirit

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -