Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从boost::spirit解析器检索AST_C++_Templates_Boost Spirit_Boost Spirit Qi - Fatal编程技术网

C++ 从boost::spirit解析器检索AST

C++ 从boost::spirit解析器检索AST,c++,templates,boost-spirit,boost-spirit-qi,C++,Templates,Boost Spirit,Boost Spirit Qi,在阅读了on之后,我非常喜欢它,因为它使用了解析器组合器语法。制作解析器非常简单 不幸的是,在从解析器中获取复杂数据结构的问题上,这些教程并不那么精确。我正试图到达终点 无论如何,这是我的AST代码: #ifndef __AST_HPP__ #define __AST_HPP__ #include <boost/fusion/include/adapt_struct.hpp> #include <boost/variant/recursive_variant.hpp>

在阅读了on之后,我非常喜欢它,因为它使用了解析器组合器语法。制作解析器非常简单

不幸的是,在从解析器中获取复杂数据结构的问题上,这些教程并不那么精确。我正试图到达终点

无论如何,这是我的AST代码:

#ifndef __AST_HPP__
#define __AST_HPP__

#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <string>
#include <vector>

namespace ast {

struct add;
struct sub;
struct mul;
struct div;
struct func_call;
template<typename OpTag> struct binary_op;

typedef boost::variant<double, std::string, boost::recursive_wrapper<binary_op<
        add>>, boost::recursive_wrapper<binary_op<sub>>,
        boost::recursive_wrapper<binary_op<mul>>, boost::recursive_wrapper<
                binary_op<div>>, boost::recursive_wrapper<func_call>>
        expression;

template<typename OpTag>
struct binary_op {
    expression left;
    expression right;

    binary_op(const expression & lhs, const expression & rhs) :
        left(lhs), right(rhs) {
    }
};

struct func_call {
    std::string callee;
    std::vector<expression> args;

    func_call(const std::string func, const std::vector<expression> &args) :
        callee(func), args(args) {
    }
};

struct prototype {
    std::string name;
    std::vector<std::string> args;

    prototype(const std::string &name, const std::vector<std::string> &args) :
        name(name), args(args) {
    }
};

struct function {
    prototype proto;
    expression body;

    function(const prototype &proto, const expression &body) :
        body(body), proto(proto) {
    }
};

}
    #endif
我遇到的问题是,它似乎与生成的
ast::expression
有关。编译后的模板抛出200多行复杂的模板错误。我怀疑这与我试图从
binop
规则中获取信息的方式有关,但我不确定


有人能帮忙吗?

您正试图使用Boost Phoenix占位符调用
ast::binary\u op
的构造函数。它们混不好。您需要对
ast::binary\u op
构造函数使用。这在Phoenix中通过使用
构造提供:

binop = (expr >> '+' >> expr) [_val = construct< ast::binary_op<ast::add> >(_1, _2)]
      | (expr >> '-' >> expr) [_val = construct< ast::binary_op<ast::sub> >(_1, _2)]
      | (expr >> '*' >> expr) [_val = construct< ast::binary_op<ast::mul> >(_1, _2)]
      | (expr >> '/' >> expr) [_val = construct< ast::binary_op<ast::div> >(_1, _2)] ;
提神气非常强大,但也很难调试。当我开始使用它时,我发现这些非常有用


我希望这会有帮助,因为我不是Boost Spirit的专家。

感谢
构造
确实消除了很多错误。现在我只剩下一个:
解析器。hpp:38:81:错误:“boost::spirit::_1”的值在常量表达式中不可用
注意:“boost::spirit:_1”未声明为“constexpr”
。有什么帮助吗?好吧,废话,我写下你的解决方案是个错误。谢谢Spirit应用程序链接列出了一些很棒的示例源,谢谢!
binop = (expr >> '+' >> expr) [_val = construct< ast::binary_op<ast::add> >(_1, _2)]
      | (expr >> '-' >> expr) [_val = construct< ast::binary_op<ast::sub> >(_1, _2)]
      | (expr >> '*' >> expr) [_val = construct< ast::binary_op<ast::mul> >(_1, _2)]
      | (expr >> '/' >> expr) [_val = construct< ast::binary_op<ast::div> >(_1, _2)] ;
qi::rule<Iterator, std::string(), ascii::space_type> varname;
//                            ^^          
qi::rule<Iterator, double(), ascii::space_type> number;
//                       ^^