mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 20:11:12 +01:00
[executable semantics] Minimal cxx parser (#363)
Makes a minimal transition to using C++ in the parser.
This commit is contained in:
@@ -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]+ ;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user