增强精神 - 无法获得属性
boost spirit - unable to get attributes
我有以下代码:
#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: []
为什么在" got:"解析时没有任何参数?我在做什么错?
三个问题:
-
您在这里缺少括号:
boost::spirit::qi::rule<Iterator, parameter(), boost::spirit::qi::ascii::space_type> param; ^^
我同意,很难改善"流浪"模板参数的诊断,这显然并不容易。但是,这是您很快就会习惯的,因为它对于任何语法/规则定义都是惯用的。
-
您的函数struct仅包含一个元素,并且有一些局限性"破坏"单元素元组的抽象。这是一个/非常众所周知的问题,应该在Spirit V3中解释。目前,要么跳过结构:
using function = std::vector<parameter>;
或使用"规范"解决方法:
start %= eps >> (params % ',');
-
您的开始规则有一个虚假的克莱恩之星。如果要允许空参数列表,请执行
start %= eps >> -(params % ',');
微妙的不同(允许多个连续的
,
:start %= eps >> (-params % ',');
-
剩余的样式元素:
%=
在没有语义动作的规则上是多余的
请参阅 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; ]
完整代码
#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";
}
}
相关文章:
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 无法将结构注册为增强几何体3D点
- C++概念:如何使用'concept'检查模板化结构的属性?
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 通过指向指针数组的指针访问子类的属性
- MSVC是否支持C++11样式的属性而不是__declspec
- QML:修改在不同QML文件(而非main.QML)中定义的子对象的属性
- 类的C++属性似乎已重新初始化
- Qt Quick-如何仅从c++代码与qml属性交互
- 用概念检查属性的类型
- C++如何将同一类的实例作为属性
- 增强基于 XML class_id的反序列化
- 按多个属性排序
- 主函数参数的属性
- 增强精神 - 无法获得属性
- 具有继承属性的增强精神解析器 - 简单示例无法编译
- 增强BGL read_graphviz的捆绑属性
- 增强BGL:边缘属性贴图
- 增强精神合成属性混乱
- 增强精神串属性兼容性