mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
[executable semantics] Use type-safe variant in C++ parser (#364)
We're now one step away from eliminating bare pointers in semantic actions. There are plenty of other cleanups and modernizations that can be made in the parser, but the elimination of bare pointers is the one that has the highest impact for the codebase.
This commit is contained in:
@@ -9,9 +9,16 @@
|
||||
%require "3.2"
|
||||
%language "c++"
|
||||
|
||||
// We don't need a separate header for Bison locations yet.
|
||||
// We don't need a separate header for Bison locations.
|
||||
%define api.location.file none
|
||||
|
||||
// Use a type-safe C++ variant for semantic values
|
||||
%define api.value.type variant
|
||||
|
||||
// Have Bison generate the functions ‘make_TEXT’ and ‘make_NUMBER’, but also
|
||||
// ‘make_YYEOF’, for the end of input.
|
||||
%define api.token.constructor
|
||||
|
||||
//
|
||||
// Parameters to the parser and lexer
|
||||
//
|
||||
@@ -64,8 +71,6 @@ void yy::parser::error(
|
||||
|
||||
}
|
||||
|
||||
%define api.value.type union
|
||||
|
||||
%token <int> integer_literal
|
||||
%token <char*> identifier
|
||||
%type <char*> designator
|
||||
@@ -89,6 +94,7 @@ void yy::parser::error(
|
||||
%type <std::list<std::pair<std::string, Carbon::Expression*>>*> alternative_list
|
||||
%type <std::pair<Carbon::Expression*, Carbon::Statement*>*> clause
|
||||
%type <std::list<std::pair<Carbon::Expression*, Carbon::Statement*>>*> clause_list
|
||||
%token END_OF_FILE 0
|
||||
%token AND
|
||||
%token OR
|
||||
%token NOT
|
||||
@@ -99,7 +105,7 @@ void yy::parser::error(
|
||||
%token FNTY
|
||||
%token ARROW
|
||||
%token VAR
|
||||
%token EQUAL
|
||||
%token EQUAL_EQUAL
|
||||
%token IF
|
||||
%token ELSE
|
||||
%token WHILE
|
||||
@@ -115,13 +121,31 @@ void yy::parser::error(
|
||||
%token DBLARROW
|
||||
%token DEFAULT
|
||||
%token AUTO
|
||||
%nonassoc '{' '}'
|
||||
%nonassoc ':' ',' DBLARROW
|
||||
%token
|
||||
EQUAL "="
|
||||
MINUS "-"
|
||||
PLUS "+"
|
||||
STAR "*"
|
||||
SLASH "/"
|
||||
LEFT_PARENTHESIS "("
|
||||
RIGHT_PARENTHESIS ")"
|
||||
LEFT_CURLY_BRACE "{"
|
||||
RIGHT_CURLY_BRACE "}"
|
||||
LEFT_SQUARE_BRACKET "["
|
||||
RIGHT_SQUARE_BRACKET "]"
|
||||
PERIOD "."
|
||||
COMMA ","
|
||||
SEMICOLON ";"
|
||||
COLON ":"
|
||||
;
|
||||
|
||||
%nonassoc "{" "}"
|
||||
%nonassoc ":" "," DBLARROW
|
||||
%left OR AND
|
||||
%nonassoc EQUAL NOT
|
||||
%left '+' '-'
|
||||
%left '.' ARROW
|
||||
%nonassoc '(' ')' '[' ']'
|
||||
%nonassoc EQUAL_EQUAL NOT
|
||||
%left "+" "-"
|
||||
%left "." ARROW
|
||||
%nonassoc "(" ")" "[" "]"
|
||||
%start input
|
||||
%locations
|
||||
%%
|
||||
@@ -137,9 +161,9 @@ expression:
|
||||
{ $$ = Carbon::MakeVar(yylineno, $1); }
|
||||
| expression designator
|
||||
{ $$ = Carbon::MakeGetField(yylineno, $1, $2); }
|
||||
| expression '[' expression ']'
|
||||
| expression "[" expression "]"
|
||||
{ $$ = Carbon::MakeIndex(yylineno, $1, $3); }
|
||||
| expression ':' identifier
|
||||
| expression ":" identifier
|
||||
{ $$ = Carbon::MakeVarPat(yylineno, $3, $1); }
|
||||
| integer_literal
|
||||
{ $$ = Carbon::MakeInt(yylineno, $1); }
|
||||
@@ -156,11 +180,11 @@ expression:
|
||||
| AUTO
|
||||
{ $$ = Carbon::MakeAutoType(yylineno); }
|
||||
| paren_expression { $$ = $1; }
|
||||
| expression EQUAL expression
|
||||
| expression EQUAL_EQUAL expression
|
||||
{ $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::Eq, $1, $3); }
|
||||
| expression '+' expression
|
||||
| expression "+" expression
|
||||
{ $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::Add, $1, $3); }
|
||||
| expression '-' expression
|
||||
| expression "-" expression
|
||||
{ $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::Sub, $1, $3); }
|
||||
| expression AND expression
|
||||
{ $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::And, $1, $3); }
|
||||
@@ -168,16 +192,16 @@ expression:
|
||||
{ $$ = Carbon::MakeBinOp(yylineno, Carbon::Operator::Or, $1, $3); }
|
||||
| NOT expression
|
||||
{ $$ = Carbon::MakeUnOp(yylineno, Carbon::Operator::Not, $2); }
|
||||
| '-' expression
|
||||
| "-" expression
|
||||
{ $$ = Carbon::MakeUnOp(yylineno, Carbon::Operator::Neg, $2); }
|
||||
| expression tuple
|
||||
{ $$ = Carbon::MakeCall(yylineno, $1, $2); }
|
||||
| FNTY tuple return_type
|
||||
{ $$ = Carbon::MakeFunType(yylineno, $2, $3); }
|
||||
;
|
||||
designator: '.' identifier { $$ = $2; }
|
||||
designator: "." identifier { $$ = $2; }
|
||||
;
|
||||
paren_expression: '(' field_list ')'
|
||||
paren_expression: "(" field_list ")"
|
||||
{
|
||||
if ($2->fields->size() == 1 &&
|
||||
$2->fields->front().first == "" &&
|
||||
@@ -190,7 +214,7 @@ paren_expression: '(' field_list ')'
|
||||
}
|
||||
}
|
||||
;
|
||||
tuple: '(' field_list ')'
|
||||
tuple: "(" field_list ")"
|
||||
{
|
||||
auto vec = new std::vector<std::pair<std::string,Carbon::Expression*>>(
|
||||
$2->fields->begin(), $2->fields->end());
|
||||
@@ -204,7 +228,7 @@ field:
|
||||
fields->push_back(std::make_pair("", $1));
|
||||
$$ = Carbon::MakeFieldList(fields);
|
||||
}
|
||||
| designator '=' pattern
|
||||
| designator "=" pattern
|
||||
{
|
||||
auto fields =
|
||||
new std::list<std::pair<std::string, Carbon::Expression*>>();
|
||||
@@ -220,7 +244,7 @@ field_list:
|
||||
}
|
||||
| field
|
||||
{ $$ = $1; }
|
||||
| field ',' field_list
|
||||
| field "," field_list
|
||||
{ $$ = Carbon::MakeConsField($1, $3); }
|
||||
;
|
||||
clause:
|
||||
@@ -242,25 +266,25 @@ clause_list:
|
||||
{ $$ = $2; $$->push_front(*$1); }
|
||||
;
|
||||
statement:
|
||||
expression '=' expression ';'
|
||||
expression "=" expression ";"
|
||||
{ $$ = Carbon::MakeAssign(yylineno, $1, $3); }
|
||||
| VAR pattern '=' expression ';'
|
||||
| VAR pattern "=" expression ";"
|
||||
{ $$ = Carbon::MakeVarDef(yylineno, $2, $4); }
|
||||
| expression ';'
|
||||
| expression ";"
|
||||
{ $$ = Carbon::MakeExpStmt(yylineno, $1); }
|
||||
| IF '(' expression ')' statement optional_else
|
||||
| IF "(" expression ")" statement optional_else
|
||||
{ $$ = Carbon::MakeIf(yylineno, $3, $5, $6); }
|
||||
| WHILE '(' expression ')' statement
|
||||
| WHILE "(" expression ")" statement
|
||||
{ $$ = Carbon::MakeWhile(yylineno, $3, $5); }
|
||||
| BREAK ';'
|
||||
| BREAK ";"
|
||||
{ $$ = Carbon::MakeBreak(yylineno); }
|
||||
| CONTINUE ';'
|
||||
| CONTINUE ";"
|
||||
{ $$ = Carbon::MakeContinue(yylineno); }
|
||||
| RETURN expression ';'
|
||||
| RETURN expression ";"
|
||||
{ $$ = Carbon::MakeReturn(yylineno, $2); }
|
||||
| '{' statement_list '}'
|
||||
| "{" statement_list "}"
|
||||
{ $$ = Carbon::MakeBlock(yylineno, $2); }
|
||||
| MATCH '(' expression ')' '{' clause_list '}'
|
||||
| MATCH "(" expression ")" "{" clause_list "}"
|
||||
{ $$ = Carbon::MakeMatch(yylineno, $3, $6); }
|
||||
;
|
||||
optional_else:
|
||||
@@ -285,20 +309,20 @@ return_type:
|
||||
{ $$ = $2; }
|
||||
;
|
||||
function_definition:
|
||||
FN identifier tuple return_type '{' statement_list '}'
|
||||
FN identifier tuple return_type "{" statement_list "}"
|
||||
{ $$ = MakeFunDef(yylineno, $2, $4, $3, $6); }
|
||||
| FN identifier tuple DBLARROW expression ';'
|
||||
| FN identifier tuple DBLARROW expression ";"
|
||||
{
|
||||
$$ = Carbon::MakeFunDef(yylineno, $2, Carbon::MakeAutoType(yylineno), $3,
|
||||
Carbon::MakeReturn(yylineno, $5));
|
||||
}
|
||||
;
|
||||
function_declaration:
|
||||
FN identifier tuple return_type ';'
|
||||
FN identifier tuple return_type ";"
|
||||
{ $$ = MakeFunDef(yylineno, $2, $4, $3, 0); }
|
||||
;
|
||||
member:
|
||||
VAR expression ':' identifier ';'
|
||||
VAR expression ":" identifier ";"
|
||||
{ $$ = MakeField(yylineno, $4, $2); }
|
||||
;
|
||||
member_list:
|
||||
@@ -326,7 +350,7 @@ alternative_list:
|
||||
$$ = new std::list<std::pair<std::string, Carbon::Expression*>>();
|
||||
$$->push_front(*$1);
|
||||
}
|
||||
| alternative ',' alternative_list
|
||||
| alternative "," alternative_list
|
||||
{ $$ = $3; $$->push_front(*$1); }
|
||||
;
|
||||
declaration:
|
||||
@@ -334,12 +358,12 @@ declaration:
|
||||
{ $$ = new Carbon::Declaration(Carbon::FunctionDeclaration{$1}); }
|
||||
| function_declaration
|
||||
{ $$ = new Carbon::Declaration(Carbon::FunctionDeclaration{$1}); }
|
||||
| STRUCT identifier '{' member_list '}'
|
||||
| STRUCT identifier "{" member_list "}"
|
||||
{
|
||||
$$ = new Carbon::Declaration(
|
||||
Carbon::StructDeclaration{yylineno, $2, $4});
|
||||
}
|
||||
| CHOICE identifier '{' alternative_list '}'
|
||||
| CHOICE identifier "{" alternative_list "}"
|
||||
{
|
||||
$$ = new Carbon::Declaration(
|
||||
Carbon::ChoiceDeclaration{yylineno, $2, std::list(*$4)});
|
||||
|
||||
Reference in New Issue
Block a user