1

次の文法を使用して、テスト結果のログ ファイルを解析しようとしています。

template<typename Iterator>
struct test_step_parse: qi::grammar<Iterator, TestResults(), ascii::space_type> {
test_step_parse() : test_step_parse::base_type(rqmts) {
    using qi::lit;
    using qi::lexeme;
    using qi::omit;
    using qi::int_;
    using qi::eol;
    using qi::char_;

    test_step = lit("Test Step No.") >> int_;

    pass_or_fail = lit("-") >> (string("Passed") | string("Failed"));

    fdor_rqmts = -lit("OID")
                 >> lit("FDOR")
                 >> -lit("OID")
                 >> int_
                 >> *(-omit[char_(",/\\")] >> -(lit("FDOR") ^ lit("OID")) >> int_)
                 ;

    sard_rqmts = -lit("OID")
                 >> lit("SARD")
                 >> -lit("OID")
                 >> int_
                 >> *(-omit[char_(",/\\")] >> -(lit("SARD") ^ -lit("OID")) >> int_)
                         ;

    comment = lit("Comment:") >> lexeme[*(char_ - eol)] ;

    rqmts =  test_step
             >> pass_or_fail
             >> omit[*(char_ - lit("REQUIREMENT VERIFIED:"))]
             >> lit("REQUIREMENT VERIFIED:")
             >> (fdor_rqmts ^ sard_rqmts)
             >> omit[+char_("=")]
             >> -comment
             ;

    BOOST_SPIRIT_DEBUG_NODE(test_step);
    BOOST_SPIRIT_DEBUG_NODE(pass_or_fail);
    BOOST_SPIRIT_DEBUG_NODE(fdor_rqmts);
    BOOST_SPIRIT_DEBUG_NODE(sard_rqmts);
    BOOST_SPIRIT_DEBUG_NODE(comment);
    BOOST_SPIRIT_DEBUG_NODE(rqmts);
}

qi::rule<Iterator, TestResults(),  ascii::space_type> rqmts;
qi::rule<Iterator, int(), ascii::space_type> test_step;
qi::rule<Iterator, std::string(), ascii::space_type> pass_or_fail;
qi::rule<Iterator, std::string(), ascii::space_type> comment;
qi::rule<Iterator, std::vector<int>(),  ascii::space_type> fdor_rqmts;
qi::rule<Iterator, std::vector<int>(),  ascii::space_type> sard_rqmts;

};

グラマーは問題なく解析します。ただし、ユーザー定義の構造体を自動入力しようとすると、std::string 型のルール「コメント」の属性が ASCII 数字としてベクターに渡されます。

これは私のユーザー定義の構造体です:

struct TestResults {
    int test_step_no;
    std::string pass_or_fail;
    std::vector<int> FDOR;
    std::vector<int> SARD;
    std::string comment;
}; 

BOOST_FUSION_ADAPT_STRUCT(
    atp::TestResults,
    (int, test_step_no)
    (std::string, pass_or_fail)
    (std::vector<int>, FDOR)
    (std::vector<int>, SARD)
    (std::string, comment)
)

デバッグ出力は、ルールが正しい型を公開していることを示していますが、どういうわけか構造体に正しく配置されていません。

私が間違っていることは何ですか?用語等の誤用はご容赦ください。

gcc 4.6.3 とブースト 1-47 を使用。ありがとうございました。

更新:明確にするために、次を解析することを期待しています:

std::string test_test =
"Test Step No. 953-Failed\n"
"==============================================================================\n"
"STEP 7.7:\n"
"Test step, etc.\n"
"===============================================================================\n"
"REQUIREMENT VERIFIED: FDOR 12345"
"                      SARD 12345, 12356\n"
"===============================================================================\n"
"Comment: Didn't work.\n"
;

デバッガーを使用すると、すべてのルールが属性を正しく公開しているように見えます。

<rqmts>
  <try>Test Step No. 953-Fa</try>
  <test_step>
    <try>Test Step No. 953-Fa</try>
    <success>-Failed\n============</success>
    <attributes>[953]</attributes>
   </test_step>
   <pass_or_fail>
    <try>-Failed\n============</try>
    <success>\n===================</success>
      <attributes>[[F, a, i, l, e, d]]</attributes>
      </pass_or_fail>
     <fdor_rqmts>
     <try> FDOR 12345         </try>
         <success>                    </success>
         <attributes>[[12345]]</attributes>
    </fdor_rqmts>
    <sard_rqmts>
        <try>                    </try>
        <success>\n===================</success>
        <attributes>[[12345, 12356]]</attributes>
   </sard_rqmts>
   <comment>
       <try>Comment: Didn't work</try>
       <success>\n</success>
       <attributes>[[D, i, d, n, ', t,  , w, o, r, k, .]]</attributes>
  </comment>
  <success>\n</success>
       <attributes>[[953, [F, a, i, l, e, d], [12345], [68, 105, 100, 110, 39, 116, 32, 119, 111, 114, 107, 46], []]]</attributes>
 </rqmts>

したがって、「コメント」属性(std::string)がASCII数字のベクトルとして「SARD」属性(ベクター)に詰め込まれていることを除いて、すべてが機能しているようです。つまり、

[68, 105, 100, 110, 39, 116, 32, 119, 111, 114, 107, 46] = "Didn't work."
4

1 に答える 1

2

問題は、パーサー(A ^ B)が A タイプと B タイプのタプルであるタイプを返すことです。つまり、あなたの場合(fdor_rqmts ^ sard_rqmts)は type を返しますboost::tuple<std::vector<int>, std::vector<int> >

パーサーの結合方法の詳細については、Boost のドキュメントを参照してください。

structしたがって、パーサーが返す型に合わせて変更する選択肢があります(これは、属性文法の唯一の選択肢です)。

struct TestResults {
    int test_step_no;
    std::string pass_or_fail;
    boost::tuple<std::vector<int>, std::vector<int> > FdorOrSard;
    std::string comment;
}; 

またはアクションを指定します。次に、文法は次のようになります。

struct TestResults {
    int test_step_no;
    std::string pass_or_fail;
    std::vector<int> FDOR;
    std::vector<int> SARD;
    std::string comment;
}; 

test_step [ at<0>(_val) = _1]
>> pass_or_fail [ at<1>(_val) = _1 ] 
>> omit[*(char_ - lit("REQUIREMENT VERIFIED:"))]
>> lit("REQUIREMENT VERIFIED:")
>> (fdor_rqmts [at<2>(_val) = _1 ] ^ sard_rqmts [at<3>(_val) = _1] )
>> omit[+char_("=")]
>> -comment [at<4>(_val) = _1];

アクションは、適応された構造体を持つことに依然依存していますが、解析された結果を配置する方法を明示的に記述するようになりました。の結果に対して何もしていないことに注意してください。代わりに、結果または結果(A ^ B)に対して何かを行っています。AB

補足として、私はミキシングの問題に遭遇し、結果を面白い方法で入れ子にすることを決定しました>.属性ベースの文法を機能させることができません。この質問には、この種のことに関する詳細情報があります: boost::spirit::qi Expectation Parser and parser grouping unexpected behavior>>spirit

編集:アクションがどのように機能するか、必要な include ステートメントと using ステートメントを知っていると仮定しています。これには、最初の 2 つのスピリット パーサー チュートリアルが適しています。それ以外の場合は、質問があればコメントしてください。at_c代わりに使用する必要があるかもしれませんat-ブーストフェニックス/関数の詳細を理解することは本当にできません...

于 2012-05-14T02:55:54.437 に答える