【问题标题】:Parsing two vectors of strings using boost:qi使用 boost:qi 解析两个字符串向量
【发布时间】:2017-04-11 04:21:12
【问题描述】:

我刚开始使用气,遇到了困难。我希望解析如下输入:

X + Y + Z , A + B

分成两个字符串向量。

我有代码这样做,但前提是语法解析单个字符。理想情况下,以下行应该是可读的:

习+夜+邹、敖+毕

使用诸如elem = +(char_ - '+') % '+' 之类的简单替换无法解析,因为它会消耗第一个元素上的“,”,但我还没有找到解决此问题的简单方法。

这是我的单字符代码,供参考:

#include <bits/stdc++.h>

#define BOOST_SPIRIT_DEBUG
#include <boost/fusion/adapted.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>

namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;

typedef std::vector<std::string> element_array;

struct reaction_t
{
  element_array reactants;
  element_array products;
};

BOOST_FUSION_ADAPT_STRUCT(reaction_t, (element_array, reactants)(element_array, products))

template<typename Iterator>
struct reaction_parser : qi::grammar<Iterator,reaction_t(),qi::blank_type>
 {
    reaction_parser() : reaction_parser::base_type(reaction)
    {
        using namespace qi;

    elem = char_ % '+';
    reaction = elem >> ',' >> elem;

    BOOST_SPIRIT_DEBUG_NODES((reaction)(elem));
    }
    qi::rule<Iterator, reaction_t(), qi::blank_type> reaction;
    qi::rule<Iterator, element_array(), qi::blank_type> elem;
};
int main()
{

    const std::string input = "X + Y + Z, A + B";
    auto f = begin(input), l = end(input);

    reaction_parser<std::string::const_iterator> p;
    reaction_t data;

    bool ok = qi::phrase_parse(f, l, p, qi::blank, data);

    if (ok) std::cout << "success\n";
    else    std::cout << "failed\n";

    if (f!=l)
        std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
}

【问题讨论】:

    标签: c++ boost boost-spirit boost-spirit-qi


    【解决方案1】:

    使用简单的替换,例如 elem = +(char_ - '+') % '+' 无法解析,因为它会消耗第一个 elem 上的 ',',但我还没有找到简单的解决方法这个。

    嗯,完整(无脑)简单的解决方案是使用+(char_ - '+' - ',')+~char_("+,")

    不过,真的,我会为element 制定更具体的规则,例如:

        elem     = qi::lexeme [ +alpha ] % '+';
    

    请参阅Boost spirit skipper issues 了解词位和船长

    Live On Coliru

    #include <boost/fusion/adapted.hpp>
    #include <boost/spirit/include/qi.hpp>
    #include <boost/spirit/include/phoenix.hpp>
    
    namespace qi = boost::spirit::qi;
    namespace phx = boost::phoenix;
    
    typedef std::vector<std::string> element_array;
    
    struct reaction_t
    {
        element_array reactants;
        element_array products;
    };
    
    BOOST_FUSION_ADAPT_STRUCT(reaction_t, (element_array, reactants)(element_array, products))
    
    template<typename Iterator>
    struct reaction_parser : qi::grammar<Iterator,reaction_t(),qi::blank_type>
    {
        reaction_parser() : reaction_parser::base_type(reaction) {
            using namespace qi;
    
            elem     = qi::lexeme [ +alpha ] % '+';
            reaction = elem >> ',' >> elem;
    
            BOOST_SPIRIT_DEBUG_NODES((reaction)(elem));
        }
        qi::rule<Iterator, reaction_t(), qi::blank_type> reaction;
        qi::rule<Iterator, element_array(), qi::blank_type> elem;
    };
    
    int main()
    {
        reaction_parser<std::string::const_iterator> p;
    
        for (std::string const input : {
                "X + Y + Z, A + B",
                "Xi + Ye + Zou , Ao + Bi",
                })
        {
            std::cout << "----- " << input << "\n";
            auto f = begin(input), l = end(input);
    
            reaction_t data;
    
            bool ok = qi::phrase_parse(f, l, p, qi::blank, data);
    
            if (ok) {
                std::cout << "success\n";
                for (auto r : data.reactants) { std::cout << "reactant: " << r << "\n"; }
                for (auto p : data.products)  { std::cout << "product:  " << p << "\n"; }
            }
            else
                std::cout << "failed\n";
    
            if (f != l)
                std::cout << "Remaining unparsed: '" << std::string(f, l) << "'\n";
        }
    }
    

    印刷:

    ----- X + Y + Z, A + B
    success
    reactant: X
    reactant: Y
    reactant: Z
    product:  A
    product:  B
    ----- Xi + Ye + Zou , Ao + Bi
    success
    reactant: Xi
    reactant: Ye
    reactant: Zou
    product:  Ao
    product:  Bi
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-06
      • 2019-12-10
      • 2017-04-10
      相关资源
      最近更新 更多