![]() |
|
|||
File indexing completed on 2025-03-02 09:54:20
0001 /*============================================================================= 0002 Copyright (c) 1998-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_ACTIONS_HPP 0009 #define BOOST_SPIRIT_ACTIONS_HPP 0010 0011 #include <boost/spirit/home/classic/namespace.hpp> 0012 #include <boost/spirit/home/classic/core/parser.hpp> 0013 #include <boost/spirit/home/classic/core/composite/composite.hpp> 0014 #include <boost/core/ignore_unused.hpp> 0015 0016 namespace boost { namespace spirit { 0017 0018 BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN 0019 0020 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) 0021 #pragma warning(push) 0022 #pragma warning(disable:4512) //assignment operator could not be generated 0023 #endif 0024 0025 /////////////////////////////////////////////////////////////////////////// 0026 // 0027 // action class 0028 // 0029 // The action class binds a parser with a user defined semantic 0030 // action. Instances of action are never created manually. Instead, 0031 // action objects are typically created indirectly through 0032 // expression templates of the form: 0033 // 0034 // p[f] 0035 // 0036 // where p is a parser and f is a function or functor. The semantic 0037 // action may be a function or a functor. When the parser is 0038 // successful, the actor calls the scanner's action_policy policy 0039 // (see scanner.hpp): 0040 // 0041 // scan.do_action(actor, attribute, first, last); 0042 // 0043 // passing in these information: 0044 // 0045 // actor: The action's function or functor 0046 // attribute: The match (returned by the parser) object's 0047 // attribute (see match.hpp) 0048 // first: Iterator pointing to the start of the matching 0049 // portion of the input 0050 // last: Iterator pointing to one past the end of the 0051 // matching portion of the input 0052 // 0053 // It is the responsibility of the scanner's action_policy policy to 0054 // dispatch the function or functor as it sees fit. The expected 0055 // function or functor signature depends on the parser being 0056 // wrapped. In general, if the attribute type of the parser being 0057 // wrapped is a nil_t, the function or functor expect the signature: 0058 // 0059 // void func(Iterator first, Iterator last); // functions 0060 // 0061 // struct ftor // functors 0062 // { 0063 // void func(Iterator first, Iterator last) const; 0064 // }; 0065 // 0066 // where Iterator is the type of the iterator that is being used and 0067 // first and last are the iterators pointing to the matching portion 0068 // of the input. 0069 // 0070 // If the attribute type of the parser being wrapped is not a nil_t, 0071 // the function or functor usually expect the signature: 0072 // 0073 // void func(T val); // functions 0074 // 0075 // struct ftor // functors 0076 // { 0077 // void func(T val) const; 0078 // }; 0079 // 0080 // where T is the attribute type and val is the attribute value 0081 // returned by the parser being wrapped. 0082 // 0083 /////////////////////////////////////////////////////////////////////////// 0084 template <typename ParserT, typename ActionT> 0085 class action : public unary<ParserT, parser<action<ParserT, ActionT> > > 0086 { 0087 public: 0088 0089 typedef action<ParserT, ActionT> self_t; 0090 typedef action_parser_category parser_category_t; 0091 typedef unary<ParserT, parser<self_t> > base_t; 0092 typedef ActionT predicate_t; 0093 0094 template <typename ScannerT> 0095 struct result 0096 { 0097 typedef typename parser_result<ParserT, ScannerT>::type type; 0098 }; 0099 0100 action(ParserT const& p, ActionT const& a) 0101 : base_t(p) 0102 , actor(a) {} 0103 0104 template <typename ScannerT> 0105 typename parser_result<self_t, ScannerT>::type 0106 parse(ScannerT const& scan) const 0107 { 0108 typedef typename ScannerT::iterator_t iterator_t; 0109 typedef typename parser_result<self_t, ScannerT>::type result_t; 0110 0111 ignore_unused(scan.at_end()); // allow skipper to take effect 0112 iterator_t save = scan.first; 0113 result_t hit = this->subject().parse(scan); 0114 if (hit) 0115 { 0116 typename result_t::return_t val = hit.value(); 0117 scan.do_action(actor, val, save, scan.first); 0118 } 0119 return hit; 0120 } 0121 0122 ActionT const& predicate() const { return actor; } 0123 0124 private: 0125 0126 ActionT actor; 0127 }; 0128 0129 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) 0130 #pragma warning(pop) 0131 #endif 0132 0133 BOOST_SPIRIT_CLASSIC_NAMESPACE_END 0134 0135 }} // namespace BOOST_SPIRIT_CLASSIC_NS 0136 0137 #endif
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |