使用boost-spirit将字符串解析为QStrings的结构

时间:2019-06-07 08:29:44

标签: c++ boost-spirit qstring

今天,我尝试使用boost-spirit编写一个非常简单的解析器。

现在,我偶然遇到了一个障碍,我真的不知道该如何解决。

基本上,我希望语义操作返回QString而不是Stl std::string。我还想在语义动作中以非常简单的方式进行这种转换,因为将会有更多的QString对象通过。最终目标是将所有这些QString打包到一个通用结构中。

(QString是std::string的Qt-Framework等效项。)

这是我到目前为止所得到的。

#include <QString>

#include <vector>
#include <iostream>
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/phoenix/object/construct.hpp>

class QStringHelper {
public:
    QStringHelper() {}
    QStringHelper(const std::string& string) : mString(QString::fromStdString(string)){

    }
    // This operator might help?
    QString operator()() const {
        return mString;
    }
    QString mString;
};

template <typename Iterator, typename Skipper>
struct grammar : boost::spirit::qi::grammar<Iterator, void(), Skipper>
{
    QString color;
    std::string stdColor; 
    QStringHelper helper;

    grammar() : grammar::base_type(listOfProperties)
    {
        namespace fusion = boost::fusion;
        namespace phoenix = boost::phoenix;
        namespace qi = boost::spirit::qi;
        namespace ascii = boost::spirit::ascii;

        using qi::lit;
        using qi::lexeme;
        using ascii::char_;
        using ascii::string;
        using boost::phoenix::ref;
        using namespace qi::labels;


        listOfProperties = (colorProperty % lit(";"));
        // 1. Works, but is not what I desire!
        // colorProperty = lit("color") >> lit(":") >> qi::as_string[lexeme[+(char_ - ';')]][boost::phoenix::ref(stdColor) =_1];

        // 2. Cannot compile, as QString has not constructor like QString(const std::string&)
        // colorProperty = lit("color") >> lit(":") >> qi::as_string[lexeme[+(char_ - ';')]][boost::phoenix::ref(color) = boost::phoenix::construct<QString>(_1)]; 

        // 3. Does compile, but is not exactly what I desire!
        colorProperty = lit("color") >> lit(":") >> qi::as_string[lexeme[+(char_ - ';')]][boost::phoenix::ref(helper) = boost::phoenix::construct<QStringHelper>(_1)]; 

        // 4. My desired solution, that I really don't know what someMagicExpression might be?
        // colorProperty = lit("color") >> lit(":") >> qi::as_string[lexeme[+(char_ - ';')]][boost::phoenix::ref(color) = someMagicExpression(_1)];

        // Many more complex properties will go by!
    }

    boost::spirit::qi::rule<Iterator, void(), Skipper> listOfProperties;
    boost::spirit::qi::rule<Iterator, void(), Skipper> colorProperty;
};



int main(int argc, char**args) {
    try {
        std::string stringToParse = "color:#ff00ff";
        boost::spirit::qi::space_type space;
        grammar<std::string::const_iterator, decltype(space)> parser;
        auto b = stringToParse.begin();
        auto e = stringToParse.end();
        bool ok = boost::spirit::qi::phrase_parse(b, e, parser, space);
        if (b != e) {
            return EXIT_SUCCESS;
        }
        else {
            std::cout << "Color: " << parser.color.toStdString();
        }
        return EXIT_SUCCESS;
    }
    catch (const boost::spirit::qi::expectation_failure<std::string::iterator>&) {
        return EXIT_FAILURE;
    }
}

0 个答案:

没有答案