2

我有很多具有共同前缀和后缀的规则:

rule = begin_stuff >> some >> other >> stuff >> end_stuff.

(其中begin_stuffend_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 规则?

4

2 回答 2

2

我认为您正在寻找“子规则”(Spirit V1/classical 曾经拥有)。这些现在已经过时了。

看一下

  • c++11autoBOOST_AUTO

    auto subexpression = int_ >> ',' >> double_;
    qi::rule<It> rule  = "A:" >> subexpression >> "Rest:" >> (subexpression % eol);
    

    使用autoSpirit 规则(尤其是 MSVC)曾经存在问题(请参阅2 秒内从零到 60 MPH!和评论),但我已被告知(很快)不再是问题

    Yep. Anyway,FYI, it's fixed in Spirit-3. You can 
    use auto all you want. 
    
    Regards, 
    -- 
    Joel de Guzman
    
  • 齐::懒惰

  • 继承的参数- 在Mini XML - ASTs教程中介绍

这是一个概念证明,它将一个公共子规则传递给不同的“复合”规则,以允许包装(),[]{}:

#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 语法。当“通用”规则会暴露不同的属性时,这种方式就不能很好地发挥作用。

于 2012-11-15T01:40:51.560 回答
1

我认为您需要使用 Spirit Repository 中的Qi Confix Parser Derective。这正是您所需要的。

于 2013-11-11T03:10:09.510 回答