X3, what is attr_gen?
Asked Answered
I

2

2

I end up getting these move errors a lot and am not quite sure why other than having something to do with the way I'm parsing strings. Remove everything having to do with 'dummy' and the errors come back.

Someone mentioned using attr_gen (couldn't find this in the docs) and by doing so, I can get past these "traits::move_to" compile errors, but the parser still fails. I've marked the lines that I've added to get it to compile, but don't think are necessary with "<---".

#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"; }
}
Impressionable answered 18/7, 2017 at 4:12 Comment(6)
If you split out the question about parsing till the end of the line... Asking two unrelated questions at once just makes the question unuseful to others in the future.Preemption
So you forgot about the other question? I've got the answer sitting here waitingPreemption
Had to run off, was thinking it looked simple enough. Removed the 'till eol' question. However, I've tried all three of these methods and continue to get errors. I'm not too familiar with the differences of Qi and X3, but I'm using X3. I've changed my parse to phrase_parse but somehow the rule doesn't mix well w/ what I have. "keep string workaround" is the method I've chosen to focus on since it seemed a good workaround fit.Impressionable
Here's what I tried ... coliru.stacked-crooked.com/a/8c83f3513ba411bdImpressionable
I've no clue about all your confusion. What is "all three of these methods". What is "the rule" (which one) "doesn't mix well" (uhm, what happens) with "what I have" (what do you have). "keep string workaround" - what does that mean? Anyhow, it's your question of course, and I've just un-deleted the answer to your till-eof question so you might find some use for it regardlessPreemption
You're link to "Spirit Qi attribute propagation ..." in which you answered all the questions in which you just asked are there. Also, what I have is in the coliru link, just two comments up. Had you posted the till-eof question and not asked to split it out, I'd have left it. Either way, I thank you for helping.Impressionable
P
3

x3::attr() is perfectly well documented (the generator type behind it is an implementation detail, much like you'd use x3::int_, not x3::int_gen).

The fact that you need it has been answered before. The key is having single-element fusion sequences.

Preemption answered 18/7, 2017 at 8:50 Comment(0)
P
0
comment = char_ % ' ';

This parses 1 or more arbitrary characters separated by single space literals. In your case it may match only 't' because what follows is 'h', not a ' '.

I'd naturally spell that

comment = *(char_ - eol);

So it would match anything until eol. If you insist on matching "wordy" things, by all means

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

To synthesize the matched input into a string attribute, wrap it in raw[]:

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

Or if, indeed you want no other whitespace than ' ', make it so

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

It's slightly weird to spell it like

comment = raw[ (+graph_) % ' ' ];

Because

  • it doesn't match an empty line
  • it doesn't match "hello world" or `"hello\tworld"'
Preemption answered 18/7, 2017 at 9:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.