我编写了这段代码并期望它打印OPERATION( OPERATOR(aaa) ID(bbb) )
,但我只得到OPERATION ( OPERATOR(aaa) )
。 result2
和it1 == it2
都是正确的。为什么操作数不被解析?
#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;
}
答案 0 :(得分: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
中的元组元素中。在这里,我恐怕无法告诉你应该做些什么。
我根据自己的经验检查了{em>融合适应是否适用于tuple
s。我一时兴起改变了
#include <boost/fusion/include/adapt_struct.hpp>
到
#include <boost/fusion/include/adapted.hpp>
现在的输出是:
OPERATION( OPERATOR(aaa) ID(bbb) )
直播http://liveworkspace.org/code/c0da90349fbcae6655ab3e6a45f1ef69
PS :我很想说这是Qi中的一个错误,没有诊断存在说暴露的属性不完全复制到属性引用。您可以在https://lists.sourceforge.net/lists/listinfo/spirit-general
发布此信息