[executable semantics] Minimal cxx parser (#363)

Makes a minimal transition to using C++ in the parser.
This commit is contained in:
Dave Abrahams
2021-03-09 20:46:52 -08:00
committed by GitHub
parent 07a37933c6
commit 436a9dda79
5 changed files with 91 additions and 92 deletions
+31 -31
View File
@@ -50,43 +50,43 @@ integer_literal [0-9]+
%%
{AND} { return AND; }
{ARROW} { return ARROW; }
{AUTO} { return AUTO; }
{BOOL} { return BOOL; }
{BREAK} { return BREAK; }
{CASE} { return CASE; }
{CHOICE} { return CHOICE; }
{AND} { return yy::parser::token::AND; }
{ARROW} { return yy::parser::token::ARROW; }
{AUTO} { return yy::parser::token::AUTO; }
{BOOL} { return yy::parser::token::BOOL; }
{BREAK} { return yy::parser::token::BREAK; }
{CASE} { return yy::parser::token::CASE; }
{CHOICE} { return yy::parser::token::CHOICE; }
{COMMENT} ;
{CONTINUE} { return CONTINUE; }
{DBLARROW} { return DBLARROW; }
{DEFAULT} { return DEFAULT; }
{ELSE} { return ELSE; }
{EQUAL} { return EQUAL; }
{FALSE} { return FALSE; }
{FN} { return FN; }
{FNTY} { return FNTY; }
{IF} { return IF; }
{INT} { return INT; }
{MATCH} { return MATCH; }
{NOT} { return NOT; }
{OR} { return OR; }
{RETURN} { return RETURN; }
{STRUCT} { return STRUCT; }
{TRUE} { return TRUE; }
{TYPE} { return TYPE; }
{VAR} { return VAR; }
{WHILE} { return WHILE; }
{CONTINUE} { return yy::parser::token::CONTINUE; }
{DBLARROW} { return yy::parser::token::DBLARROW; }
{DEFAULT} { return yy::parser::token::DEFAULT; }
{ELSE} { return yy::parser::token::ELSE; }
{EQUAL} { return yy::parser::token::EQUAL; }
{FALSE} { return yy::parser::token::FALSE; }
{FN} { return yy::parser::token::FN; }
{FNTY} { return yy::parser::token::FNTY; }
{IF} { return yy::parser::token::IF; }
{INT} { return yy::parser::token::INT; }
{MATCH} { return yy::parser::token::MATCH; }
{NOT} { return yy::parser::token::NOT; }
{OR} { return yy::parser::token::OR; }
{RETURN} { return yy::parser::token::RETURN; }
{STRUCT} { return yy::parser::token::STRUCT; }
{TRUE} { return yy::parser::token::TRUE; }
{TYPE} { return yy::parser::token::TYPE; }
{VAR} { return yy::parser::token::VAR; }
{WHILE} { return yy::parser::token::WHILE; }
{identifier} {
int n = strlen(yytext);
yylval.str = reinterpret_cast<char*>(malloc((n + 1) * sizeof(char)));
strncpy(yylval.str, yytext, n + 1);
return identifier;
yylval->identifier = reinterpret_cast<char*>(malloc((n + 1) * sizeof(char)));
strncpy(yylval->identifier, yytext, n + 1);
return yy::parser::token::identifier;
}
{integer_literal} {
yylval.num = atof(yytext);
return integer_literal;
yylval->integer_literal = atof(yytext);
return yy::parser::token::integer_literal;
}
[ \t\n]+ ;
+2 -1
View File
@@ -7,6 +7,7 @@
#include <iostream>
#include "executable_semantics/syntax/parse_and_lex_context.h"
#include "executable_semantics/syntax/parser.h"
#include "executable_semantics/tracing_flag.h"
extern FILE* yyin;
@@ -28,7 +29,7 @@ auto parse(const std::string& inputFileName)
std::optional<AST> parsedInput = std::nullopt;
ParseAndLexContext context(inputFileName);
auto syntaxErrorCode = yyparse(parsedInput, context);
auto syntaxErrorCode = yy::parser(parsedInput, context)();
if (syntaxErrorCode != 0) {
return syntaxErrorCode;
}
@@ -11,7 +11,7 @@
// Writes a syntax error diagnostic, containing message, for the input file at
// the given line, to standard error.
auto Carbon::ParseAndLexContext::PrintDiagnostic(const char* message,
auto Carbon::ParseAndLexContext::PrintDiagnostic(const std::string& message,
int line_num) -> void {
std::cerr << inputFileName << ":" << line_num << ": " << message << std::endl;
exit(-1); // TODO: do we really want this here? It makes the comment and the
@@ -21,7 +21,7 @@ class ParseAndLexContext {
// Writes a syntax error diagnostic, containing message, for the input file at
// the given line, to standard error.
auto PrintDiagnostic(const char* message, int lineNumber) -> void;
auto PrintDiagnostic(const std::string& message, int lineNumber) -> void;
private:
// A path to the file processed, relative to the current working directory
@@ -32,7 +32,10 @@ class ParseAndLexContext {
} // namespace Carbon
// Gives flex the yylex prototype we want.
#define YY_DECL int yylex(Carbon::ParseAndLexContext& context)
#define YY_DECL \
int yylex(yy::parser::semantic_type* yylval, \
yy::parser::location_type* sourceLocation, \
Carbon::ParseAndLexContext& context)
// Declares yylex for the parser's sake.
YY_DECL;
+52 -57
View File
@@ -2,6 +2,30 @@
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// -----------------------------------------------------------------------------
// Bison Configuration
// -----------------------------------------------------------------------------
%require "3.2"
%language "c++"
// We don't need a separate header for Bison locations yet.
%define api.location.file none
//
// Parameters to the parser and lexer
//
// Parameters to the parser are stored therein as protected data members, and
// thus available to its methods.
// "out" parameter passed to the parser, where the AST is written.
%parse-param {std::optional<Carbon::AST>& parsedProgram}
// "inout" parameter passed to both the parser and the lexer.
%param {Carbon::ParseAndLexContext& context}
// -----------------------------------------------------------------------------
%code top {
#include <algorithm>
#include <cstdarg>
@@ -32,68 +56,39 @@ class ParseAndLexContext;
extern int yylineno;
void yyerror(
std::optional<Carbon::AST> const& /* parsedProgram */,
Carbon::ParseAndLexContext& context,
char* message
) {
void yy::parser::error(
const location_type&, const std::string& message)
{
context.PrintDiagnostic(message, yylineno);
}
}
//
// Parameters to yyparse and yylex.
//
%define api.value.type union
// "out" parameter passed to the parser, where the AST is written.
%parse-param {std::optional<Carbon::AST>& parsedProgram}
// "inout" parameter passed to both the parser and the lexer.
%param {Carbon::ParseAndLexContext& context}
%union {
char* str;
int num;
Carbon::Expression* expression;
std::list<std::pair<std::string, Carbon::Expression*>>* field_types;
Carbon::Statement* statement;
Carbon::Statement* statement_list;
Carbon::FunctionDefinition* function_definition;
Carbon::Declaration* declaration;
std::list<Carbon::Declaration>* declaration_list;
Carbon::Member* member;
std::list<Carbon::Member*>* member_list;
Carbon::FieldList* field_list;
std::pair<std::string, Carbon::Expression*>* alternative;
std::list<std::pair<std::string, Carbon::Expression*>>* alternative_list;
std::pair<Carbon::Expression*, Carbon::Statement*>* clause;
std::list<std::pair<Carbon::Expression*, Carbon::Statement*>>* clause_list;
Carbon::Expression* fun_type;
};
%token <num> integer_literal
%token <str> identifier
%type <str> designator
%type <declaration> declaration
%type <function_definition> function_declaration
%type <function_definition> function_definition
%type <declaration_list> declaration_list
%type <statement> statement
%type <statement> optional_else
%type <statement_list> statement_list
%type <expression> expression
%type <expression> pattern
%type <expression> return_type
%type <expression> paren_expression
%type <expression> tuple
%type <member> member
%type <member_list> member_list
%type <field_list> field
%type <field_list> field_list
%type <alternative> alternative
%type <alternative_list> alternative_list
%type <clause> clause
%type <clause_list> clause_list
%token <int> integer_literal
%token <char*> identifier
%type <char*> designator
%type <Carbon::Declaration*> declaration
%type <Carbon::FunctionDefinition*> function_declaration
%type <Carbon::FunctionDefinition*> function_definition
%type <std::list<Carbon::Declaration>*> declaration_list
%type <Carbon::Statement*> statement
%type <Carbon::Statement*> optional_else
%type <Carbon::Statement*> statement_list
%type <Carbon::Expression*> expression
%type <Carbon::Expression*> pattern
%type <Carbon::Expression*> return_type
%type <Carbon::Expression*> paren_expression
%type <Carbon::Expression*> tuple
%type <Carbon::Member*> member
%type <std::list<Carbon::Member*>*> member_list
%type <Carbon::FieldList*> field
%type <Carbon::FieldList*> field_list
%type <std::pair<std::string, Carbon::Expression*>*> alternative
%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 AND
%token OR
%token NOT