【问题标题】:Boost Spirit synthesised attribute confusion提升精神合成属性混乱
【发布时间】:2016-11-04 11:12:30
【问题描述】:

我正在尝试解析具有加号或减号字符、后跟 X 或 Y 字符、后跟无符号整数的输入。

(char_('+') | char_('-')) >> char_("xyXY") >> uint_

根据我对文档的阅读,合成属性将是 tuple<vector<char>,unsigned int>,因为替代解析器 (char | char) 的类型为 charchar >> char("xyXY") 的类型为 vector<char>,@987654327 @ 将是类型的元组,所以 tuple<vector<char>,unsigned int>。编译失败

qi\detail\assign_to.hpp(152) : error C2440: 'static_cast' : cannot convert from 'const char' to 'boost::tuples::tuple<T0,T1>'

代码:

#include <iostream>
#include <string>
#include <vector>

#include <boost/fusion/include/tuple.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/tuple/tuple.hpp>

using namespace boost::spirit::qi;

int main()
{
    std::string input("-Y 512");
    typedef std::string::const_iterator Iterator;
    Iterator first = input.begin();
    Iterator last = input.end();
    boost::tuple<std::vector<char>,unsigned int> output;
    bool result = phrase_parse(first,last,(char_('+') | char_('-')) >> char_("xyXY") >> uint_,ascii::space,output);
    if(result && first == last)
        std::cout << "sign=" << boost::get<0>(output)[0] << ", xy=" << boost::get<0>(output)[1] << ", size=" << boost::get<1>(output) << '\n';
    else
        std::cerr << "Parse error\n";
}

然后我尝试tuple&lt;char,char,unsigned int&gt;作为属性类型:

#include <iostream>
#include <string>
#include <vector>

#include <boost/fusion/include/tuple.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/tuple/tuple.hpp>

using namespace boost::spirit::qi;

int main()
{
    std::string input("-Y 512");
    typedef std::string::const_iterator Iterator;
    Iterator first = input.begin();
    Iterator last = input.end();
    boost::tuple<char,char,unsigned int> output;
    bool result = phrase_parse(first,last,(char_('+') | char_('-')) >> char_("xyXY") >> uint_,ascii::space,output);
    if(result && first == last)
        std::cout << "sign=" << boost::get<0>(output) << ", xy=" << boost::get<1>(output) << ", size=" << boost::get<2>(output) << '\n';
    else
        std::cerr << "Parse error\n";
}

这可以编译,但输出不正确。输入的第一个标记被正确解析,但随后的标记没有:

sign=-, xy= , size=0

我也试过as_string[]

#include <iostream>
#include <string>
#include <vector>

#include <boost/fusion/include/tuple.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/tuple/tuple.hpp>

using namespace boost::spirit::qi;

int main()
{
    std::string input("-Y 512");
    typedef std::string::const_iterator Iterator;
    Iterator first = input.begin();
    Iterator last = input.end();
    boost::tuple<std::string,unsigned int> output;
    bool result = phrase_parse(first,last,as_string[(char_('+') | char_('-')) >> char_("xyXY")] >> uint_,ascii::space,output);
    if(result && first == last)
        std::cout << "sign=" << boost::get<0>(output)[0] << ", xy=" << boost::get<0>(output)[1] << ", size=" << boost::get<1>(output) << '\n';
    else
        std::cerr << "Parse error\n";
}

这改进了 x/y 标记被解析的情况,但不是第三个整数标记:

sign=-, xy=Y, size=0

请告诉我哪里出错了。

我使用的是 Spirit 2.5.2 版(来自 Boost 1.58.0)和 Microsoft Visual Studio 2008。

【问题讨论】:

    标签: c++ boost-spirit boost-spirit-qi


    【解决方案1】:

    Spirit 库文档建议使用Fusion tuple。我想我在某个地方(现在找不到)看到 Boost tuple 可能与 Spirit 库不完全兼容。

    这是您的固定示例:

    #include <iostream>
    #include <string>
    #include <vector>
    
    #include <boost/fusion/include/tuple.hpp>
    #include <boost/spirit/include/qi.hpp>
    #include <boost/fusion/sequence.hpp>
    
    namespace qi = boost::spirit::qi;
    
    int main()
    {
        std::string input("-Y 512");
        typedef std::string::const_iterator Iterator;
        Iterator first = input.begin();
        Iterator last = input.end();
    
        boost::fusion::tuple<char, char, unsigned int> output;
        bool result = qi::phrase_parse(first, last, (qi::char_('+') | qi::char_('-')) >> qi::char_("xyXY") >> qi::uint_, qi::ascii::space, output);
        if (result && first == last)
            std::cout << "sign=" << boost::fusion::get<0>(output) << ", xy=" << boost::fusion::get<1>(output) << ", size=" << boost::fusion::get<2>(output) << '\n';
        else
            std::cerr << "Parse error\n";
    
        return 0;
    }
    

    输出: sign=-, xy=Y, size=512

    更新:实际上我发现here 可以使用boost::tuple,但需要包含不同的标题:#include &lt;boost/fusion/include/boost_tuple.hpp&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-08
      • 1970-01-01
      • 1970-01-01
      • 2013-06-09
      • 1970-01-01
      相关资源
      最近更新 更多