到目前为止,我的语法一直使用标准的boost :: spirit :: ascii :: space / boost :: spirit :: ascii :: space_type skipper.
我有一些使用船长的规则和一些不使用船长的规则
qi::rule<Iterator,PTR<Expression>(),ascii::space_type> expression; qi::rule<Iterator,PTR<Term>()> term;
当我在跳过非终结符(如表达式)中使用非跳过非终结符(如术语)时,一切都像我期望的那样 – 空白只在非终结词内部很重要.
此外,到目前为止,我一直很好,包括使用不使用qi :: skip重新跳过的非终结者内部的队长的非终结者,例如
index = (qi::lit('[') >> qi::skip(ascii::space)[explist >> qi::lit(']')]);
这样,[]括号内的空格不重要,但在外面.
但是,现在我想添加自己的自定义队列(我想让换行符显着,然后添加注释跳过).我的船长语法看起来像:
struct skip_grammar : qi::grammar<Iterator> { qi::rule<Iterator> start; skip_grammar() : skip_grammar::base_type(start) { start = qi::char_("\t\r "); } };
我已经能够将它添加到我的规则定义中就好了
qi::rule<Iterator,skip_grammar> expression;
但我似乎无法弄清楚如何使用我的跳过语法作为qi :: skip(并替换ascii :: space)的参数.我尝试使用类型,本地实例变量和全局实例变量.我得到的最远的是让clang抱怨我的skip_grammar需要一个拷贝构造函数.所以我尝试在我的跳过语法中添加一个复制构造函数,但显然boost :: noncopyable基类是有原因的,因为我的二进制文件几乎立即就被发现了.
我应该如何使用它?
谢谢
解决方法
qi :: grammar只是qi :: rules的容器.它没有复制构造函数,因为这可能会无意中在这些规则右侧的解析器表达式中创建悬空引用.
像你想要的那样使用语法作为队长是有点棘手的,相当于将语法的开始规则传递给跳过解析器.为此创建规则实例可能更容易(特别是如果您有一个规则管理器).
在任何情况下,规则都需要作为参考传递给船长(通过调用规则的成员函数别名()):
skip_grammar skippper; index = '[' >> qi::skip(skipper.start.alias())[explist >> ']'];
或者干脆:
rule<iterator> skipper = qi::char_("\t\r "); index = '[' >> qi::skip(skipper.alias())[explist >> ']'];
别名是必要的,因为复制规则意味着什么.在Spirit的FAQ here中有更详细的描述.