Provide a BisonWrap for default construction (#761)

Co-authored-by: Geoff Romer <gromer@google.com>
This commit is contained in:
Jon Meow
2021-08-19 12:31:25 -07:00
committed by GitHub
co-authored by Geoff Romer
parent 367f9e4e94
commit 0619b4ce6a
3 changed files with 55 additions and 6 deletions
+7
View File
@@ -6,6 +6,12 @@ load("@rules_cc//cc:defs.bzl", "cc_library")
package(default_visibility = ["//executable_semantics:__pkg__"])
cc_library(
name = "bison_wrap",
hdrs = ["bison_wrap.h"],
deps = ["//common:check"],
)
cc_library(
name = "syntax",
srcs = [
@@ -28,6 +34,7 @@ cc_library(
"-Wno-writable-strings",
],
deps = [
":bison_wrap",
"//common:check",
"//common:ostream",
"//common:string_helpers",
+41
View File
@@ -0,0 +1,41 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#ifndef EXECUTABLE_SEMANTICS_SYNTAX_BISON_WRAP_H_
#define EXECUTABLE_SEMANTICS_SYNTAX_BISON_WRAP_H_
#include <optional>
#include "common/check.h"
namespace Carbon {
// Bison requires that types be default initializable for use with its variant
// semantics. This wraps arbitrary types to support a default constructor, while
// still requiring they be properly initialized.
template <typename T>
class BisonWrap {
public:
// Assigning a value initializes the wrapper.
BisonWrap& operator=(T&& rhs) {
val = std::move(rhs);
return *this;
}
// Support transparent conversion to the wrapped type, erroring if not
// initialized.
operator T() {
CHECK(val.has_value());
T ret = std::move(*val);
val.reset();
return ret;
}
private:
std::optional<T> val;
};
} // namespace Carbon
#endif // EXECUTABLE_SEMANTICS_SYNTAX_BISON_WRAP_H_
+7 -6
View File
@@ -71,6 +71,7 @@
#include "executable_semantics/common/arena.h"
#include "executable_semantics/common/ptr.h"
#include "executable_semantics/ast/paren_contents.h"
#include "executable_semantics/syntax/bison_wrap.h"
namespace Carbon {
class ParseAndLexContext;
@@ -93,7 +94,7 @@ void Carbon::Parser::error(const location_type&, const std::string& message) {
%token <std::string> sized_type_literal
%token <std::string> string_literal
%type <std::string> designator
%type <const Declaration*> declaration
%type <BisonWrap<Ptr<const Declaration>>> declaration
%type <const FunctionDefinition*> function_declaration
%type <const FunctionDefinition*> function_definition
%type <std::list<Ptr<const Declaration>>> declaration_list
@@ -567,20 +568,20 @@ alternative_list:
;
declaration:
function_definition
{ $$ = global_arena->RawNew<FunctionDeclaration>($1); }
{ $$ = global_arena->New<FunctionDeclaration>($1); }
| function_declaration
{ $$ = global_arena->RawNew<FunctionDeclaration>($1); }
{ $$ = global_arena->New<FunctionDeclaration>($1); }
| CLASS identifier "{" member_list "}"
{
$$ = global_arena->RawNew<ClassDeclaration>(yylineno, $2, $4);
$$ = global_arena->New<ClassDeclaration>(yylineno, $2, $4);
}
| CHOICE identifier "{" alternative_list "}"
{
$$ = global_arena->RawNew<ChoiceDeclaration>(yylineno, $2, $4);
$$ = global_arena->New<ChoiceDeclaration>(yylineno, $2, $4);
}
| VAR variable_declaration "=" expression ";"
{
$$ = global_arena->RawNew<VariableDeclaration>(yylineno, $2, $4);
$$ = global_arena->New<VariableDeclaration>(yylineno, $2, $4);
}
;
declaration_list: