Boost Spirit X3 нет подходящей ссылки для вызова при вставке строк в вектор - PullRequest
0 голосов
/ 03 июля 2018

Здравствуйте, я пытаюсь использовать spirit x3 для заполнения строк в векторе, но я получаю следующую ошибку. Код прямо из документации, за исключением того, что вектор использует строки.

error: no matching function for call to 
std::vector<std::__cxx11::basic_string<char> 
>::push_back(boost::spirit::x3::unused_type&)’
auto push_back = [&](auto& ctx){ slt.push_back(_attr(ctx)); };`

Мой код выглядит следующим образом, я думаю, что все необходимые включения включены (это внутри метода класса):

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

#include <algorithm>
#include <bitset>
#include <fstream>
#include <iostream>
#include <iterator>
#include <map>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>

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

using x3::double_;
using x3::phrase_parse;
using x3::_attr;
using x3::parse;
using x3::lit;
using x3::char_;
using x3::lexeme;
using x3::alpha;
using x3::alnum;
using x3::skip;
using ascii::space;

/*Something,something.......*/

auto name = x3::rule<class name>{}
                = char_("a-zA-Z") >> *char_("a-z_A-Z0-9");

auto args_l = x3::rule<class l>{}
                = " " >> (name % skip(space)[","]);

auto comment = x3::rule<class comment>{}
                = "//" >> *char_;

auto iter_start = line.begin();
auto iter_end = line.end();

vector<string> slt;

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


bool result = parse(
        iter_start,
        iter_end,
        name[push_back] >> -args_l >> *(char_(" "))
);

/ Что-то, что-то ....... /

Ответы [ 2 ]

0 голосов
/ 03 июля 2018

После ответив вопрос как есть, я посмотрел ваш код.

БОНУС

Учитывая остальную часть вашего кода, возможно, это то, что вы ищете:

Live On Wandbox

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

namespace x3 = boost::spirit::x3;

namespace P {
    using namespace x3;

    auto name = x3::rule<class name, std::string>{}
        = lexeme [char_("a-zA-Z") >> *char_("a-z_A-Z0-9")];

    auto comment = x3::rule<class comment>{}
        = "//" >> *(char_-eol) 
        | "/*" >> *(char_ - "*/") >> "*/";

    auto args_l = skip(space|comment) [name % ','];
}

#include <iostream>
#include <iomanip>

int main() {
    for (std::string const line : { 
            "a90_b",
            "a90_b,   /*comment ignored*/ b8, //more stuff\nz",
        })
    {
        std::cout << "Parsing " << std::quoted(line) << "\n";

        auto iter_start = line.begin();
        auto iter_end   = line.end();

        std::vector<std::string> slt;
        bool result = parse(iter_start, iter_end, P::args_l, slt);

        if (result) {
                for (auto& tok: slt) {
                    std::cout << " -> " << std::quoted(tok) << "\n";
                }
        } else {
            std::cout << "Parsed failed\n";
        }

        if (iter_start!=iter_end) {
            std::cout << "Remaining unparsed: " << std::quoted(std::string(iter_start, iter_end)) << "\n";
        }
    }
}

печать

Parsing "a90_b"
 -> "a90_b"
Parsing "a90_b,   /*comment ignored*/ b8, //more stuff
z"
 -> "a90_b"
 -> "b8"
 -> "z"
0 голосов
/ 03 июля 2018

Ваше определение правила не предоставляет атрибут.

Как указал @llonesmiz, исправьте это:

auto name = x3::rule<class name, std::string>{}
    = char_("a-zA-Z") >> *char_("a-z_A-Z0-9");

И посмотри Live On Wandbox (boost-1.67)

Примечание: ошибки

Если у вас есть Boost 1.65-1.66, вы столкнетесь с Как создать рекурсивное правило в Boost Spirit x3 в VS2017 , ( Live On Wandbox который был исправлен в Boost 1.67 (и ранее, кстати, например, Live на Wandbox / Boost 1.64 )

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

namespace x3 = boost::spirit::x3;

namespace P {
    using namespace x3;

    auto name = x3::rule<class name, std::string>{}
        = char_("a-zA-Z") >> *char_("a-z_A-Z0-9");

    auto args_l = x3::rule<class l>{}
        = " " >> (name % skip(space)[","]);

    auto comment = x3::rule<class comment>{}
        = "//" >> *char_;
}

#include <iostream>
#include <iomanip>

int main() {
    std::string const line = "a90_b";
    auto iter_start = line.begin();
    auto iter_end = line.end();

    std::vector<std::string> slt;

    auto push_back = [&](auto& ctx){ slt.push_back(x3::_attr(ctx)); };

    bool result = parse(
            iter_start,
            iter_end,
            P::name[push_back] >> -P::args_l >> *x3::char_(" ")
        );

    for (auto& tok: slt) {
        std::cout << std::quoted(tok) << "\n";
    }

    if (iter_start!=iter_end)
        std::cout << "Remaining unparsed: " << std::quoted(std::string(iter_start, iter_end)) << "\n";

    return result? 0 : 255;
}
...