【问题标题】:Boost Spirit inherited string attribute populating vector<int> in ascii charactersBoost Spirit 继承的字符串属性以 ascii 字符填充 vector<int>
【发布时间】:2012-05-13 21:19:11
【问题描述】:

我正在尝试使用以下语法解析测试结果的日志文件。

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 类型的规则“comment”的属性被作为 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 和 boost 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>

所以除了“cmets”属性(std::string)被填充在“SARD”属性(vector)中之外,一切似乎都正常工作,作为ascii数字的向量,即

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

【问题讨论】:

  • 你能举例说明你在字符串中得到了什么以及你期望什么?
  • 上面提供的说明。

标签: c++ boost-spirit


【解决方案1】:

问题是解析器(A ^ B)返回一个类型是A类型和B类型的元组,即在你的情况下(fdor_rqmts ^ sard_rqmts)返回一个类型boost::tuple&lt;std::vector&lt;int&gt;, std::vector&lt;int&gt; &gt;

解析器如何组合的详细信息可以在Boost documentation中找到。

因此,您可以选择修改 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) 的结果做任何事情,而是对A 结果或B 结果做一些事情。

作为旁注,我在混合 &gt;&gt;&gt; 时遇到了问题,其中 spirit 决定以有趣的方式嵌套结果 - 我个人发现几乎不可能在事后确定结构是什么返回,所以当我无法让基于属性的语法工作时,我倾向于坚持使用动作。在这个问题中有更多关于这类事情的信息:boost::spirit::qi Expectation Parser and parser grouping unexpected behaviour

编辑:我假设您知道操作是如何工作的,以及您需要的包含和使用语句。前几个精神解析器教程对此很有用,否则有任何问题都可以评论!您可能还必须使用at_c 而不是at - 我真的永远无法弄清楚boost phoenix / function 的细节......

【讨论】:

  • 谢谢!现在这很有意义......我对此很陌生。我无法让元组正常工作(即使我这样做了,是否可以保证始终填充正确的元素?),但我会尝试语义操作。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-11
  • 1970-01-01
相关资源
最近更新 更多