C++ boost::spirit算术公式分析器无法编译

C++ boost::spirit算术公式分析器无法编译,c++,boost-spirit-qi,boost-variant,boost-fusion,C++,Boost Spirit Qi,Boost Variant,Boost Fusion,我正在尝试为算术表达式编写一个spirit解析器,它填充一个抽象语法树。如果我没有尝试填充AST,但在当前版本中失败(有一个24K错误),解析器将编译。我使用的是带-std=c++11的clang++3.5.0,运行在Ubuntu 14.4上 #include <string> #include <vector> #include <utility> #include <boost/spirit/include/qi.hpp> #include

我正在尝试为算术表达式编写一个spirit解析器,它填充一个抽象语法树。如果我没有尝试填充AST,但在当前版本中失败(有一个24K错误),解析器将编译。我使用的是带-std=c++11的clang++3.5.0,运行在Ubuntu 14.4上

#include <string>
#include <vector>
#include <utility>

#include <boost/spirit/include/qi.hpp>

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

#include <boost/variant/variant.hpp>
#include <boost/variant/recursive_wrapper.hpp>

using std::string;
using std::vector;
using std::pair;

using boost::spirit::qi::grammar;
using boost::spirit::qi::space_type;
using boost::spirit::qi::rule;

struct Term; // forward dec
typedef boost::recursive_wrapper<Term> RWTerm;
typedef pair<char, RWTerm> OpAndRWTerm;
typedef pair<RWTerm, vector<OpAndRWTerm> > Expr;
typedef boost::variant<Expr, double> Factor;
typedef pair<char, Factor> OpAndFactor;
struct Term : public pair<Factor, vector<OpAndFactor> >{};

template<typename It>
struct formula_parser : grammar<It, Expr(), space_type> {
  formula_parser() : formula_parser::base_type(expr_rule) {
    using boost::spirit::qi::double_;
    using boost::spirit::ascii::char_;

    factor_rule %= double_ | parenthesis_rule;
    parenthesis_rule %= '(' >> expr_rule >> ')';
    op_and_factor_rule %= char_("/*") >> factor_rule;
    term_rule %= factor_rule >> *op_and_factor_rule;
    op_and_term_rule %= char_("+-") >> term_rule;
    expr_rule %= term_rule >> *op_and_term_rule;
  }
  rule<It, OpAndRWTerm(), space_type> op_and_term_rule;
  rule<It, Expr(), space_type> expr_rule;
  rule<It, OpAndFactor(), space_type> op_and_factor_rule;
  rule<It, RWTerm(), space_type> term_rule;
  rule<It, Expr(), space_type> parenthesis_rule;
  rule<It, Factor(), space_type> factor_rule;
};

int main() {
  formula_parser<string::const_iterator> grammar;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用std::string;
使用std::vector;
使用std::pair;
使用boost::spirit::qi::语法;
使用boost::spirit::qi::space\u type;
使用boost::spirit::qi::rule;
结构术语;//远期十二月
typedef boost::递归_包装器术语;
typedef对OpAndRWTerm;
typedef对Expr;
变量因子;
类型定义对运算因子;
结构项:公共对{};
模板
结构公式解析器:语法{
公式解析器():公式解析器::基本类型(expr\u规则){
使用boost::spirit::qi::double;
使用boost::spirit::ascii::char;
因子_规则%=双|括号_规则;
括号“\u rule%=”(“>>expr\u rule>>”);
op_和_factor_rule%=字符(“/*”>>factor_rule;
术语规则%=系数规则>>*操作规则和系数规则;
op_和_term_rule%=字符(“+-”>>term_rule;
expr\u rule%=术语规则>>*操作和术语规则;
}
规则op_和_项_规则;
规则解释规则;
规则op_和_因子_规则;
规则术语\规则;
规则括号\规则;
规则因子\规则;
};
int main(){
公式语法;
}
我从错误消息中了解到,fusion将规则项_规则中的类型因子和RWTerm混合在一起


我做错了什么?

如果我改变两件事,它会为我编译:

  • 由于
    Term
    继承自
    std::pair
    Term
    是一种新的类型。因此,您需要将
    BOOST\u FUSION\u ADAPT\u STRUCT
    应用于
    Term
    ,而不管是否已对
    中的
    std::pair
    执行此操作:

    顺便说一下:您必须在这里完全限定
    std::vector
    ,因为:

  • 完整代码:

    #include <string>
    #include <vector>
    #include <utility>
    
    #include <boost/spirit/include/qi.hpp>
    
    #include <boost/fusion/include/adapt_struct.hpp>
    #include <boost/fusion/adapted.hpp>
    #include <boost/fusion/include/adapted.hpp>
    
    #include <boost/variant/variant.hpp>
    #include <boost/variant/recursive_wrapper.hpp>
    
    using boost::spirit::qi::grammar;
    using boost::spirit::qi::space_type;
    using boost::spirit::qi::rule;
    
    struct Term; // forward dec
    typedef boost::recursive_wrapper<Term> RWTerm;
    typedef std::pair<char, RWTerm> OpAndRWTerm;
    typedef std::pair<RWTerm, std::vector<OpAndRWTerm> > Expr;
    typedef boost::variant<Expr, double> Factor;
    typedef std::pair<char, Factor> OpAndFactor;
    struct Term : public std::pair<Factor, std::vector<OpAndFactor> >{};
    
    BOOST_FUSION_ADAPT_STRUCT(
        Term,
        (Factor, first)
        (std::vector<OpAndFactor>, second)
    )
    
    
    template<typename It>
    struct formula_parser : grammar<It, Expr(), space_type> {
      formula_parser() : formula_parser::base_type(expr_rule) {
        using boost::spirit::qi::double_;
        using boost::spirit::ascii::char_;
    
        factor_rule %= double_ | parenthesis_rule;
        parenthesis_rule %= '(' >> expr_rule >> ')';
        op_and_factor_rule %= char_("/*") >> factor_rule;
        term_rule %= factor_rule >> *op_and_factor_rule;
        op_and_term_rule %= char_("+-") >> term_rule;
        expr_rule %= term_rule >> *op_and_term_rule;
      }
      rule<It, OpAndRWTerm(), space_type> op_and_term_rule;
      rule<It, Expr(), space_type> expr_rule;
      rule<It, OpAndFactor(), space_type> op_and_factor_rule;
      rule<It, Term(), space_type> term_rule;
      rule<It, Expr(), space_type> parenthesis_rule;
      rule<It, Factor(), space_type> factor_rule;
    };
    
    int main() {
      formula_parser<std::string::const_iterator> grammar;
    }
    
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    使用boost::spirit::qi::语法;
    使用boost::spirit::qi::space\u type;
    使用boost::spirit::qi::rule;
    结构术语;//远期十二月
    typedef boost::递归_包装器术语;
    typedef std::pair OpAndRWTerm;
    typedef std::pair Expr;
    变量因子;
    typedef std::pair OpAndFactor;
    结构术语:公共std::pair{};
    增强融合适应结构(
    学期
    (第一因素)
    (标准::向量,秒)
    )
    模板
    结构公式解析器:语法{
    公式解析器():公式解析器::基本类型(expr\u规则){
    使用boost::spirit::qi::double;
    使用boost::spirit::ascii::char;
    因子_规则%=双|括号_规则;
    括号“\u rule%=”(“>>expr\u rule>>”);
    op_和_factor_rule%=字符(“/*”>>factor_rule;
    术语规则%=系数规则>>*操作规则和系数规则;
    op_和_term_rule%=字符(“+-”>>term_rule;
    expr\u rule%=术语规则>>*操作和术语规则;
    }
    规则op_和_项_规则;
    规则解释规则;
    规则op_和_因子_规则;
    规则术语\规则;
    规则括号\规则;
    规则因子\规则;
    };
    int main(){
    公式语法;
    }
    

    谢谢-它很有效!使用pair继承有什么问题?@davidelhavi我用解释更新了答案感谢详细信息(只有在将您的代码与我以前的尝试进行比较后,我才意识到必须完全限定向量)最近的boost还可以
    boost\u FUSION\u ADAPT\u STRUCT(术语,第一,第二)
    :@sehe我在:推导成员类型(#9516)的新自适应结构、自适应ADT、自适应ASSOC
    struct Term { Factor f; std::vector<OpAndFactor>  o;};
    
    BOOST_FUSION_ADAPT_STRUCT(
        Term,
        (Factor, f)
        (std::vector<OpAndFactor>, o)
    )
    
    using std::vector;
    BOOST_FUSION_ADAPT_STRUCT(
        Term,
        (Factor, f)
        (vector<OpAndFactor>, o)
    )
    
    rule<It, Term(), space_type> term_rule;
    
    #include <string>
    #include <vector>
    #include <utility>
    
    #include <boost/spirit/include/qi.hpp>
    
    #include <boost/fusion/include/adapt_struct.hpp>
    #include <boost/fusion/adapted.hpp>
    #include <boost/fusion/include/adapted.hpp>
    
    #include <boost/variant/variant.hpp>
    #include <boost/variant/recursive_wrapper.hpp>
    
    using boost::spirit::qi::grammar;
    using boost::spirit::qi::space_type;
    using boost::spirit::qi::rule;
    
    struct Term; // forward dec
    typedef boost::recursive_wrapper<Term> RWTerm;
    typedef std::pair<char, RWTerm> OpAndRWTerm;
    typedef std::pair<RWTerm, std::vector<OpAndRWTerm> > Expr;
    typedef boost::variant<Expr, double> Factor;
    typedef std::pair<char, Factor> OpAndFactor;
    struct Term : public std::pair<Factor, std::vector<OpAndFactor> >{};
    
    BOOST_FUSION_ADAPT_STRUCT(
        Term,
        (Factor, first)
        (std::vector<OpAndFactor>, second)
    )
    
    
    template<typename It>
    struct formula_parser : grammar<It, Expr(), space_type> {
      formula_parser() : formula_parser::base_type(expr_rule) {
        using boost::spirit::qi::double_;
        using boost::spirit::ascii::char_;
    
        factor_rule %= double_ | parenthesis_rule;
        parenthesis_rule %= '(' >> expr_rule >> ')';
        op_and_factor_rule %= char_("/*") >> factor_rule;
        term_rule %= factor_rule >> *op_and_factor_rule;
        op_and_term_rule %= char_("+-") >> term_rule;
        expr_rule %= term_rule >> *op_and_term_rule;
      }
      rule<It, OpAndRWTerm(), space_type> op_and_term_rule;
      rule<It, Expr(), space_type> expr_rule;
      rule<It, OpAndFactor(), space_type> op_and_factor_rule;
      rule<It, Term(), space_type> term_rule;
      rule<It, Expr(), space_type> parenthesis_rule;
      rule<It, Factor(), space_type> factor_rule;
    };
    
    int main() {
      formula_parser<std::string::const_iterator> grammar;
    }