2012-10-19 43 views
2

我写了这个代码示例,并期望它打印OPERATION(OPERATOR(aaa) ID(bbb)),但我只获得OPERATION (OPERATOR(aaa))result2it1 == it2都是如此。为什么操作数不被解析?Boost :: spirit序列没有得到解析

#include "stdafx.h" 

#include <boost/serialization/strong_typedef.hpp> 
#include <boost/bind.hpp> 
#include <boost/tuple/tuple.hpp> 
#include <boost/spirit/include/phoenix.hpp> 
#include <boost/spirit/include/phoenix1.hpp> 
#include <boost/spirit/include/phoenix_core.hpp> 
#include <boost/spirit/include/phoenix_operator.hpp> 
#include <boost/spirit/include/phoenix_object.hpp> 
#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/support.hpp> 
#include <boost/fusion/include/adapt_struct.hpp> 
#include <boost/variant/recursive_variant.hpp> 
#include <iostream> 
#include <string> 

namespace NsSemSDK 
{ 

struct STreeConstructionRuleRegexp { 
    std::string m_strEntity; 
}; 

struct STreeConstructionRuleString { 
    std::string m_strEntity; 
}; 

struct STreeConstructionRuleIdentifier { 
    std::string m_strEntity; 
}; 

typedef int STreeConstructionRuleNumber; 

typedef std::string STreeConstructionRuleOperation; 
typedef boost::variant<STreeConstructionRuleRegexp, STreeConstructionRuleNumber, STreeConstructionRuleString, STreeConstructionRuleIdentifier> STreeConstructionRuleOperand; 
typedef boost::tuple<STreeConstructionRuleOperation, std::vector<STreeConstructionRuleOperand> > STreeConstructionRuleOperationWithOperands; 


std::ostream& operator<<(std::ostream& stream, const NsSemSDK::STreeConstructionRuleIdentifier& val); 
std::ostream& operator<<(std::ostream& stream, const NsSemSDK::STreeConstructionRuleString& val); 
std::ostream& operator<<(std::ostream& stream, const NsSemSDK::STreeConstructionRuleRegexp& val); 
std::ostream& operator<<(std::ostream& stream, const NsSemSDK::STreeConstructionRuleOperationWithOperands& val); 


std::ostream& operator<<(std::ostream& stream, const NsSemSDK::STreeConstructionRuleOperationWithOperands& val) 
{ 
    stream << "OPERATION(" << "OPERATOR(" << val.get<0>() << ")"; 
    for (int i = 0; i < val.get<1>().size(); i++) 
    { 
     stream << " " << val.get<1>()[i]; 
    } 
    stream << ")"; 
    return stream; 
} 

std::ostream& operator<<(std::ostream& stream, const NsSemSDK::STreeConstructionRuleRegexp& val) 
{ 
    return stream << "REGEXP(" << val.m_strEntity << ")"; 
} 

std::ostream& operator<<(std::ostream& stream, const NsSemSDK::STreeConstructionRuleString& val) 
{ 
    return stream << "STR(" << val.m_strEntity << ")"; 
} 

std::ostream& operator<<(std::ostream& stream, const NsSemSDK::STreeConstructionRuleIdentifier& val) 
{ 
    return stream << "ID(" << val.m_strEntity << ")"; 
} 

} 

BOOST_FUSION_ADAPT_STRUCT(
    NsSemSDK::STreeConstructionRuleRegexp, 
    (std::string, m_strEntity) 
) 

BOOST_FUSION_ADAPT_STRUCT(
    NsSemSDK::STreeConstructionRuleString, 
    (std::string, m_strEntity) 
) 

BOOST_FUSION_ADAPT_STRUCT(
    NsSemSDK::STreeConstructionRuleIdentifier, 
    (std::string, m_strEntity) 
) 

namespace NsSemSDK{ 

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


template <typename Iterator, typename Skipper> 
struct STreeContructionRulesGrammar : qi::grammar<Iterator, STreeConstructionRuleOperationWithOperands(), Skipper> // std::vector<STreeConstructionRule>() 
{ 
    qi::rule<Iterator, STreeConstructionRuleOperationWithOperands(), Skipper> m_oOperationWithOperands; 
    qi::rule<Iterator, STreeConstructionRuleOperation(), Skipper> m_oOperation; 
    qi::rule<Iterator, std::vector<STreeConstructionRuleOperand>(), Skipper> m_oOperandsList; 
    qi::rule<Iterator, STreeConstructionRuleOperand(), Skipper> m_oOperand; 
    qi::rule<Iterator, STreeConstructionRuleString(), Skipper> m_oString; 
    qi::rule<Iterator, STreeConstructionRuleRegexp(), Skipper> m_oRegexp; 
    qi::rule<Iterator, STreeConstructionRuleNumber(), Skipper> m_oNumber; 
    qi::rule<Iterator, STreeConstructionRuleIdentifier(), Skipper> m_oIdentifier; 

    STreeContructionRulesGrammar() : STreeContructionRulesGrammar::base_type(m_oOperationWithOperands) 
    { 
     m_oOperationWithOperands %= m_oOperation > m_oOperandsList; 
     m_oOperation %= qi::lexeme[+(qi::alnum)]; 
     m_oOperandsList %= qi::lit("[") >> (m_oOperand % ',') >> qi::lit("]"); 
     m_oOperand %= m_oString | m_oRegexp | m_oNumber | m_oIdentifier; 

     m_oString %= qi::lit("\"") >> qi::lexeme[*(qi::char_ - '"')] >> qi::lit("\""); 
     m_oRegexp %= qi::lit("'") >> qi::lexeme[*(qi::char_ - '\'')] >> qi::lit("'"); 
     m_oNumber %= qi::int_; 
     m_oIdentifier %= +(qi::alpha) >> qi::eps; 
    } 

}; 

} 
using namespace NsSemSDK; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    std::string str("aaa [bbb]"); 
    STreeContructionRulesGrammar<std::string::iterator, boost::spirit::ascii::space_type> grammar; 
    STreeConstructionRuleOperationWithOperands result; 
    std::string::iterator it1 = str.begin(), it2 = str.end(); 
    bool result2 = qi::phrase_parse(it1, it2, grammar, boost::spirit::ascii::space, result); 
    std::cout << result << std::endl; 
    return 0; 
} 
+1

为什么downvote?这是一个完美的问题,有一个很好的SSCCE。为什么这是一个合理的问题,请参阅我的答案以获取更多理由 – sehe

回答

5

我用BOOST_SPIRIT_DEBUG这样

正如你所看到的,解析调试跟踪显示bbb被匹配为标识符:

<m_oOperationWithOperands> 
    <try>aaa [bbb]</try> 
    <m_oOperation> 
    <try>aaa [bbb]</try> 
    <success> [bbb]</success> 
    <attributes>[[a, a, a]]</attributes> 
    </m_oOperation> 
    <m_oOperandsList> 
    <try> [bbb]</try> 
    <m_oOperand> 
     <try>bbb]</try> 
     <m_oString> 
     <try>bbb]</try> 
     <fail/> 
     </m_oString> 
     <m_oRegexp> 
     <try>bbb]</try> 
     <fail/> 
     </m_oRegexp> 
     <m_oNumber> 
     <try>bbb]</try> 
     <fail/> 
     </m_oNumber> 
     <m_oIdentifier> 
     <try>bbb]</try> 
     <success>]</success> 
     <attributes>[[[b, b, b]]]</attributes> 
     </m_oIdentifier> 
     <success>]</success> 
     <attributes>[[[b, b, b]]]</attributes> 
    </m_oOperand> 
    <success></success> 
    <attributes>[[[[b, b, b]]]]</attributes> 
    </m_oOperandsList> 
    <success></success> 
    <attributes>[OPERATION(OPERATOR(aaa))]</attributes> 
</m_oOperationWithOperands> 

到目前为止,这么好。所以问题是为什么结果没有被分配到规则m_oOperationWithOperands中的元组元素。在这里,恐怕我不能告诉你你应该做什么。

我用我的经验,并检查融合适应是否适用于tuple s。心血来潮,我改变

#include <boost/fusion/include/adapt_struct.hpp> 

而现在的输出是:

OPERATION(OPERATOR(aaa) ID(bbb)) 

见活在http://liveworkspace.org/code/c0da90349fbcae6655ab3e6a45f1ef69

附::我很想说这是Qi中的一个错误,没有诊断存在,说明暴露的属性不完整复制到属性参考。你可能想要发布在https://lists.sourceforge.net/lists/listinfo/spirit-general

相关问题