提振精神 - 无法获取属性 [英] boost spirit - unable to get attributes
问题描述
我有以下的code:
#define BOOST_SPIRIT_DEBUG
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>
#include <boost/spirit/include/qi.hpp>
#include <iostream>
#include <string>
#include <vector>
struct parameter
{
std::string type;
std::string name;
};
BOOST_FUSION_ADAPT_STRUCT(
parameter,
(std::string, type)
(std::string, name)
)
inline
std::ostream& operator<<(std::ostream& os, const parameter& param)
{
os << param.type << ' ' << param.name;
return os;
}
inline
std::ostream& operator<<(std::ostream& os, const std::vector<parameter>& parameters)
{
for (const auto& param : parameters)
{
os << param;
}
return os;
}
struct function
{
std::vector<parameter> parameters;
};
BOOST_FUSION_ADAPT_STRUCT(
::function,
(std::vector<parameter>, parameters)
)
template <typename Iterator>
struct function_parser : boost::spirit::qi::grammar<Iterator, function(), boost::spirit::qi::ascii::space_type>
{
function_parser() : function_parser::base_type(start)
{
using boost::spirit::qi::alnum;
using boost::spirit::qi::alpha;
string %= alpha >> *alnum;
BOOST_SPIRIT_DEBUG_NODE(string);
param %= string >> string;
BOOST_SPIRIT_DEBUG_NODE(param);
start %= *(param % ',');
BOOST_SPIRIT_DEBUG_NODE(start);
}
boost::spirit::qi::rule<Iterator, std::string()> string;
boost::spirit::qi::rule<Iterator, parameter, boost::spirit::qi::ascii::space_type> param;
boost::spirit::qi::rule<Iterator, function(), boost::spirit::qi::ascii::space_type> start;
};
int main()
{
std::string input_data("int bar, int baz");
function fn;
auto itr = input_data.begin();
auto end = input_data.end();
function_parser<decltype(itr)> g;
bool res = boost::spirit::qi::phrase_parse(itr, end, g, boost::spirit::ascii::space, fn);
if (res && itr == end)
{
std::cout << boost::fusion::tuple_open('[');
std::cout << boost::fusion::tuple_close(']');
std::cout << boost::fusion::tuple_delimiter(", ");
std::cout << "Parsing succeeded \n";
std::cout << "got: " << boost::fusion::as_vector(fn) << std::endl;
}
else
{
std::cout << "Parsing failed \n";
}
}
输出
<start>
<try>int bar, int baz</try>
<param>
<try>int bar, int baz</try>
<string>
<try>int bar, int baz</try>
<success> bar, int baz</success>
<attributes>[[i, n, t]]</attributes>
</string>
<string>
<try>bar, int baz</try>
<success>, int baz</success>
<attributes>[[b, a, r]]</attributes>
</string>
<success>, int baz</success>
<attributes>[]</attributes>
</param>
<param>
<try> int baz</try>
<string>
<try>int baz</try>
<success> baz</success>
<attributes>[[i, n, t]]</attributes>
</string>
<string>
<try>baz</try>
<success></success>
<attributes>[[b, a, z]]</attributes>
</string>
<success></success>
<attributes>[]</attributes>
</param>
<param>
<try></try>
<string>
<try></try>
<fail/>
</string>
<fail/>
</param>
<success></success>
<attributes>[[[]]]</attributes>
</start>
Parsing succeeded
got: []
为什么没有上市之后的任何参数得到的消息在解析成功了吗?我在做什么错了?
Why there isn't any parameters listed after "got: " message while parsing succeeded? What am I doing wrong?
推荐答案
三个问题:
-
您在这儿缺少括号:
You're missing parentheses here:
boost::spirit::qi::rule<Iterator, parameter(), boost::spirit::qi::ascii::space_type> param;
^^
我同意它吮吸,这显然不是容易提高流浪模板参数诊断。然而,这一个东西,你将能够迅速适应pretty,因为它是惯用的任何语法/规则的定义。
I agree that it sucks that it isn't apparently easy to improve diagnostics for "stray" template arguments. However, this one is something that you will get used to pretty quickly, as it is idiomatic for any grammar/rule definition.
您的功能结构只有一个元素,而且有局限性的break单元素的元组的抽象。这是一个/非常不确定/问题,并应灵V3得到缓解。现在,无论是跳过结构:
Your function struct contains only one element, and there are limitations that "break" the abstraction with single-element tuples. This is a /very wellknown/ issue, and should be relieved in Spirit V3. For now, either skip the struct:
using function = std::vector<parameter>;
或使用'规范'的解决方法:
or use the 'canonical' workaround:
start %= eps >> (params % ',');
您开始规则有虚假克莱尼星号。如果你想允许空参数列表,执行
Your start rule has a spurious kleen star. If you want to allow empty param lists, do
start %= eps >> -(params % ',');
微妙的不同(允许多个连续的,
:
start %= eps >> (-params % ',');
<子>的风格剩余元素:(%)=
是多余的规则没有语义动作
Remaining element of style: %=
is redundant on rules without semantic actions
看它的 住在Coliru
See it Live On Coliru
输出:
<start>
<try>int bar, int baz</try>
<param>
<!-- snip -->
<attributes>[[[i, n, t], [b, a, z]]]</attributes>
</param>
<success></success>
<attributes>[[[[[i, n, t], [b, a, r]], [[i, n, t], [b, a, z]]]]]</attributes>
</start>
Parsing succeeded
got: [int bar; int baz; ]
全code
#define BOOST_SPIRIT_DEBUG
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>
#include <boost/spirit/include/qi.hpp>
#include <iostream>
#include <string>
#include <vector>
struct parameter
{
std::string type;
std::string name;
};
BOOST_FUSION_ADAPT_STRUCT(
parameter,
(std::string, type)
(std::string, name)
)
inline std::ostream& operator<<(std::ostream& os, const parameter& param) { return os << param.type << ' ' << param.name; }
inline std::ostream& operator<<(std::ostream& os, const std::vector<parameter>& parameters) {
for (const auto& param : parameters) { os << param << "; "; }
return os;
}
struct function
{
std::vector<parameter> parameters;
};
BOOST_FUSION_ADAPT_STRUCT(
::function,
(std::vector<parameter>, parameters)
)
template <typename Iterator>
struct function_parser : boost::spirit::qi::grammar<Iterator, function(), boost::spirit::qi::ascii::space_type>
{
function_parser() : function_parser::base_type(start)
{
using boost::spirit::qi::alnum;
using boost::spirit::qi::alpha;
string %= alpha >> *alnum;
BOOST_SPIRIT_DEBUG_NODE(string);
param %= string >> string;
BOOST_SPIRIT_DEBUG_NODE(param);
start = boost::spirit::qi::eps >> (param % ',');
BOOST_SPIRIT_DEBUG_NODE(start);
}
boost::spirit::qi::rule<Iterator, std::string()> string;
boost::spirit::qi::rule<Iterator, parameter(), boost::spirit::qi::ascii::space_type> param;
boost::spirit::qi::rule<Iterator, function(), boost::spirit::qi::ascii::space_type> start;
};
int main()
{
std::string input_data("int bar, int baz");
function fn;
auto itr = input_data.begin();
auto end = input_data.end();
function_parser<decltype(itr)> g;
bool res = boost::spirit::qi::phrase_parse(itr, end, g, boost::spirit::ascii::space, fn);
if (res && itr == end)
{
std::cout << boost::fusion::tuple_open('[');
std::cout << boost::fusion::tuple_close(']');
std::cout << boost::fusion::tuple_delimiter(", ");
std::cout << "Parsing succeeded \n";
std::cout << "got: " << boost::fusion::as_vector(fn) << std::endl;
//std::cout << "got: " << fn << std::endl;
}
else
{
std::cout << "Parsing failed \n";
}
}
这篇关于提振精神 - 无法获取属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!