提升灵气重新建立跳跃与自定义跳跃语法

发布于 2024-10-17 17:45:49 字数 1319 浏览 0 评论 0原文

我有一个语法,到目前为止,一直使用标准 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

書生途 2024-10-24 17:45:49

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

按照您的意愿使用语法作为跳过程序有点棘手,相当于将语法的起始规则传递给跳过解析器。为此创建一个规则实例可能会更容易(特别是如果您有一个规则队长)。

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

skip_grammar skippper;
index = '[' >> qi::skip(skipper.start.alias())[explist >> ']'];

或者简单地说:

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

别名是必要的,因为它的具体含义复制规则。 此处中的 Spirit 常见问题解答中有更详细的描述。

A qi::grammar is just a container for qi::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()):

skip_grammar skippper;
index = '[' >> qi::skip(skipper.start.alias())[explist >> ']'];

or simply:

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文