通过过滤一个std ::地图的合成属性,提振精神,语义动作 [英] Filter the synthesized attribute through a std::map in a boost spirit semantic action

查看:119
本文介绍了通过过滤一个std ::地图的合成属性,提振精神,语义动作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在哪里,我想过滤通过一个std ::地图的规则内的综合属性出现的值的情况。


  • 地图是pre-产生的,并不会解析过程中改变。

  • 地图和实分析器的性质意味着该查找应该永远不会失败(尽管元件的实际数量可以是相当大的)

  • 通常的方法完全适合于这个问题(使用符号表)是不适合的实际情况。在真正的问题的基础上,将直到在分析更晚是显而易见(以稍微移除规则)的属性查找是有条件的。

我尝试:

 的#define BOOST_SPIRIT_USE_PHOENIX_V3
#包括LT&;升压/精神/有/ qi.hpp>
#包括LT&;升压/精神/有/ phoenix.hpp>
#包括LT&;升压/ foreach.hpp>
#包括LT&;串GT;
#包括LT&;&iostream的GT;
#包括LT&;矢量>
#包括LT&;地图和GT;命名空间补气=的boost ::精神::补气;
命名空间PHX =提振::凤;诠释主(){    性病::地图<为unsigned int,unsigned int类型> MYMAP;
    MYMAP [1] = 100; MYMAP [2] = 200; MYMAP [3] = 300;    标准::字符串测试=1 2 3;
    的std ::矢量< unsigned int类型>结果;    齐::规则<的std ::字符串::迭代器,无符号整型()> - [R
                      =补气:: uint_ [齐:: _ VAL = PHX ::在(MYMAP,补气:: _ 1)];    齐::解析(test.begin(),test.end(),(R%),结果);    BOOST_FOREACH(unsigned int类型和放大器; X,结果){
        性病::法院LT&;<点¯x所述&;&下; \\ n;
    }
}

我想我是在IM pression下,由于对的 STL容器,这应该工作。但我得到的基准线编译错误。这个错误消失,如果我取代经典的毫无意义的语义动作 [齐:: _ VAL =补气:: _ 1] (不奇怪)。

MSVS10下的编译器错误是惊人的长,像往常一样,但这里是我的code文件首次提及:(在C:\\ code \\ Compiler2 \\ spirit_test.cpp(25)...行25是规则研究

  C:\\ boost_1_50_0 \\升压/精神的/ home /气/非终结/ rule.hpp(191):见参考函数模板instantiatio
N'无效boost::spirit::qi::rule<Iterator,T1>::define<boost::mpl::false_,Expr>(boost::spirit::qi::rule<Iterator,T1> &安培;,CON
ST Expr的&安培;,提振:: MPL :: true_)正在编制
        同
        [
            迭代器=的std :: _ St​​ring_iterator&LT;焦炭,的std :: char_traits&LT;焦炭&GT;,性病::分配器&LT;焦炭&GT;&gt;中
            T1 =无符号整型(无效),
            Expr=boost::proto::exprns_::expr<boost::proto::tagns_::tag::subscript,boost::proto::argsns_::list2<const嘘
ST ::精神::终端LT;的boost ::精神::标签:: uint_&GT; &安培;,常量的boost ::凤::演员&LT;提高::原:: exprns _ :: basic_expr&LT;提高:: p
roto::tagns_::tag::assign,boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,b
oost::proto::argsns_::term<boost::spirit::attribute<0>>,0>,boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost
::phoenix::detail::tag::function_eval,boost::proto::argsns_::list3<boost::proto::exprns_::basic_expr<boost::proto::tagns
_::tag::terminal,boost::proto::argsns_::term<boost::phoenix::stl::at_impl>,0>,boost::phoenix::actor<boost::proto::exprns
_::basic_expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::reference_wrapper<std::map<unsigned
 整型,无符号int>>>,0>>,boost::phoenix::actor<boost::spirit::argument<0>>>,3>>>,2>> &放大器;&GT;,2 - ;
        ]
        C:\\ code \\ Compiler2 \\ spirit_test.cpp(25):见参考函数模板实例化的boost ::精神::气
::规则&LT;迭代器,T1&GT; ::规则&LT;提高::原:: exprns _ :: EXPR&LT;标签,参数数量,元数&GT;&GT;(常量Expr的&安培;,常量标准::字符串&安培;)正在编制        同
        [
            迭代器=的std :: _ St​​ring_iterator&LT;焦炭,的std :: char_traits&LT;焦炭&GT;,性病::分配器&LT;焦炭&GT;&gt;中
            T1 =无符号整型(无效),
            标签=提振::原:: tagns _ ::标签::标,
            ARGS =提振::原:: argsns _ ::列表2&LT;常量的boost ::精神::终端LT;的boost ::精神::标签:: uint_&GT; &安培;,常量的boost :: pH值
oenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign,boost::proto::argsns_::list2<boost::pro
to::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::attribute<0>>,0>,boost:
:phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::detail::tag::function_eval,boost::proto::argsns_::list
3<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::phoenix::stl:
:at_impl>,0>,boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal,boost::proto::a
rgsns _ ::术语下,提振::的reference_wrapper&LT;的std ::地图&LT;为unsigned int,unsigned int类型&GT;&GT;&GT; 0&GT;&GT;,提振::凤::演员&LT;的boost ::精神:: ARG
输稿&℃,GT;&GT;&GT,3 GT;&GT;&GT;,2 - ;&GT; &放大器;&gt;中
            元数= 2,
            Expr=boost::proto::exprns_::expr<boost::proto::tagns_::tag::subscript,boost::proto::argsns_::list2<const嘘
ST ::精神::终端LT;的boost ::精神::标签:: uint_&GT; &安培;,常量的boost ::凤::演员&LT;提高::原:: exprns _ :: basic_expr&LT;提高:: p
roto::tagns_::tag::assign,boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,b
oost::proto::argsns_::term<boost::spirit::attribute<0>>,0>,boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost
::phoenix::detail::tag::function_eval,boost::proto::argsns_::list3<boost::proto::exprns_::basic_expr<boost::proto::tagns
_::tag::terminal,boost::proto::argsns_::term<boost::phoenix::stl::at_impl>,0>,boost::phoenix::actor<boost::proto::exprns
_::basic_expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::reference_wrapper<std::map<unsigned
 整型,无符号int>>>,0>>,boost::phoenix::actor<boost::spirit::argument<0>>>,3>>>,2>> &放大器;&GT;,2 - ;
        ]
C:\\ boost_1_50_0 \\升压/原/变换/ default.hpp(154):错误C2440:'=':不能从转换'的std ::对&LT; _Ty1,_Ty2&GT;' ŧ
O'无符号整型
        同
        [
            _Ty1 =常数为unsigned int,
            _Ty2 =无符号整型
        ]
        没有可用的用户定义转换操作者可以执行这个转换,或操作员不能被称为


解决方案

<子>的意见重新发布

尝试齐:: _ VAL = PHX :: REF(MYMAP)[齐:: _ 1] ,而不是齐:: _ VAL = PHX: :在(MYMAP,补气:: _ 1)

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 will not change during the parsing.
  • The nature of the map and the real parser means that the lookup should never fail (although the actual number of elements may be quite large)
  • The usual approach perfectly suited to this problem (use a symbol table) isn't appropriate for the real case. In the real problem, the lookup is conditional based on an attribute that won't be apparent until much later in the parse (in a somewhat removed rule).

My attempt:

#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;

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(myMap, qi::_1)];

    qi::parse(test.begin(), test.end(), ( r % " " ), results);

    BOOST_FOREACH(unsigned int &x, results) {
        std::cout << x << "\n";
    }
}

I guess I was under the impression, due to the phoenix support for stl containers, that this should work. But I get a compile error on the rule line. This error goes away if I replace the semantic action with the classic pointless [qi::_val = qi::_1] (not surprisingly).

The compiler error under MSVS10 is shockingly long, as usual, but here's the first mention of my code file: (at C:\code\Compiler2\spirit_test.cpp(25)... line 25 is the rule r)

C:\boost_1_50_0\boost/spirit/home/qi/nonterminal/rule.hpp(191) : see reference to function template instantiatio
n 'void boost::spirit::qi::rule<Iterator,T1>::define<boost::mpl::false_,Expr>(boost::spirit::qi::rule<Iterator,T1> &,con
st Expr &,boost::mpl::true_)' being compiled
        with
        [
            Iterator=std::_String_iterator<char,std::char_traits<char>,std::allocator<char>>,
            T1=unsigned int (void),
            Expr=boost::proto::exprns_::expr<boost::proto::tagns_::tag::subscript,boost::proto::argsns_::list2<const boo
st::spirit::terminal<boost::spirit::tag::uint_> &,const boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::p
roto::tagns_::tag::assign,boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,b
oost::proto::argsns_::term<boost::spirit::attribute<0>>,0>,boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost
::phoenix::detail::tag::function_eval,boost::proto::argsns_::list3<boost::proto::exprns_::basic_expr<boost::proto::tagns
_::tag::terminal,boost::proto::argsns_::term<boost::phoenix::stl::at_impl>,0>,boost::phoenix::actor<boost::proto::exprns
_::basic_expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::reference_wrapper<std::map<unsigned
 int,unsigned int>>>,0>>,boost::phoenix::actor<boost::spirit::argument<0>>>,3>>>,2>> &>,2>
        ]
        C:\code\Compiler2\spirit_test.cpp(25) : see reference to function template instantiation 'boost::spirit::qi
::rule<Iterator,T1>::rule<boost::proto::exprns_::expr<Tag,Args,Arity>>(const Expr &,const std::string &)' being compiled

        with
        [
            Iterator=std::_String_iterator<char,std::char_traits<char>,std::allocator<char>>,
            T1=unsigned int (void),
            Tag=boost::proto::tagns_::tag::subscript,
            Args=boost::proto::argsns_::list2<const boost::spirit::terminal<boost::spirit::tag::uint_> &,const boost::ph
oenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::assign,boost::proto::argsns_::list2<boost::pro
to::exprns_::expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::spirit::attribute<0>>,0>,boost:
:phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::detail::tag::function_eval,boost::proto::argsns_::list
3<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::phoenix::stl:
:at_impl>,0>,boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal,boost::proto::a
rgsns_::term<boost::reference_wrapper<std::map<unsigned int,unsigned int>>>,0>>,boost::phoenix::actor<boost::spirit::arg
ument<0>>>,3>>>,2>> &>,
            Arity=2,
            Expr=boost::proto::exprns_::expr<boost::proto::tagns_::tag::subscript,boost::proto::argsns_::list2<const boo
st::spirit::terminal<boost::spirit::tag::uint_> &,const boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::p
roto::tagns_::tag::assign,boost::proto::argsns_::list2<boost::proto::exprns_::expr<boost::proto::tagns_::tag::terminal,b
oost::proto::argsns_::term<boost::spirit::attribute<0>>,0>,boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost
::phoenix::detail::tag::function_eval,boost::proto::argsns_::list3<boost::proto::exprns_::basic_expr<boost::proto::tagns
_::tag::terminal,boost::proto::argsns_::term<boost::phoenix::stl::at_impl>,0>,boost::phoenix::actor<boost::proto::exprns
_::basic_expr<boost::proto::tagns_::tag::terminal,boost::proto::argsns_::term<boost::reference_wrapper<std::map<unsigned
 int,unsigned int>>>,0>>,boost::phoenix::actor<boost::spirit::argument<0>>>,3>>>,2>> &>,2>
        ]
C:\boost_1_50_0\boost/proto/transform/default.hpp(154) : error C2440: '=' : cannot convert from 'std::pair<_Ty1,_Ty2>' t
o 'unsigned int'
        with
        [
            _Ty1=const unsigned int,
            _Ty2=unsigned int
        ]
        No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

解决方案

Reposting from comment

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

这篇关于通过过滤一个std ::地图的合成属性,提振精神,语义动作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆