【问题标题】:Boost Spirit X3: skip parser that would do nothingBoost Spirit X3:跳过什么都不做的解析器
【发布时间】:2020-12-30 08:43:31
【问题描述】:

我正在熟悉 boost spirit v3。我想问的问题是如何说明您不想以任何方式使用跳过解析器这一事实。

考虑一个解析逗号分隔的整数序列的简单示例:

#include <iostream>
#include <string>
#include <vector>

#include <boost/spirit/home/x3.hpp>

int main()
{
    using namespace boost::spirit::x3;

    const std::string input{"2,4,5"};

    const auto parser = int_ % ',';
    std::vector<int> numbers;

    auto start = input.cbegin();
    auto r = phrase_parse(start, input.end(), parser, space, numbers);

    if(r && start == input.cend())
    {
        // success
        for(const auto &item: numbers)
            std::cout << item << std::endl;
        return 0;
    }

    std::cerr << "Input was not parsed successfully" << std::endl;
    return 1;
}

这完全没问题。但是,我想禁止在两者之间有空格(即 "2, 4,5" 不应该被很好地解析)。

我尝试在phrase_parse 中使用eps 作为跳过解析器,但您可以猜到,由于eps 匹配一个空字符串,因此程序最终进入了无限循环。

我找到的解决方案是使用no_skip 指令(https://www.boost.org/doc/libs/1_75_0/libs/spirit/doc/html/spirit/qi/reference/directive/no_skip.html)。所以解析器现在变成了:

const auto parser = no_skip[int_ % ','];

这很好用,但我认为它不是一个优雅的解决方案(尤其是在我不想跳过空格时在phrase_parse 中提供"space" 解析器)。有没有什么都不做的跳过解析器?我错过了什么吗?

感谢您的宝贵时间。期待任何回复。

【问题讨论】:

    标签: c++ boost boost-spirit boost-spirit-x3


    【解决方案1】:

    您可以使用no_skip[]lexeme[]。它们几乎相同,除了预跳过 (Boost Spirit lexeme vs no_skip)。

    有没有什么都不做的跳过解析器?我错过了什么吗?

    一个疯狂的猜测,但您可能错过了最初不接受船长的 parse API

    Live On Coliru

    #include <iostream>
    #include <iomanip>
    #include <boost/spirit/home/x3.hpp>
    namespace x3 = boost::spirit::x3;
    
    int main() {
        std::string const input{ "2,4,5" };
        auto f = begin(input), l = end(input);
    
        const auto parser = x3::int_ % ',';
        std::vector<int> numbers;
    
        auto r = parse(f, l, parser, numbers);
    
        if (r) {
            // success
            for (const auto& item : numbers)
                std::cout << item << std::endl;
        } else {
            std::cerr << "Input was not parsed successfully" << std::endl;
            return 1;
        }
    
        if (f!=l) {
            std::cout << "Remaining input " << std::quoted(std::string(f,l)) << "\n";
            return 2;
        }
    }
    

    打印

    2
    4
    5
    

    【讨论】:

    • 附言。对于几乎不匹配的船长,use x3::eps(false)。我突然想到,在所有更相关的信息之后,你可能仍然很好奇。
    • 谢谢,eps(false) 成功了。至于没有跳过解析器的phrase_parse 重载,上面的示例运行良好,但不适用于一些更复杂的解析器。不知道为什么
    • 另见stackoverflow.com/questions/17072987/…。大多数事情比照适用于 Spirit X3(除了船长现在严格地属于上下文的一部分)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多