【发布时间】:2015-02-09 02:59:17
【问题描述】:
对于我实际实现的解析器,我在解析器中部分拥有这些私有函数:
解析器私有方法:
Token const* current_token() const;
Token const* next_token();
Token const* peek_token();
std::unique_ptr<ast::Expression> parse_expression();
std::unique_ptr<ast::TypeSpecifier> parse_type_specifier();
std::unique_ptr<ast::VariableDeclarationStatement> parse_variable_declaration();
std::unique_ptr<ast::Statement> parse_function_definition();
std::unique_ptr<ast::Statement> parse_top_level_statement();
parse_variable_declaration 方法的实现是这样的:
parse_variable_declaration():
std::unique_ptr<ast::VariableDeclarationStatement> Parser::parse_variable_declaration() {
next_token(); // consume 'var'
if (current_token()->get_type() != TokenTypes::identifier) {
throw parser_error(current_token(), "", "expected identifier\n");
}
const auto id = current_token(); // store identifier
next_token(); // consume identifier
std::unique_ptr<ast::TypeSpecifier> type;
std::unique_ptr<ast::Expression> expr;
auto assignment_required = true;
if (current_token()->get_type() == TokenTypes::op_colon) { // optional type specifier
next_token(); // consume ':'
type = parse_type_specifier();
assignment_required = false;
}
if (assignment_required && current_token()->get_type() != TokenTypes::op_equals) {
throw parser_error(current_token(), "", "expected equals operator\n");
}
if (current_token()->get_type() == TokenTypes::op_equals) {
next_token(); // consume '='
expr = parse_expression();
}
if (current_token()->get_type() != TokenTypes::op_semi_colon) {
throw parser_error(current_token(), "", "expected semi-colon\n");
}
next_token(); // consume ';'
DEBUG_STDERR("parsed: variable_declaration_statement\n");
return std::make_unique<ast::VariableDeclarationStatement>(
id->get_string(), std::move(type), std::move(expr));
}
最后一行(返回)以分段错误结束。 它基本上调用了VariableDeclarationStatement的构造函数:
VariableDeclarationStatement ctor:
VariableDeclarationStatement::VariableDeclarationStatement(
std::string const& name,
std::unique_ptr<TypeSpecifier> type_specifier,
std::unique_ptr<Expression> expr
):
m_name{name},
m_type_specifier{std::move(type_specifier)},
m_expr{std::move(expr)}
{}
我从昨天开始就在调试这些东西,但似乎无法找出为什么它不能按预期工作。我想用指向其子节点的唯一指针构建抽象语法树(解析器输出)(因为它们是其子节点的唯一所有者,这是有意义的)——这就是我努力与它们合作的原因。
控制台输出:DEBUG_STDERR
parsed: primitive_type_int // from parse_type_specifier()
parsed: integral_expression // from parse_expression()
parsed: variable_declaration_statement
[1] 12638 segmentation fault (core dumped) ./cion_compiler
【问题讨论】:
-
你不能在调试器下运行吗?如果你这样做,应该很容易追踪发生了什么。以及你如何使用
Parser::parse_variable_declaration()的返回值可能也很重要。 -
为什么ctor参数不是
std::unique_ptr<TypeSpecifier> &&type_specifier? -
我想知道您是否可以创建一个small, complete program 来重现您有问题的
return声明。否则,您只是希望问题的根源恰好在您选择向我们展示的代码中。 -
@Slava 为什么会这样?它是一个 sink 参数,当前的签名清楚地表明构造函数无条件地接管了参数。
-
@Praetorian 我认为当参数是右值引用时,很明显构造函数会移动参数,不是吗?
标签: c++ segmentation-fault smart-pointers move-semantics unique-ptr