X3,什么是attr_gen?

时间:2017-07-18 04:12:46

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

我最终得到了这些移动错误,并且我不太确定为什么除了与我解析字符串的方式有关之外。删除与'dummy'有关的所有内容,然后错误就会消失。

有人提到使用attr_gen(在文档中找不到这个),通过这样做,我可以通过这些“traits :: move_to”编译错误,但解析器仍然失败。我已经标记了我为了编译而添加的行,但不认为“< ---”是必要的。

#define BOOST_SPIRIT_X3_DEBUG

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

#include <boost/spirit/home/x3.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>

namespace client { 
    namespace ast {
        struct number {
            int num1;
            int num2;  
        };

        struct comment {
            std::string text;
            bool dummy;     // <---
        };

        struct input {
            std::vector<comment> comments;  
            std::vector<number> numbers;
        };
    } 
}

BOOST_FUSION_ADAPT_STRUCT(client::ast::comment, text, dummy)    // <---
BOOST_FUSION_ADAPT_STRUCT(client::ast::number, num1, num2)
BOOST_FUSION_ADAPT_STRUCT(client::ast::input, comments, numbers)

namespace client {      
    namespace parser {

        namespace x3 = boost::spirit::x3;
        namespace ascii = boost::spirit::x3::ascii;

        using namespace x3;
        x3::attr_gen dummy;   // <---                   

        auto const comment = char_ % ' ' >> dummy(false);       // <---
        //auto const comment = lexeme[+graph] >> dummy(false);
        auto const number = int_ >> int_;

        auto lines = [](auto p) { return *(p >> eol); };

        auto const input = skip(blank) [
            lines(comment) >> 
            lines(number)
        ];
    }
}

int main()
{
    namespace x3 = boost::spirit::x3;
    using boost::spirit::x3::ascii::blank;
    using x3::char_;

    std::string const iss(R"(this is a test
    1 2)");

    auto iter = iss.begin(), eof = iss.end();

    client::ast::input types;

    bool ok = parse(iter, eof, client::parser::input, types);

    if (iter != eof) {
        std::cout << "Remaining unparsed: '" << std::string(iter, eof) << "'\n";
    }
    std::cout << "Parsed: " << (100.0 * std::distance(iss.begin(), iter) / iss.size()) << "%\n";
    std::cout << "ok = " << ok << std::endl;

    for (auto& item : types.comments)    { std::cout << boost::fusion::as_deque(item) << "\n"; }
    for (auto& item : types.numbers)    { std::cout << boost::fusion::as_deque(item) << "\n"; }
}

2 个答案:

答案 0 :(得分:3)

x3::attr()完全正常documented(其后面的生成器类型是一个实现细节,就像你使用x3::int_,而不是x3::int_gen)。

您需要它的事实之前已得到回答。关键是具有单元素融合序列。

答案 1 :(得分:0)

comment = char_ % ' ';

这解析由单个空格文字分隔的1个或多个任意字符。在您的情况下,它可能只与't'匹配,因为后面的内容是'h',而不是' '

我自然会拼写

comment = *(char_ - eol);

所以在eol之前它会匹配任何东西。如果你坚持匹配&#34;罗嗦&#34;事情,无论如何

comment = skip(blank) [ *lexeme[+graph_] ];

要将匹配的输入合成为字符串属性,请将其包装在raw[]

comment = raw [ skip(blank) [ *graph_ ] ];

或者,如果您确实不想要除' '之外的其他空格,那么就这样做

comment = raw[ skip(' ') [ *graph_ ] ];

一样拼写它有点奇怪
comment = raw[ (+graph_) % ' ' ];

由于

  • 它不匹配空行
  • 它不匹配"hello world"或`&#34; hello \ tworld&#34;&#39;