c++ - 我如何在 boost::spirit::qi 中解析带有换行符的列表?

标签 c++ parsing boost

我想知道如何在 boost::spirit::qi 中用换行符解析 python 样式列表。

一个基本的解析器将是:

list_ = '[' >> -(test_ % ',') >> -lit(",") >> ']';

boost::spirit::ascii::space 作为 skipper 。

但是在我的例子中,我想自己在其他语法规则中明确匹配换行符。结果,我切换到 boost::spirit::ascii::blank 作为 skipper 。虽然我仍然想在列表的定义中允许换行。

我最终得出这样的结论:

list_ = '[' >> -(test_ % (-eol >> ',' >> -eol)) >> -lit(",") >> -eol >> ']';

基本上我在每个可能的位置添加了eol。这种语法有效,但看起来很糟糕。

有没有更简洁的方法来实现这一点?或者更具体地说,如果可以包含 eol 作为单个规则而不是整个语法的 skipper 。

最佳答案

只需为相关部分使用单独的 skipper 。

只是将 skipper “烘焙”到语法的外部接口(interface)中,这有点像教程中的固定装置。在 99% 的情况下,这根本没有意义:更改 skipper 会破坏语法。所以,我已经开始按照众神的意图封装 skipper (开玩笑):

代替

template <typename It>
struct MyGrammar : qi::grammar<It, Attribute(), qi::space_type> {
    MyGrammar() : MyGrammar::base_type(start) {
        start = /*....*/;
    }
  private:
    qi::rule<It, Attribute(), qi::space_type> start;
};

我写

template <typename It>
struct MyGrammar : qi::grammar<It, Attribute()> {
    MyGrammar() : MyGrammar::base_type(start) {
        start = qi::skip(qi::space) [ mainRule ];
        mainRule = /*....*/;
    }
  private:
    qi::rule<It, Attribute()> start;
    qi::rule<It, Attribute(), qi::space_type> mainRule;
};

这意味着你可以写

bool ok = qi::parse(f,l, MyGrammar<It>{});

它仍然会使用正确的 skipper 。即使你做了

bool ok = qi::phrase_parse(f, l, MyGrammar<It>{}, qi::char_);

它仍然会使用正确的 skipper !

不同规则的不同 skipper

您必须决定您的主要 skipper 是什么,但是您可以使用 qi::skip()[] 指令来切换任意 skipper 。所以让我们假设,就像在大多数编程语言中一样,换行符通常是无意义的空格,所以你会有

qi::rule<It, qi::space_type> a_whole, bunch_of, rules;

然后在您的 bunch_of 规则中您要使用 differentRule ,它确实有明显的空白:

qi::rule<It, qi::blank_type> differentRule;

然后你像这样切换它:

bunch_of = "stuff" >> '{' >> qi::skip(qi::blank) [ differentRule ] >> '}';

就是这样。当然,如果你不想在 differentRule 中完全跳过,你可以像往常一样使用 qi::lexeme[],或者实际上只是从规则声明中删除了 skipper :

// implicit lexeme
qi::rule<It> differentRule;

背景

以上所有内容都在这个更广泛的答案中进行了详细说明:Boost spirit skipper issues

关于c++ - 我如何在 boost::spirit::qi 中解析带有换行符的列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47046805/

相关文章:

c++ - get_unit_value 在 boost ODEINT 中的作用

c++ - 在Android设备上获取COCOS2D-X中文件的完整路径

mysql - 在mysql中解析字符串并获取日期

c++ - 如何使用 Boost 实现 C++14 风格的自动返回类型?

android - android应用程序中的json解析问题

java - 从字符串中删除特殊字符

c++ - 如何重现 Boost 流程文档提示的死锁?

c++ - 如何在 Linux 上使用带有 EG20T 芯片组的英特尔凌动 Q7 模块上的 CAN 总线?

c++ - 使用字符串和整数对对 vector 进行排序

c++ - 在 C/C++ 中调用 MATLAB API