我改编了 x3 文档(http://ciere.com/cppnow15/x3_docs/spirit/tutorials/reexpr.html)中的一个示例来解析一个简单的二进制前缀表示法语法,我发现我需要定义复制 con,复制 assign op 和使用 g++ 6.1.1 编译时的默认构造函数,尽管该示例声称您只需要base_type
使用using
. 然后我发现它可以使用 clang 3.8.1 按预期编译。我将发布代码的重要部分,这里是一个完整的 g++ 示例,带有显示错误的 AST 打印机。
我看到g ++似乎认为复制con被删除了,因为已经定义了移动构造函数或移动赋值运算符,但是为什么它用clang编译呢?哪个编译器是正确的?
#include <iostream>
#include <string>
#include <vector>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>
namespace x3 = boost::spirit::x3;
namespace chars = boost::spirit::x3::ascii;
namespace ast {
struct Expression;
struct Primary : x3::variant<
std::string,
x3::forward_ast<Expression>
> {
// GCC seems to require these three to be defined, but clang doesn't
// if I comment them out, then it compiles on clang but not gcc
Primary& operator=(const Primary&) = default;
Primary(const Primary&) = default;
Primary() = default;
// the documentation says that only these two are necessary
using base_type::base_type;
using base_type::operator=;
};
using ArgumentList = std::vector<Primary>;
struct Expression {
std::string func_name;
ArgumentList arguments;
Expression() : func_name(), arguments() { }
};
}
BOOST_FUSION_ADAPT_STRUCT(
ast::Expression,
func_name,
arguments
)
namespace parser {
x3::rule<class Primary, ast::Primary > Primary = "Primary";
x3::rule<class Expression, ast::Expression > Expression = "Expression";
const auto function_name = x3::lexeme[ +chars::alnum ];
const auto number = x3::lexeme[ +chars::digit ];
const auto Primary_def = number | Expression;
const auto Expression_def = function_name > x3::repeat(2)[ Primary ]; // only accept binary functions for now
BOOST_SPIRIT_DEFINE(Primary, Expression)
}
int main() {
while (std::cin.good() == true) {
const auto line = [&]() {
std::string str;
std::getline(std::cin, str);
return str;
}();
auto iter_in_line = begin(line);
const auto end_of_line = end(line);
ast::Expression root_expr;
const bool is_match = phrase_parse(iter_in_line, end_of_line,
parser::Expression,
chars::space,
root_expr
);
}
}