1

"{ABC,HIJ}:{10,15,20}"この文字列を解析してにキャプチャしようとしていますstruct indicator_rec

解析は成功しますが、最初のセットのみがフィールド{ABC,HIJ}にキャプチャされstd::vector<std::string>ます。

2番目の部分{10,15,20}は正しく解析されますが、2番目のフィールドに入れることができません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 );
}
4

1 に答える 1

2

この昨日の質問はほぼ同じです。すべてのルールの署名は、この関数宣言構文を使用する必要があります。括弧の前の型はルールから「返された」属性 (合成された属性) であり、内側の型は継承された属性です (それらを使用した簡単な例はこちらで確認できます)。

したがって、これらの継承された属性を使用していない場合rule_attribute_type()は、ルール宣言で使用する必要があります。理想的には、そうしないとコンパイラ エラーが発生しますが、ルールのテンプレート パラメーターの異質な性質が原因で、残念ながらそうはなりません。

于 2012-11-22T07:33:23.430 に答える