/*============================================================================= Copyright (c) 1998-2003 Joel de Guzman http://spirit.sourceforge.net/ 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_PARSER_HPP) #define BOOST_SPIRIT_PARSER_HPP #include #include #include #include #include namespace boost { namespace spirit { BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN template class action; // forward declaration /////////////////////////////////////////////////////////////////////////// // // Parser categories // // Helper template classes to distinguish different types of // parsers. The following categories are the most generic. More // specific types may inherit from these. Each parser has a typedef // parser_category_t that defines its category. By default, if one // is not specified, it will inherit from the base parser class // which typedefs its parser_category_t as plain_parser_category. // // - plain parser has nothing special // - binary parser has subject a and b (e.g. alternative) // - unary parser has single subject (e.g. kleene star) // - action parser has an attached action parser // /////////////////////////////////////////////////////////////////////////// struct plain_parser_category {}; struct binary_parser_category : plain_parser_category {}; struct unary_parser_category : plain_parser_category {}; struct action_parser_category : unary_parser_category {}; /////////////////////////////////////////////////////////////////////////// // // parser_result metafunction // // Given a scanner type ScannerT and a parser type ParserT, the // parser_result metafunction provides the actual result of the // parser. // // Usage: // // typename parser_result::type // /////////////////////////////////////////////////////////////////////////// template struct parser_result { typedef typename boost::remove_reference::type parser_type; typedef typename parser_type::template result::type type; }; /////////////////////////////////////////////////////////////////////////// // // parser class // // This class is a protocol base class for all parsers. This is // essentially an interface contract. The parser class does not // really know how to parse anything but instead relies on the // template parameter DerivedT (which obviously is assumed to be a // subclass) to do the actual parsing. // // Concrete sub-classes inheriting from parser must have a // corresponding member function parse(...) compatible with the // conceptual Interface: // // template // RT parse(ScannerT const& scan) const; // // where RT is the desired return type of the parser and ScannerT // scan is the scanner (see scanner.hpp). // // Concrete sub-classes inheriting from parser in most cases need to // have a nested meta-function result that returns the result type // of the parser's parse member function, given a scanner type. The // meta-function has the form: // // template // struct result // { // typedef RT type; // }; // // where RT is the desired return type of the parser. This is // usually, but not always, dependent on the template parameter // ScannerT. If a parser does not supply a result metafunction, a // default is provided by the base parser class. // // The parser's derived() member function returns a reference to the // parser as its derived object. // // An operator[] is provided. The operator returns a semantic action // handler (see actions.hpp). // // Each parser has a typedef embed_t. This typedef specifies how a // parser is embedded in a composite (see composite.hpp). By // default, if one is not specified, the parser will be embedded by // value. That is, a copy of the parser is placed as a member // variable of the composite. Most parsers are embedded by value. In // certain situations however, this is not desirable or possible. // /////////////////////////////////////////////////////////////////////////// template struct parser { typedef DerivedT embed_t; typedef DerivedT derived_t; typedef plain_parser_category parser_category_t; template struct result { typedef typename match_result::type type; }; DerivedT& derived() { return *static_cast(this); } DerivedT const& derived() const { return *static_cast(this); } template action operator[](ActionT const& actor) const { return action(derived(), actor); } }; /////////////////////////////////////////////////////////////////////////// // // parse_info // // Results returned by the free parse functions: // // stop: points to the final parse position (i.e parsing // processed the input up to this point). // // hit: true if parsing is successful. This may be full: // the parser consumed all the input, or partial: // the parser consumed only a portion of the input. // // full: true when we have a full hit (i.e the parser // consumed all the input. // // length: The number of characters consumed by the parser. // This is valid only if we have a successful hit // (either partial or full). // /////////////////////////////////////////////////////////////////////////// template struct parse_info { IteratorT stop; bool hit; bool full; std::size_t length; parse_info( IteratorT const& stop_ = IteratorT(), bool hit_ = false, bool full_ = false, std::size_t length_ = 0) : stop(stop_) , hit(hit_) , full(full_) , length(length_) {} template parse_info(ParseInfoT const& pi) : stop(pi.stop) , hit(pi.hit) , full(pi.full) , length(pi.length) {} }; /////////////////////////////////////////////////////////////////////////// // // Generic parse function // /////////////////////////////////////////////////////////////////////////// template parse_info parse( IteratorT const& first, IteratorT const& last, parser const& p); /////////////////////////////////////////////////////////////////////////// // // Parse function for null terminated strings // /////////////////////////////////////////////////////////////////////////// template parse_info parse( CharT const* str, parser const& p); BOOST_SPIRIT_CLASSIC_NAMESPACE_END }} // namespace BOOST_SPIRIT_CLASSIC_NS #endif #include