提升精神Qi重新建立跳过自定义跳过语法

jto*_*lds 7 c++ boost-spirit boost-spirit-qi

到目前为止,我的语法一直使用标准boost::spirit::ascii::space/ boost::spirit::ascii::space_type队长.

我有一些使用船长的规则和一些不使用船长的规则

qi::rule<Iterator, PTR<Expression>(), ascii::space_type> expression;
qi::rule<Iterator, PTR<Term>()> term;
Run Code Online (Sandbox Code Playgroud)

当我在跳过非终结符(例如term)中使用非跳过非终结符(例如expression)时,一切都像我期望的那样工作 - 空格只对term非终结内部很重要.

此外,到目前为止,我一直很好,包括使用不使用qi::skip重新跳过的非终端内的队长的非终结者,例如

index = (qi::lit('[') >> qi::skip(ascii::space)[explist >> qi::lit(']')]);
Run Code Online (Sandbox Code Playgroud)

这样,在[]括号内部的空白并不重要,但在外面.

但是,现在我想添加我自己的自定义队列(我想让换行有意义,然后添加评论跳过).我的船长语法看起来像:

struct skip_grammar : qi::grammar<Iterator> {
  qi::rule<Iterator> start;
  skip_grammar() : skip_grammar::base_type(start) {
    start = qi::char_("\t\r ");
  }
};
Run Code Online (Sandbox Code Playgroud)

我已经能够将它添加到我的规则定义中就好了

qi::rule<Iterator, PTR<Expression>(), skip_grammar> expression;
Run Code Online (Sandbox Code Playgroud)

但我似乎无法弄清楚如何使用我的跳过语法作为参数qi::skip(和替换ascii::space).我尝试使用类型,本地实例变量和全局实例变量.我得到的最远的就是抱怨我的skip_grammar需要一个拷贝构造函数.所以我尝试将一个复制构造函数添加到我的跳过语法中,但显然boost::noncopyable基类是有原因的,因为我的二进制文件几乎立即就被发现了.

我应该如何使用它?

谢谢

hka*_*ser 7

A qi::grammar只是一个容器qi::rules.它没有复制构造函数,因为这可能会无意中在这些规则右侧的解析器表达式中创建悬空引用.

如你所愿使用语法作为队长是有点棘手的,相当于将语法的开始规则传递给跳过解析器.为此创建规则实例可能更容易(特别是如果您有一个规则管理器).

在任何情况下,规则都需要作为参考传递给船长(通过调用规则的成员函数alias()):

skip_grammar skippper;
index = '[' >> qi::skip(skipper.start.alias())[explist >> ']'];
Run Code Online (Sandbox Code Playgroud)

或者干脆:

rule<iterator> skipper = qi::char_("\t\r ");
index = '[' >> qi::skip(skipper.alias())[explist >> ']'];
Run Code Online (Sandbox Code Playgroud)

别名是必要的,因为复制规则意味着什么.这里的 Spirit的常见问题解答中有更详细的描述.