提升灵气重新建立跳跃与自定义跳跃语法
我有一个语法,到目前为止,一直使用标准 boost::spirit::ascii::space
/boost::spirit::ascii::space_type
船长。
我有一些使用船长的规则,有些则不使用,例如
qi::rule<Iterator, PTR<Expression>(), ascii::space_type> expression;
qi::rule<Iterator, PTR<Term>()> term;
当我在跳过非终端(如 表达式
)内使用非跳过非终端(如 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, PTR<Expression>(), skip_grammar> expression;
但我似乎无法弄清楚如何使用我的跳过语法作为 qi::skip
的参数(并替换 ascii::space
)。我尝试过使用类型、本地实例变量和全局实例变量。我得到的最远的是让 clang 抱怨我的skip_grammar需要一个复制构造函数。因此,我尝试在我的跳过语法中添加一个复制构造函数,但显然 boost::noncopyable 基类的存在是有原因的,因为我的二进制文件几乎立即出现了段错误。
我应该如何使用这个?
谢谢
I have a grammar that has, up until now, been using the standard boost::spirit::ascii::space
/boost::spirit::ascii::space_type
skipper.
I have some rules that use the skipper and some that don't, like
qi::rule<Iterator, PTR<Expression>(), ascii::space_type> expression;
qi::rule<Iterator, PTR<Term>()> term;
When I use a non-skipping nonterminal (like term
) inside of a skipping nonterminal (like expression
), everything works like I would expect - whitespace only matters inside the term
nonterminal.
Further, up until now, I have been fine including nonterminals that use the skipper inside of nonterminals that don't using qi::skip
to restablish skipping, such as
index = (qi::lit('[') >> qi::skip(ascii::space)[explist >> qi::lit(']')]);
This way, whitespace is not significant inside of the []
braces, but is outside.
However, now I want to add my own custom skipper (I want to make newlines significant and later add comment-skipping). My skipper grammar looks like:
struct skip_grammar : qi::grammar<Iterator> {
qi::rule<Iterator> start;
skip_grammar() : skip_grammar::base_type(start) {
start = qi::char_("\t\r ");
}
};
I have been able to add it into my rule definitions just fine like
qi::rule<Iterator, PTR<Expression>(), skip_grammar> expression;
But I can't seem to figure out how to use my skip grammar as an argument to qi::skip
(and replace ascii::space
). I've tried using the type, a local instance variable, and a global instance variable. The farthest I've gotten is to get clang to complain that my skip_grammar needs a copy constructor. So I tried adding a copy constructor to my skip grammar, but apparently the boost::noncopyable
base class is there for a reason, because my binary segfaulted almost immediately.
How should I be using this?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
qi::grammar
只是qi::rules
的容器。它没有复制构造函数,因为这可能会无意中在这些规则右侧的解析器表达式中创建悬空引用。按照您的意愿使用语法作为跳过程序有点棘手,相当于将语法的起始规则传递给跳过解析器。为此创建一个规则实例可能会更容易(特别是如果您有一个规则队长)。
在任何情况下,规则都需要作为引用传递给船长(通过调用规则的成员函数
alias()
):或者简单地说:
别名是必要的,因为它的具体含义复制规则。 此处中的 Spirit 常见问题解答中有更详细的描述。
A
qi::grammar
is just a container forqi::rules
. It does not have a copy constructor because this could inadvertently create dangling references in the parser expressions on the right hand side of those rules.Using a grammar as a skipper as you want to do it is a bit tricky and amounts to passing the start rule of the grammar to the skip parser. It might be easier to just create a rule instance for that (especially if you have a single rule skipper).
In any case, the rule needs to be passed to the skipper as a reference (by calling the rule's member function
alias()
):or simply:
The aliasing is necessary because of the specifics of what it means to copy a rule. It is described in more detail in Spirit's FAQ here.