Boost::spirit 序列未得到解析

标签 boost boost-spirit

我编写了这个代码示例,并期望它打印 OPERATION( OPERATOR(aaa) ID(bbb) ) 但我只得到 OPERATION ( OPERATOR(aaa) )反而。 result2it1 == it2 都是 true。为什么操作数不被解析?

#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;
}

最佳答案

我像这样使用了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 中的元组元素中。在这里,恐怕我无法告诉你你应该做什么。

我利用自己的经验检查了正确的 fusion 适应是否对元组有效。一时兴起我就改变了

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

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

现在的输出是:

OPERATION( OPERATOR(aaa) ID(bbb) )

观看直播 http://liveworkspace.org/code/c0da90349fbcae6655ab3e6a45f1ef69

P.S.: I'd be tempted to say it is a bug in Qi that no diagnostic exists saying that the exposed attributes are being incompletely copied to the attribute reference. You may want to post this at https://lists.sourceforge.net/lists/listinfo/spirit-general

关于Boost::spirit 序列未得到解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12974941/

相关文章:

c++ - 我无法在 Boost Spirit 的词法分析器功能中获得语义操作来编译

c++ - 在使用单独的规则定义和实例化时,Boost Spirit X3 AST 无法处理语义操作

c++ - Boost Spirit Lexeme与No_skip

c++ - boost "no such file or directory"

c++ - 用于 64 位 Windows 的 64 位版本的 Boost

boost - 如何将动态任务设置为defaultTask

c++ - 升压精神X3 : “Attribute does not have the expected size” redux

c++ - 返回一个 unique_ptr<T> 。概念澄清

c++ - 如何将 'CDT' 转换为 time_zone_ptr

c++ - 灵气用词法分析器寻找n个字符