c++ - 提升精神合成属性困惑

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

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

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

根据我对文档的阅读,其合成属性为 tuple<vector<char>,unsigned int>因为替代解析器 (char | char)类型为 charchar >> char("xyXY")将是vector<char> ,以及vector<char> >> uint_将是类型的元组,因此 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<char,char,unsigned int>作为属性类型:

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

最佳答案

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但需要包含不同的 header :#include <boost/fusion/include/boost_tuple.hpp> .

关于c++ - 提升精神合成属性困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40421215/

相关文章:

c++ - 无论实际实例化如何,都接受函数签名中的模板化参数

c++ - 依赖的非类型模板参数

c++ - 如何在不先将整个文件读入内存的情况下使用 Boost::Spirit::Lex 对文件进行 lex?

c++ - 为传递到 qi::phrase_parse 的表达式设置语义 Action 的属性

c++ - 带有左移运算符的奇怪积分促销

c++ - Visual C++ 不会自动完成类成员

c++ - 使用 boost::spirit 的简单表达式

c++ - boost spirit 解析标识符

c++ - 灵气 : Completely ignoring output of some rules

c++ - 是否可以在没有 Boost.Fusion 的情况下使用 Boost.Spirit V2.x?