如何使用Boost Spirit X3 Kleene Star?

时间:2018-10-14 09:58:57

标签: c++ boost boost-spirit

我是boost::spirit的新手,正在尝试使用x3编写一个简单的解析器。 我遇到了我无法解释的错误。 由于某种原因,我收到关于boost::spirit::x3::unused_type的错误。 当我在下面标记的行中删除支流星时,错误消失。 其他克利恩星似乎还不错(由于某种原因)。 这是我的代码:

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

namespace x3 = boost::spirit::x3;

int main()
{
    std::string str = "qqq::qqq::qqq";

    auto begin = str.begin(), end   = str.end();
    bool r = x3::parse(begin, end,
        (        (x3::alpha | '_') >> *(x3::alnum | '_')) >>
        *                                         //this line is the problem
        ("::" >> (x3::alpha | '_') >> *(x3::alnum | '_'))
    ); // is supposed to match str

    if (r && std::distance(begin,end) < 1)
    {
        std::cout << "Parsing succeeded\n";
    }
    else
    {
        std::cout << "Parsing FAILED\n";
        std::cout << "r " << r << " d " << std::distance(begin,end) << "\n";
    }

    return 0;
}

这是错误:

/usr/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp:254:22: error: ‘const struct boost::spirit::x3::unused_type’ has no member named ‘empty’
254 |             if (attr.empty())
    |                 ~~~~~^~~~~
/usr/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp:259:22: error: ‘const struct boost::spirit::x3::unused_type’ has no member named ‘insert’
259 |                 attr.insert(attr.end(), rest.begin(), rest.end());
    |                 ~~~~~^~~~~~
/usr/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp:259:34: error: ‘const struct boost::spirit::x3::unused_type’ has no member named ‘end’
259 |                 attr.insert(attr.end(), rest.begin(), rest.end());
    |                             ~~~~~^~~
/usr/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp:259:46: error: ‘const struct boost::spirit::x3::unused_type’ has no member named ‘begin’
259 |                 attr.insert(attr.end(), rest.begin(), rest.end());
    |                                         ~~~~~^~~~~
/usr/include/boost/spirit/home/x3/core/detail/parse_into_container.hpp:259:60: error: ‘const struct boost::spirit::x3::unused_type’ has no member named ‘end’
259 |                 attr.insert(attr.end(), rest.begin(), rest.end());
    |                                                       ~~~~~^~~

我在使用Boost 1.65.1的Ubuntu 18.04上。 我读了这篇(https://stackoverflow.com/a/49121776/2359966)帖子,其中描述了类似的问题。

是否可以在不更改系统软件包的情况下解决或避免此问题?

1 个答案:

答案 0 :(得分:2)

不,这只是一个已修复的错误。

无论如何,像x3::alpha | '_'这样的语法构造不会显示您所需的内容,因为文字 '_'不会显示任何属性。

因此,实际上,您可能只想使用raw[]进行简化:

auto ident = x3::raw [ x3::lexeme [ (x3::alpha | '_') >> *(x3::alnum | '_') ] 

接下来,您可以匹配多个::限定的标识符:

x3::raw [ ident >> * ("::" >> ident) ]

顺便说一句,完全等同于

x3::raw [ ident % "::") ]

请参见

奖金:

分配属性

Live On Coliru

#include <boost/spirit/home/x3.hpp>
#include <iostream>
#include <iomanip>
#include <string>

namespace x3 = boost::spirit::x3;

int main() {
    std::string str = "foo::_bar::qux_1";

    auto begin = str.begin(), end = str.end();
    auto ident = x3::raw [ x3::lexeme [ (x3::alpha | '_') >> *(x3::alnum | '_') ] ];

    std::vector<std::string> qualified;
    bool r = x3::parse(begin, end, ident % "::", qualified);

    if (r && begin==end) {
        std::cout << "Parsing succeeded\n";
        for (auto& el : qualified) {
            std::cout << " element " << std::quoted(el) << "\n";
        }
    } else {
        std::cout << "Parsing FAILED\n";
    }

    std::cout << std::boolalpha << r << " " << std::quoted(std::string(begin, end)) << "\n";
}

打印:

Parsing succeeded
 element "foo"
 element "_bar"
 element "qux_1"
true ""

语法被简化为

std::vector<std::string> qualified;
bool r = x3::parse(begin, end, ident % "::", qualified);

通常这是一个好兆头。