1 // Copyright (c) 2001-2011 Hartmut Kaiser 2 // 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 6 #if !defined(BOOST_SPIRIT_LEX_LEXER_SEMANTIC_ACTION_DATA_JUN_10_2009_0417PM) 7 #define BOOST_SPIRIT_LEX_LEXER_SEMANTIC_ACTION_DATA_JUN_10_2009_0417PM 8 9 #if defined(_MSC_VER) 10 #pragma once 11 #endif 12 13 #include <boost/spirit/home/lex/lexer/pass_flags.hpp> 14 #include <boost/mpl/bool.hpp> 15 #include <boost/function.hpp> 16 #include <vector> 17 18 namespace boost { namespace spirit { namespace lex { namespace lexertl 19 { 20 namespace detail 21 { 22 /////////////////////////////////////////////////////////////////////// 23 template <typename Iterator, typename SupportsState, typename Data> 24 struct semantic_actions; 25 26 // This specialization of semantic_actions will be used if the token 27 // type (lexer definition) does not support states, which simplifies 28 // the data structures used to store the semantic action function 29 // objects. 30 template <typename Iterator, typename Data> 31 struct semantic_actions<Iterator, mpl::false_, Data> 32 { 33 typedef void functor_type(Iterator&, Iterator& 34 , BOOST_SCOPED_ENUM(pass_flags)&, std::size_t&, Data&); 35 typedef boost::function<functor_type> functor_wrapper_type; 36 37 // add a semantic action function object 38 template <typename F> add_actionboost::spirit::lex::lexertl::detail::semantic_actions39 void add_action(std::size_t unique_id, std::size_t, F act) 40 { 41 if (actions_.size() <= unique_id) 42 actions_.resize(unique_id + 1); 43 44 actions_[unique_id] = act; 45 } 46 47 // try to invoke a semantic action for the given token (unique_id) invoke_actionsboost::spirit::lex::lexertl::detail::semantic_actions48 BOOST_SCOPED_ENUM(pass_flags) invoke_actions(std::size_t /*state*/ 49 , std::size_t& id, std::size_t unique_id, Iterator& end 50 , Data& data) const 51 { 52 // if there is nothing to invoke, continue with 'match' 53 if (unique_id >= actions_.size() || !actions_[unique_id]) 54 return pass_flags::pass_normal; 55 56 // Note: all arguments might be changed by the invoked semantic 57 // action 58 BOOST_SCOPED_ENUM(pass_flags) match = pass_flags::pass_normal; 59 actions_[unique_id](data.get_first(), end, match, id, data); 60 return match; 61 } 62 63 std::vector<functor_wrapper_type> actions_; 64 }; 65 66 // This specialization of semantic_actions will be used if the token 67 // type (lexer definition) needs to support states, resulting in a more 68 // complex data structure needed for storing the semantic action 69 // function objects. 70 template <typename Iterator, typename Data> 71 struct semantic_actions<Iterator, mpl::true_, Data> 72 { 73 typedef void functor_type(Iterator&, Iterator& 74 , BOOST_SCOPED_ENUM(pass_flags)&, std::size_t&, Data&); 75 typedef boost::function<functor_type> functor_wrapper_type; 76 77 // add a semantic action function object 78 template <typename F> add_actionboost::spirit::lex::lexertl::detail::semantic_actions79 void add_action(std::size_t unique_id, std::size_t state, F act) 80 { 81 if (actions_.size() <= state) 82 actions_.resize(state + 1); 83 84 std::vector<functor_wrapper_type>& actions (actions_[state]); 85 if (actions.size() <= unique_id) 86 actions.resize(unique_id + 1); 87 88 actions[unique_id] = act; 89 } 90 91 // try to invoke a semantic action for the given token (unique_id) invoke_actionsboost::spirit::lex::lexertl::detail::semantic_actions92 BOOST_SCOPED_ENUM(pass_flags) invoke_actions(std::size_t state 93 , std::size_t& id, std::size_t unique_id, Iterator& end 94 , Data& data) const 95 { 96 // if there is no action defined for this state, return match 97 if (state >= actions_.size()) 98 return pass_flags::pass_normal; 99 100 // if there is nothing to invoke, continue with 'match' 101 std::vector<functor_wrapper_type> const& actions = actions_[state]; 102 if (unique_id >= actions.size() || !actions[unique_id]) 103 return pass_flags::pass_normal; 104 105 // set token value 106 data.set_end(end); 107 108 // Note: all arguments might be changed by the invoked semantic 109 // action 110 BOOST_SCOPED_ENUM(pass_flags) match = pass_flags::pass_normal; 111 actions[unique_id](data.get_first(), end, match, id, data); 112 return match; 113 } 114 115 std::vector<std::vector<functor_wrapper_type> > actions_; 116 }; 117 } 118 119 }}}} 120 121 #endif 122