2012-11-22 35 views
1

我想解析并捕获此字符串"{ABC,HIJ}:{10,15,20}"struct indicator_rec助推精神std ::向量<unsigned>解析但未捕获

解析成功,但只有第一组{ABC,HIJ}被捕获到std::vector<std::string>字段中。

第二部分,{10,15,20}被正确解析,但未能成为第二个字段std::vector<unsigned>

我在做什么错?

输出:

<equation> 
    <try>{ABC,HIJ}:{10,15,20}</try> 
    <indicator> 
    <try>{ABC,HIJ}:{10,15,20}</try> 
    <fail/> 
    </indicator> 
    <indicators> 
    <try>{ABC,HIJ}:{10,15,20}</try> 
    <indicator> 
     <try>ABC,HIJ}:{10,15,20}</try> 
     <success>,HIJ}:{10,15,20}</success> 
     <attributes>[[A, B, C]]</attributes> 
    </indicator> 
    <indicator> 
     <try>HIJ}:{10,15,20}</try> 
     <success>}:{10,15,20}</success> 
     <attributes>[[H, I, J]]</attributes> 
    </indicator> 
    <success>:{10,15,20}</success> 
    <attributes>[[[A, B, C], [H, I, J]]]</attributes> 
    </indicators> 
    <parameters> 
    <try>{10,15,20}</try> 
    <parameter> 
     <try>10,15,20}</try> 
     <success>,15,20}</success> 
     <attributes>[]</attributes> 
    </parameter> 
    <parameter> 
     <try>15,20}</try> 
     <success>,20}</success> 
     <attributes>[]</attributes> 
    </parameter> 
    <parameter> 
     <try>20}</try> 
     <success>}</success> 
     <attributes>[]</attributes> 
    </parameter> 
    <success></success> 
    <attributes>[[]]</attributes> 
    </parameters> 
    <success></success> 
    <attributes>[[[[A, B, C], [H, I, J]], []]]</attributes> 
</equation> 

代码:

#define BOOST_SPIRIT_DEBUG 
#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_stl.hpp> 
#include <boost/spirit/include/classic_symbols.hpp> 
#include <boost/fusion/include/adapt_struct.hpp> 
#include <boost/fusion/include/io.hpp> 

#include <boost/algorithm/string.hpp> 
#include <boost/regex.hpp> // std::regex not fully implemented in stdc++ yet 

#include <string> 
#include <map> 
#include <utility> 
#include <functional> 

// ----------------------------------------------------------------------------- 
namespace client 
{ 
    namespace qi  = boost::spirit::qi; 
    namespace ascii = boost::spirit::ascii; 
    namespace spirit = boost::spirit; 
    namespace phoenix = boost::phoenix; 

    // --------------------------------------------------------------------------- 
    struct indicator_rec 
    { 
    public: 
     indicator_rec() { } 

     std::vector<std::string> m_indicators; 
     std::vector<unsigned>  m_parameters; 
    }; 
} 

BOOST_FUSION_ADAPT_STRUCT(
    client::indicator_rec, 
    (std::vector<std::string>, m_indicators) 
    (std::vector<unsigned>,  m_parameters) 
) 

namespace client 
{ 
    // --------------------------------------------------------------------------- 
    template <typename Iterator> 
    struct system_parser : 
     qi::grammar<Iterator, ascii::space_type, indicator_rec()> 
    { 
      system_parser() : 
       system_parser::base_type(equation) 
      { 
        using qi::double_; 
        using qi::_val; 
        using qi::_1; 
        using boost::spirit::ascii::string; 

        equation %= 
          (indicator | indicators)      
          >> ':' 
          >> (parameters | parameter) 
          ; 

        indicator %= (string("ABC")|string("HIJ")) 
          ; 

        indicators %= '{' >> (indicator % ',') >> '}' 
          ; 

        parameter %= qi::uint_ 
          ; 

        parameters %= '{' >> (parameter % ',') >> '}' 
          ; 

        BOOST_SPIRIT_DEBUG_NODE(equation); 
        BOOST_SPIRIT_DEBUG_NODE(parameter); 
        BOOST_SPIRIT_DEBUG_NODE(parameters); 
        BOOST_SPIRIT_DEBUG_NODE(indicator); 
        BOOST_SPIRIT_DEBUG_NODE(indicators); 
      } 

      qi::rule<Iterator, ascii::space_type, indicator_rec()> 
       equation; 

      qi::rule<Iterator, ascii::space_type, std::vector<std::string>()> 
       indicators; 

      qi::rule<Iterator, ascii::space_type, std::string()> 
       designator, indicator; 

      qi::rule<Iterator, ascii::space_type, unsigned> 
       parameter; 

      qi::rule<Iterator, ascii::space_type, std::vector<unsigned>()> 
       parameters; 
    }; 

    template <typename Iterator> 
    bool parse_system(Iterator first, Iterator last, client::indicator_rec& rec) 
    { 
     system_parser<Iterator> parser; 
     bool r = qi::phrase_parse(first, last, parser, ascii::space, rec); 
     if (first != last) // fail if we did not get a full match 
      return false; 
     return r; 
    } 

    template <typename Iterator> 
    bool parse_universe(Iterator first, Iterator last, std::vector<std::string>& v) 
    { 
     bool r = qi::phrase_parse(first, last, 
           // Begin grammar ------------------------------------- 
           (
                 (+(qi::alpha|qi::char_("_"))) >> ':' >> '{' >> 
                  (+~qi::char_(",}")) % ',' 
                  >> '}' 
          ) 
           , 
           // End grammar --------------------------------------- 
           ascii::space, v); 

     if (first != last) // fail if we did not get a full match 
      return false; 
     return r; 
    } 
} 

main(int argc, char* argv[]) 
{ 
    std::string calculator("{ABC,HIJ}:{10,15,20}"); 
    client::indicator_rec rec; 
    client::parse_system(calculator.begin(), calculator.end(), rec); 
} 
+1

您应该在'parameter'规则中使用'unsigned()'。 – 2012-11-22 07:12:17

+0

@llonesmiz +1神圣烟!就是这样!如果你可以添加这个答案并解释为什么我需要一个'unsigned()',那么我会非常感激它(事实上,我不确定在这种情况下unsigned()是什么意思)。 tyvm。 – kfmfe04

回答

2

This question从昨天是差不多的。每个规则的签名都需要使用这个函数声明符语法。括号前面的类型是规则(它的合成属性)的“返回”属性,里面的类型是继承的属性(可以使用它们找到一个简单的例子here)。

因此,如果您不使用这些继承的属性,则必须在规则声明中使用rule_attribute_type()。理想情况下,不这样做会导致编译器错误,但显然由于rule's template parameters的异构性质,不幸的是它不会发生。

+0

Spirit开发人员一直在研究如何在更具体的错误消息中对概念/模板参数进行检查。 IIRC他们不能在没有引入重大变化的情况下做到这一点。 (在[spirit-general]列表中搜索关于使用无效的Skipper类型诊断错误的讨论)。也许Spirit V3将纳入他们同时开发的想法。 – sehe