簡體   English   中英

如何使用 boost::spirit 解析兩個字符串?

[英]How to parse two strings using boost::spirit?

我仍在嘗試圍繞 Boost::Spirit。
我想將兩個單詞解析為一個變量。 當我可以做到這一點時,進入一個結構。

單個詞編譯,變量沒有。 為什么?

#include <boost/spirit/include/qi.hpp>
#include <boost/tuple/tuple.hpp>
#include <string>
#include <iostream>

using namespace boost::spirit;

/*
class Syntax : public qi::parser{

};
*/

int main()
{
    //get user input
    std::string input;
    std::getline(std::cin, input);
    auto it = input.begin();

    bool result;
    //define grammar for a single word
    auto word_grammar = +qi::alnum - qi::space;

    std::string singleWord;

    result = qi::parse(
        it, input.end(),
        word_grammar,
        singleWord
    );

    if(!result){
        std::cout << "Failed to parse a word" << '\n';
        return -1;
    }

    std::cout << "\"" << singleWord << "\"" << '\n';

    //Now parse two words into a variable
    std::cout << "Variable:\n";
    typedef boost::tuple<std::string, std::string> Variable;
    Variable variable;
    auto variable_grammar = word_grammar >> word_grammar;

    result = qi::parse(
        it, input.end(),
        variable_grammar,
        variable
    );

    if(!result){
        std::cout << "Failed to parse a variable" << '\n';
        return -1;
    }

    std::cout << "\"" << variable.get<0>() << "\" \"" << variable.get<1>() << "\"" << '\n';

    //now parse a list of variables
    std::cout << "List of Variables:\n";
    std::list<Variable> variables;

    result = qi::parse(
        it, input.end(),
        variable_grammar % +qi::space,
        variable
    );

    if(!result){
        std::cout << "Failed to parse a list of variables" << '\n';
        return -1;
    }

    for(auto var : variables)
        std::cout << "DataType: " << var.get<0>() << ", VariableName: " << var.get<1>() << '\n';

}

最后我想解析這樣的東西:

int a
float b
string name

模板很好,但是當出現問題時,錯誤消息就不是人類可讀的(因此在這里發布它們沒有意義)。
我正在使用 gcc

單個詞編譯,變量沒有。 為什么?

缺少兩個#includes:

#include <boost/fusion/adapted/boost_tuple.hpp>
#include <boost/spirit/include/qi_list.hpp>

抱歉拖了這么久。 我一直在匆忙構建一個新的 Web 服務器,並且有很多東西要學習。

這是它在X3樣子。 我認為它比qi更容易處理。 然后,我使用了更多。 但是qi更成熟,更豐富。 也就是說, x3旨在具有適應性和可破解性。 所以你可以讓它做任何你想做的事情。

所以,住在coliru上

#include <string>
#include <iostream>
#include <vector>
#include <boost/spirit/home/x3.hpp>
#include <boost/tuple/tuple.hpp>
//as pointed out, for the error 'The parser expects tuple-like attribute type'
#include <boost/fusion/adapted/boost_tuple.hpp>

//our declarations
using Variable = boost::tuple<std::string, std::string>;
using Vector = std::vector<Variable>;

namespace parsers {
    using namespace boost::spirit::x3;

    auto const word = lexeme[+char_("a-zA-Z")];
    //note, using 'space' as the stock skipper
    auto const tuple = word >> word;
}

std::ostream& operator << (std::ostream& os, /*const*/ Variable& obj) {
    return os << obj.get<0>() << ' ' << obj.get<1>();
}

std::ostream& operator << (std::ostream& os, /*const*/ Vector& obj) {
    for (auto& item : obj)
        os << item << " : ";
    return os;
}

template<typename P, typename A>
bool test_parse(std::string in, P parser, A& attr) {
    auto begin(in.begin());
    bool r = phrase_parse(begin, in.end(), parser, boost::spirit::x3::space, attr);
    std::cout << "result:\n " << attr << std::endl;
    return r;
}

int main()
{
    //not recomended but this is testing stuff
    using namespace boost::spirit::x3;
    using namespace parsers;

    std::string input("first second third forth");

    //parse one word
    std::string singleWord;
    test_parse(input, word, singleWord);

    //parse two words into a variable
    Variable variable;
    test_parse(input, tuple, variable);

    //parse two sets of two words
    Vector vector;
    test_parse(input, *tuple, vector);
}

您可能喜歡這種形式的測試。 您可以專注於測試解析器而無需大量額外代碼。 它可以更輕松地將基本解析器保留在自己的命名空間中。 哦,是的, x3編譯速度比qi快得多!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM