Boost Spirit合成属性混乱
Boost Spirit synthesised attribute confusion
我正在尝试解析具有加号或减号字符、后跟 X 或 Y 字符、后跟无符号整数的输入。
(char_('+') | char_('-')) >> char_("xyXY") >> uint_
根据我对文档的阅读,这个的综合属性将是 tuple<vector<char>,unsigned int>
,因为替代解析器 (char | char)
的类型是 char
,char >> 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>
.
我正在尝试解析具有加号或减号字符、后跟 X 或 Y 字符、后跟无符号整数的输入。
(char_('+') | char_('-')) >> char_("xyXY") >> uint_
根据我对文档的阅读,这个的综合属性将是 tuple<vector<char>,unsigned int>
,因为替代解析器 (char | char)
的类型是 char
,char >> 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>
.