【发布时间】:2015-03-18 09:58:27
【问题描述】:
我正在通过 qi 将文本解析为 AST,并通过 karma 再次生成文本。这按预期工作,但需要某种方法将属性从一个规则传递到另一个规则。
从 cmets 移植:
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/adapt_adt.hpp>
#include <fstream>
struct c_struct
{
int value1;
};
struct b_struct
{
std::string value1;
std::vector< c_struct > value2;
};
struct a_struct
{
std::string value1;
std::vector< b_struct > value2;
};
BOOST_FUSION_ADAPT_STRUCT( c_struct,
(int, value1)
)
BOOST_FUSION_ADAPT_STRUCT( b_struct,
(std::string, value1)
(std::vector< c_struct >, value2)
)
BOOST_FUSION_ADAPT_STRUCT( a_struct,
(std::string, value1)
(std::vector< b_struct >, value2)
)
using namespace boost::spirit;
using namespace boost::spirit::qi;
using namespace boost::spirit::karma;
using namespace boost::spirit::ascii;
template <typename Iterator>
struct grammarB : karma::grammar<Iterator, a_struct()>
{
grammarB() : grammarB::base_type(ruleA)
{
ruleA %= karma::string << karma::lit(' ') << +ruleB << eps;
ruleB %= karma::string << +ruleC << karma::lit(' ') << eps;
ruleC %= lit(" -> ") << karma::int_;
}
karma::rule<Iterator, a_struct()> ruleA;
karma::rule<Iterator, b_struct()> ruleB;
karma::rule<Iterator, c_struct()> ruleC;
};
template <typename Iterator>
struct grammarA : qi::grammar<Iterator, a_struct(), boost::spirit::ascii::space_type>
{
grammarA() : grammarA::base_type(ruleA)
{
ruleA %= ruleString >> omit[+qi::char_('.')] >> +ruleB;
ruleB %= ruleString >> omit[qi::char_(',')] >> (ruleC % qi::char_(',')) >> omit[qi::char_(';')];
ruleC %= qi::int_;
ruleString %= +qi::char_("a-z");
}
qi::rule<Iterator, a_struct(), boost::spirit::ascii::space_type> ruleA;
qi::rule<Iterator, b_struct(), boost::spirit::ascii::space_type> ruleB;
qi::rule<Iterator, c_struct(), boost::spirit::ascii::space_type> ruleC;
qi::rule<Iterator, std::string(), boost::spirit::ascii::space_type> ruleString;
};
int main(int argc, char **argv)
{
std::string storage("parent ... whee,4,5,6;ahhhh,5,6;"); // We will read the contents here.
typedef grammarA<std::string::const_iterator> grammarA_t;
grammarA_t grammar;
a_struct ast;
std::string::const_iterator iter = storage.begin();
std::string::const_iterator end = storage.end();
bool r = phrase_parse(iter, end, grammar, boost::spirit::ascii::space, ast);
if (r && iter == end)
{
std::cout << "Parsing succeeded" << std::endl;
typedef std::back_insert_iterator<std::string> output_iterator_type;
std::string generated;
output_iterator_type sink(generated);
typedef grammarB<output_iterator_type> grammarB_t;
grammarB_t generator;
if ( generate(sink, generator, ast) )
std::cout << generated << std::endl;
else
std::cout << "fail" << std::endl;
}
return 0;
}
打印出来
Parsing succeeded
parent whee -> 4 -> 5 -> 6 ahhhh -> 5 -> 6
但我更喜欢打印出来
Parsing succeeded
parent parent whee -> parent 4 -> parent 5 -> parent 6 ahhhh -> parent 5 -> parent 6
这可能吗?如何实现?
【问题讨论】:
-
没有 AST。没有生成器 API 调用(既不是迭代器也不是基于流的)。没有绑定属性。究竟想达到什么目的? “wheee”、“cool”和“childish”似乎已经实现了。 提示: 消除噪音,并显示 SSCCE/MVCE
-
SSCCE 根据link 的要求。
-
如被问及我会知道是否可以从其他规则访问/传递给定的规则属性,从而能够执行与上述相同的操作。需要注意的是,我已经更改了源链接中规则的命名。
-
SSCCE 看起来很有希望。你真的应该在问题中包含它的最小化版本,但是让我看看它。我可能会在阅读过程中为您减少它:/
-
您没有指定想要的结果。很难以梦想代码的形式“猜测”您所说的“规范”是什么意思(a)无法编译(b)没有显示您希望它实际看起来的样子(c)没有显示它会做什么,即使它是现实的代码。我会继续阅读链接的示例,以防一分钱掉在那里(但由于它确实编译,我怀疑它没有帮助)
标签: c++ boost boost-spirit boost-spirit-karma