Filter the synthesized attribute through a std::map in a boost spirit semantic action

前端 未结 2 1927
傲寒
傲寒 2020-12-21 23:23

I have a case where I\'d like to filter the value that comes up as a synthesized attribute inside of a rule through a std::map.

  • The map is pre-generated and wi
相关标签:
2条回答
  • 2020-12-21 23:51

    Reposting from comment

    Try qi::_val = phx::ref(myMap)[qi::_1] rather than qi::_val = phx::at(myMap, qi::_1).

    0 讨论(0)
  • 2020-12-21 23:59

    The problem is that the return type of phoenix::at is defined in this header as container::value_type. This is a pair in the case of a map. Simply specializing the result for map makes it work (using ref as noted by ildjarn).

    #define BOOST_SPIRIT_USE_PHOENIX_V3
    #include <boost/spirit/include/qi.hpp>
    #include <boost/spirit/include/phoenix.hpp>
    #include <boost/foreach.hpp>
    #include <string>
    #include <iostream>
    #include <vector>
    #include <map>
    
    namespace qi = boost::spirit::qi;
    namespace phx = boost::phoenix;
    
    namespace boost { namespace phoenix { namespace stl {
        template <typename This, typename Key, typename Value, typename Compare, typename Allocator, typename Index>
            struct at_impl::result<This(std::map<Key,Value,Compare,Allocator>&, Index)>
            {
                typedef Value & type;
            };
        template <typename This, typename Key, typename Value, typename Compare, typename Allocator, typename Index>
            struct at_impl::result<This(std::map<Key,Value,Compare,Allocator> const&, Index)>
            {
                typedef Value const& type;
            };
    }}}
    
    int main() {
    
        std::map<unsigned int, unsigned int> myMap;
        myMap[1] = 100; myMap[2] = 200; myMap[3] = 300;
    
        std::string test = "1 2 3";
        std::vector<unsigned int> results;
    
        qi::rule<std::string::iterator, unsigned int()> r
                          = qi::uint_ [qi::_val = phx::at(phx::cref(myMap), qi::_1)];
    
        qi::parse(test.begin(), test.end(), ( r % " " ), results);
    
        BOOST_FOREACH(unsigned int &x, results) {
            std::cout << x << "\n";
        }
    }
    
    0 讨论(0)
提交回复
热议问题