我有很多具有共同前缀和后缀的规则:
rule = begin_stuff >> some >> other >> stuff >> end_stuff.
(其中 begin_stuff
和 end_stuff
由文字组成)
我想说
rule = wrapped(some >> other >> stuff);
我尝试了一些类似的事情
template<typename Rule> Rule wrapped(Rule inside)
{
Rule result;
result = begin_stuff >> inside >> end_stuff;
return result;
}
但我得到的只是来自 Qi 的大量编译时断言。
如何以这种方式重构 Spirit 规则?
最佳答案
我认为您正在寻找“子规则”(Spirit V1/classical 曾经有)。这些现在已经过时了。
看看
c++11
auto
和BOOST_AUTO
auto subexpression = int_ >> ',' >> double_; qi::rule<It> rule = "A:" >> subexpression >> "Rest:" >> (subexpression % eol);
过去在 Spirit 规则(尤其是 MSVC)上使用
auto
时会出现问题(请参阅 Zero to 60 MPH in 2 seconds! 和评论),但我很快就被告知了这一点 is no longer an issue :Yep. Anyway,FYI, it's fixed in Spirit-3. You can use auto all you want. Regards, -- Joel de Guzman
- inherited arguments - 在 Mini XML - ASTs 中介绍教程
这是一个概念证明,它将公共(public)子规则传递给不同的“复合”规则,以允许包装在 ()
、[]
或 {}
:
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
typedef std::string::const_iterator It;
template <typename R>
void test(const std::string& input, R const& rule)
{
It f(input.begin()), l(input.end());
bool ok = qi::phrase_parse(f,l,rule,qi::space);
std::cout << "'" << input << "'\tparse " << (ok?"success":"failure") << "\n";
}
int main()
{
typedef qi::rule<It, qi::space_type> common_rule;
typedef qi::rule<It, void(common_rule), qi::space_type> compound_rule;
common_rule common = qi::int_;
compound_rule
in_parens = qi::lit('(') >> qi::_r1 >> ')',
in_brackets = qi::lit('[') >> qi::_r1 >> ']',
in_braces = qi::lit('{') >> qi::_r1 >> '}';
test("{ 231 }" , in_braces (phx::ref(common )) );
test("{ hello }", in_braces (phx::val("hello")) );
test("( 231 )" , in_parens (phx::ref(common )) );
test("( hello )", in_parens (phx::val("hello")) );
test("[ 231 ]" , in_brackets(phx::ref(common )) );
test("[ hello ]", in_brackets(phx::val("hello")) );
}
输出:
'{ 231 }' parse success
'{ hello }' parse success
'( 231 )' parse success
'( hello )' parse success
'[ 231 ]' parse success
'[ hello ]' parse success
PS。请注意,上面不是典型的 Spirit 语法。当“通用”规则会公开不同的属性时,这种方式效果不太好。
关于c++ - 分解出精神规则的共同部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13388227/