我正在使用Boost Spirit x3,目前尚不清楚。我有一个文件,其中有很多不同的重复行。前几行可能是注释。接下来的1000行可能是坐标,接下来的1000行可能是int的列表,等等。

我的问题是如何识别该行并知道该行使用哪个解析器。例如,这是两个解析器函数...。

template <typename Iterator>
bool parse_ints(Iterator first, Iterator last, std::vector<int>& v)
{
    using x3::int_;
    using x3::phrase_parse;
    using x3::_attr;
    using ascii::space;

    auto push_back = [&](auto& ctx){ v.push_back(_attr(ctx)); };

    bool r = phrase_parse(first, last,
        (
            int_[push_back]
                >> *(',' >> int_[push_back])
        )
        ,
        space);

    if (first != last)
        return false;
    return r;
}

template <typename Iterator>
bool parse_doubles(Iterator first, Iterator last, std::vector<double>& v)
{
    using x3::double_;
    using x3::phrase_parse;
    using x3::_attr;
    using ascii::space;

    auto push_back = [&](auto& ctx){ v.push_back(_attr(ctx)); };

    bool r = phrase_parse(first, last,
        (
            double_[push_back]
                >> *(',' >> double_[push_back])
        )
        ,
        space);

    if (first != last) // fail if we did not get a full match
        return false;
    return r;
}

这是输入的方式(流是数百MB的大小)。而在while循环中,我想知道如何调用哪个解析器。
int main()
{
    istringstream str(my.data());

    while (getline(str, line)) {
        // based on the format of 'line', how does one know which
        // parser to call?
    }
}

最佳答案

您的语法可以描述整个输入。所以你可以说

auto input = *headerComment
          >> points
          >> edges;

您可以在哪里简单定义
auto headerComment = '#' >> *(char_ - eol) >> eol;

和例如
auto points = skip(blank) [
     *(point >> eol)
   ];

auto edges = skip(blank) [
     *(edge >> eol)
   ];

point = int_ >> int_ >> int_; // assuming x y z
edge  = int_ >> int_;         // assuming from to

这假定输入格式是明确的。即如果点仅是x y,那是行不通的,因为那样就无法将其与边缘区分开。

关于c++ - 使用Spirit x3,如何控制在每个不同的输入上调用哪个解析器?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44611506/

10-11 19:43