Add lexer and parser sources

This commit is contained in:
2025-06-14 23:57:48 +02:00
parent d5e2d53e9b
commit f524311f06
25 changed files with 3475 additions and 427 deletions

View File

@ -225,7 +225,7 @@ namespace elna::boot
variable_declaration::variable_declaration(const struct position position, identifier_definition identifier,
std::shared_ptr<type_expression> variable_type)
: definition(position, identifier), m_variable_type(variable_type)
: declaration(position, identifier), m_variable_type(variable_type)
{
}
@ -239,28 +239,28 @@ namespace elna::boot
return *m_variable_type;
}
definition::definition(const struct position position, identifier_definition identifier)
declaration::declaration(const struct position position, identifier_definition identifier)
: node(position), identifier(identifier)
{
}
constant_definition::constant_definition(const struct position position, identifier_definition identifier,
constant_declaration::constant_declaration(const struct position position, identifier_definition identifier,
expression *body)
: definition(position, identifier), m_body(body)
: declaration(position, identifier), m_body(body)
{
}
void constant_definition::accept(parser_visitor *visitor)
void constant_declaration::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
expression& constant_definition::body()
expression& constant_declaration::body()
{
return *m_body;
}
constant_definition::~constant_definition()
constant_declaration::~constant_declaration()
{
delete m_body;
}
@ -307,55 +307,55 @@ namespace elna::boot
return this;
}
procedure_definition::procedure_definition(const struct position position, identifier_definition identifier,
procedure_declaration::procedure_declaration(const struct position position, identifier_definition identifier,
procedure_type_expression *heading, block&& body)
: definition(position, identifier), m_heading(heading), body(std::move(body))
: declaration(position, identifier), m_heading(heading), body(std::move(body))
{
}
procedure_definition::procedure_definition(const struct position position, identifier_definition identifier,
procedure_declaration::procedure_declaration(const struct position position, identifier_definition identifier,
procedure_type_expression *heading)
: definition(position, identifier), m_heading(heading), body(std::nullopt)
: declaration(position, identifier), m_heading(heading), body(std::nullopt)
{
}
void procedure_definition::accept(parser_visitor *visitor)
void procedure_declaration::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
procedure_type_expression& procedure_definition::heading()
procedure_type_expression& procedure_declaration::heading()
{
return *m_heading;
}
procedure_definition::~procedure_definition()
procedure_declaration::~procedure_declaration()
{
delete m_heading;
}
type_definition::type_definition(const struct position position, identifier_definition identifier,
type_declaration::type_declaration(const struct position position, identifier_definition identifier,
type_expression *body)
: definition(position, identifier), m_body(body)
: declaration(position, identifier), m_body(body)
{
}
type_definition::~type_definition()
type_declaration::~type_declaration()
{
delete m_body;
}
void type_definition::accept(parser_visitor *visitor)
void type_declaration::accept(parser_visitor *visitor)
{
visitor->visit(this);
}
type_expression& type_definition::body()
type_expression& type_declaration::body()
{
return *m_body;
}
block::block(std::vector<constant_definition *>&& constants, std::vector<variable_declaration *>&& variables,
block::block(std::vector<constant_declaration *>&& constants, std::vector<variable_declaration *>&& variables,
std::vector<statement *>&& body)
: m_variables(std::move(variables)), m_constants(std::move(constants)), m_body(std::move(body))
{
@ -381,7 +381,7 @@ namespace elna::boot
return m_variables;
}
const std::vector<constant_definition *>& block::constants()
const std::vector<constant_declaration *>& block::constants()
{
return m_constants;
}
@ -401,7 +401,7 @@ namespace elna::boot
{
delete variable;
}
for (constant_definition *constant : this->constants())
for (constant_declaration *constant : this->constants())
{
delete constant;
}
@ -419,7 +419,7 @@ namespace elna::boot
unit::~unit()
{
for (procedure_definition *procedure : this->procedures)
for (procedure_declaration *procedure : this->procedures)
{
delete procedure;
}
@ -427,11 +427,11 @@ namespace elna::boot
{
delete variable;
}
for (type_definition *type : this->types)
for (type_declaration *type : this->types)
{
delete type;
}
for (constant_definition *constant : this->constants)
for (constant_declaration *constant : this->constants)
{
delete constant;
}

View File

@ -133,8 +133,8 @@ along with GCC; see the file COPYING3. If not see
%type <std::vector<elna::boot::expression *>> case_labels;
%type <elna::boot::switch_case> switch_case;
%type <std::vector<elna::boot::switch_case>> switch_cases;
%type <elna::boot::constant_definition *> constant_definition;
%type <std::vector<elna::boot::constant_definition *>> constant_part constant_definitions;
%type <elna::boot::constant_declaration *> constant_declaration;
%type <std::vector<elna::boot::constant_declaration *>> constant_part constant_declarations;
%type <std::vector<elna::boot::variable_declaration *>> variable_declarations variable_part variable_declaration;
%type <elna::boot::type_expression *> type_expression;
%type <std::vector<elna::boot::type_expression *>> type_expressions;
@ -148,12 +148,12 @@ along with GCC; see the file COPYING3. If not see
%type <elna::boot::return_statement *> return_statement;
%type <elna::boot::statement *> statement;
%type <std::vector<elna::boot::statement *>> required_statements optional_statements statement_part;
%type <elna::boot::procedure_definition *> procedure_definition;
%type <elna::boot::procedure_declaration *> procedure_declaration;
%type <std::pair<std::vector<std::string>, elna::boot::procedure_type_expression *>> procedure_heading;
%type <elna::boot::procedure_type_expression::return_t> return_declaration;
%type <std::vector<elna::boot::procedure_definition *>> procedure_definitions procedure_part;
%type <elna::boot::type_definition *> type_definition;
%type <std::vector<elna::boot::type_definition *>> type_definitions type_part;
%type <std::vector<elna::boot::procedure_declaration *>> procedure_declarations procedure_part;
%type <elna::boot::type_declaration *> type_declaration;
%type <std::vector<elna::boot::type_declaration *>> type_declarations type_part;
%type <std::unique_ptr<elna::boot::block>> block;
%type <elna::boot::field_declaration> field_declaration formal_parameter;
%type <std::vector<std::pair<std::string, elna::boot::type_expression *>>>
@ -167,28 +167,28 @@ along with GCC; see the file COPYING3. If not see
%type <std::vector<elna::boot::import_declaration *>> import_declarations import_part;
%%
program:
"program" import_part constant_part type_part variable_part procedure_part "begin" optional_statements "end" "."
"program" ";" import_part constant_part type_part variable_part procedure_part statement_part "end" "."
{
auto tree = new boot::program(boot::make_position(@7));
auto tree = new boot::program(boot::make_position(@1));
std::swap(tree->imports, $2);
std::swap(tree->constants, $3);
std::swap(tree->types , $4);
std::swap(tree->variables, $5);
std::swap(tree->procedures, $6);
std::swap(tree->imports, $3);
std::swap(tree->constants, $4);
std::swap(tree->types , $5);
std::swap(tree->variables, $6);
std::swap(tree->procedures, $7);
std::swap(tree->body, $8);
driver.tree.reset(tree);
}
| "module" import_part constant_part type_part variable_part procedure_part "end" "."
| "module" ";" import_part constant_part type_part variable_part procedure_part "end" "."
{
auto tree = new boot::program(boot::make_position(@7));
auto tree = new boot::program(boot::make_position(@1));
std::swap(tree->imports, $2);
std::swap(tree->constants, $3);
std::swap(tree->types , $4);
std::swap(tree->variables, $5);
std::swap(tree->procedures, $6);
std::swap(tree->imports, $3);
std::swap(tree->constants, $4);
std::swap(tree->types , $5);
std::swap(tree->variables, $6);
std::swap(tree->procedures, $7);
driver.tree.reset(tree);
}
@ -228,27 +228,27 @@ procedure_heading: formal_parameter_list return_declaration
$$.second->parameters.push_back(type);
}
}
procedure_definition:
"proc" identifier_definition procedure_heading ";" block
procedure_declaration:
"proc" identifier_definition procedure_heading ";" block ";"
{
$$ = new boot::procedure_definition(boot::make_position(@1), std::move($2), $3.second, std::move(*$5));
$$ = new boot::procedure_declaration(boot::make_position(@1), std::move($2), $3.second, std::move(*$5));
std::swap($3.first, $$->parameter_names);
}
| "proc" identifier_definition procedure_heading ";" "extern"
| "proc" identifier_definition procedure_heading ";" "extern" ";"
{
$$ = new boot::procedure_definition(boot::make_position(@1), std::move($2), $3.second);
$$ = new boot::procedure_declaration(boot::make_position(@1), std::move($2), $3.second);
std::swap($3.first, $$->parameter_names);
}
procedure_definitions:
procedure_definition procedure_definitions
procedure_declarations:
procedure_declaration procedure_declarations
{
std::swap($$, $2);
$$.emplace($$.cbegin(), std::move($1));
}
| procedure_definition { $$.emplace_back(std::move($1)); }
| procedure_declaration { $$.emplace_back(std::move($1)); }
procedure_part:
/* no procedure definitions */ {}
| procedure_definitions { std::swap($$, $1); }
| procedure_declarations { std::swap($$, $1); }
call_expression: designator_expression actual_parameter_list
{
$$ = new boot::procedure_call(boot::make_position(@1), $1);
@ -454,9 +454,9 @@ optional_statements:
field_declaration:
IDENTIFIER ":" type_expression { $$ = std::make_pair($1, $3); }
required_fields:
field_declaration required_fields
field_declaration ";" required_fields
{
std::swap($$, $2);
std::swap($$, $3);
$$.emplace($$.cbegin(), $1);
}
| field_declaration { $$.emplace_back($1); }
@ -501,7 +501,7 @@ identifiers:
$$.emplace($$.cbegin(), std::move($1));
}
| IDENTIFIER { $$.emplace_back(std::move($1)); }
variable_declaration: identifier_definitions ":" type_expression
variable_declaration: identifier_definitions ":" type_expression ";"
{
std::shared_ptr<boot::type_expression> shared_type{ $3 };
@ -523,12 +523,12 @@ variable_declarations:
variable_part:
/* no variable declarations */ {}
| "var" variable_declarations { std::swap($$, $2); }
constant_definition: identifier_definition ":=" expression
constant_declaration: identifier_definition ":=" expression ";"
{
$$ = new boot::constant_definition(boot::make_position(@1), std::move($1), $3);
$$ = new boot::constant_declaration(boot::make_position(@1), std::move($1), $3);
}
constant_definitions:
constant_definition constant_definitions
constant_declarations:
constant_declaration constant_declarations
{
std::swap($$, $2);
$$.insert($$.cbegin(), $1);
@ -536,7 +536,7 @@ constant_definitions:
| /* no constant definitions */ {}
constant_part:
/* no constant definitions */ {}
| "const" constant_definitions { std::swap($$, $2); }
| "const" constant_declarations { std::swap($$, $2); }
import_declaration:
IDENTIFIER "." import_declaration
{
@ -545,8 +545,7 @@ import_declaration:
}
| IDENTIFIER { $$.emplace_back(std::move($1)); }
import_declarations:
/* no import declarations */ {}
| import_declaration "," import_declarations
import_declaration "," import_declarations
{
std::swap($$, $3);
$$.emplace($$.cbegin(), new boot::import_declaration(boot::make_position(@1), std::move($1)));
@ -557,13 +556,13 @@ import_declarations:
}
import_part:
/* no import declarations */ {}
| "import" import_declarations { std::swap($$, $2); }
type_definition: identifier_definition "=" type_expression
| "import" import_declarations ";" { std::swap($$, $2); }
type_declaration: identifier_definition "=" type_expression ";"
{
$$ = new boot::type_definition(boot::make_position(@1), std::move($1), $3);
$$ = new boot::type_declaration(boot::make_position(@1), std::move($1), $3);
}
type_definitions:
type_definition type_definitions
type_declarations:
type_declaration type_declarations
{
std::swap($$, $2);
$$.insert($$.cbegin(), $1);
@ -571,7 +570,7 @@ type_definitions:
| /* no type definitions */ {}
type_part:
/* no type definitions */ {}
| "type" type_definitions { std::swap($$, $2); }
| "type" type_declarations { std::swap($$, $2); }
formal_parameter:
IDENTIFIER ":" type_expression { $$ = std::make_pair($1, $3); }
formal_parameter_list:

View File

@ -83,7 +83,7 @@ namespace elna::boot
}
}
void declaration_visitor::visit(type_definition *definition)
void declaration_visitor::visit(type_declaration *definition)
{
definition->body().accept(this);
auto unresolved_declaration = this->unresolved.at(definition->identifier.identifier);
@ -164,9 +164,12 @@ namespace elna::boot
void declaration_visitor::visit(variable_declaration *declaration)
{
declaration->variable_type().accept(this);
this->symbols->enter(declaration->identifier.identifier,
std::make_shared<variable_info>(this->current_type));
}
void declaration_visitor::visit(constant_definition *definition)
void declaration_visitor::visit(constant_declaration *definition)
{
definition->body().accept(this);
@ -174,7 +177,7 @@ namespace elna::boot
std::make_shared<constant_info>(this->current_literal));
}
void declaration_visitor::visit(procedure_definition *definition)
void declaration_visitor::visit(procedure_declaration *definition)
{
std::shared_ptr<procedure_info> info = std::make_shared<procedure_info>(
build_procedure(definition->heading()), definition->parameter_names);
@ -184,7 +187,7 @@ namespace elna::boot
if (definition->body.has_value())
{
for (constant_definition *const constant : definition->body.value().constants())
for (constant_declaration *const constant : definition->body.value().constants())
{
constant->accept(this);
}
@ -293,7 +296,7 @@ namespace elna::boot
void declaration_visitor::visit(unit *unit)
{
for (type_definition *const type : unit->types)
for (type_declaration *const type : unit->types)
{
const std::string& type_identifier = type->identifier.identifier;
@ -303,7 +306,7 @@ namespace elna::boot
add_error<already_declared_error>(type->identifier.identifier, this->input_file, type->position());
}
}
for (type_definition *const type : unit->types)
for (type_declaration *const type : unit->types)
{
type->accept(this);
}
@ -316,7 +319,7 @@ namespace elna::boot
{
variable->accept(this);
}
for (procedure_definition *const procedure : unit->procedures)
for (procedure_declaration *const procedure : unit->procedures)
{
procedure->accept(this);
}

View File

@ -332,8 +332,8 @@ namespace elna::boot
return std::static_pointer_cast<constant_info>(shared_from_this());
}
variable_info::variable_info(const std::string& name, const type symbol)
: name(name), symbol(symbol)
variable_info::variable_info(const type symbol)
: symbol(symbol)
{
}