Construct the parse tree with raw pointers

This commit is contained in:
Eugen Wissner 2025-01-05 15:21:25 +01:00
parent bbd38a5d26
commit e8747a803f
Signed by: belka
GPG Key ID: A27FDC1E8EE902C0
3 changed files with 269 additions and 166 deletions

View File

@ -262,7 +262,7 @@ namespace source
*/ */
class declaration : public definition class declaration : public definition
{ {
std::unique_ptr<type_expression> m_type; type_expression *m_type;
public: public:
/** /**
@ -273,10 +273,12 @@ namespace source
* \param type Declared type. * \param type Declared type.
*/ */
declaration(const struct position position, const std::string& identifier, declaration(const struct position position, const std::string& identifier,
std::unique_ptr<type_expression>&& type); type_expression *type);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
type_expression& type() noexcept; type_expression& type() noexcept;
virtual ~declaration() override;
}; };
/** /**
@ -284,7 +286,7 @@ namespace source
*/ */
class constant_definition : public definition class constant_definition : public definition
{ {
std::unique_ptr<number_literal<std::int32_t>> m_body; number_literal<std::int32_t> *m_body;
public: public:
/** /**
@ -293,10 +295,12 @@ namespace source
* \param body Constant value. * \param body Constant value.
*/ */
constant_definition(const struct position position, const std::string& identifier, constant_definition(const struct position position, const std::string& identifier,
std::unique_ptr<number_literal<std::int32_t>>&& body); number_literal<std::int32_t> *body);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
number_literal<std::int32_t>& body(); number_literal<std::int32_t>& body();
virtual ~constant_definition() override;
}; };
/** /**
@ -304,8 +308,8 @@ namespace source
*/ */
class procedure_definition : public definition class procedure_definition : public definition
{ {
std::unique_ptr<block> m_body; block *m_body;
std::vector<std::unique_ptr<declaration>> m_parameters; std::vector<declaration *> m_parameters;
public: public:
/** /**
@ -314,11 +318,13 @@ namespace source
* \param body Procedure body. * \param body Procedure body.
*/ */
procedure_definition(const struct position position, const std::string& identifier, procedure_definition(const struct position position, const std::string& identifier,
std::unique_ptr<block>&& body); block *body);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
block& body(); block& body();
std::vector<std::unique_ptr<declaration>>& parameters() noexcept; std::vector<declaration *>& parameters() noexcept;
virtual ~procedure_definition() override;
}; };
/** /**
@ -327,7 +333,7 @@ namespace source
class call_statement : public statement class call_statement : public statement
{ {
std::string m_name; std::string m_name;
std::vector<std::unique_ptr<expression>> m_arguments; std::vector<expression *> m_arguments;
public: public:
/** /**
@ -338,24 +344,28 @@ namespace source
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
std::string& name() noexcept; std::string& name() noexcept;
std::vector<std::unique_ptr<expression>>& arguments() noexcept; std::vector<expression *>& arguments() noexcept;
virtual ~call_statement() override;
}; };
class compound_statement : public statement class compound_statement : public statement
{ {
std::vector<std::unique_ptr<statement>> m_statements; std::vector<statement *> m_statements;
public: public:
explicit compound_statement(const struct position position); explicit compound_statement(const struct position position);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
std::vector<std::unique_ptr<statement>>& statements(); std::vector<statement *>& statements();
virtual ~compound_statement() override;
}; };
class assign_statement : public statement class assign_statement : public statement
{ {
std::string m_lvalue; std::string m_lvalue;
std::unique_ptr<expression> m_rvalue; expression *m_rvalue;
public: public:
/** /**
@ -364,11 +374,13 @@ namespace source
* \param rvalue Assigned expression. * \param rvalue Assigned expression.
*/ */
assign_statement(const struct position position, const std::string& lvalue, assign_statement(const struct position position, const std::string& lvalue,
std::unique_ptr<expression>&& rvalue); expression *rvalue);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
std::string& lvalue() noexcept; std::string& lvalue() noexcept;
expression& rvalue(); expression& rvalue();
virtual ~assign_statement() override;
}; };
/** /**
@ -376,9 +388,9 @@ namespace source
*/ */
class if_statement : public statement class if_statement : public statement
{ {
std::unique_ptr<expression> m_prerequisite; expression *m_prerequisite;
std::unique_ptr<statement> m_body; statement *m_body;
std::unique_ptr<statement> m_alternative; statement *m_alternative;
public: public:
/** /**
@ -387,13 +399,15 @@ namespace source
* \param body Statement executed if the condition is met. * \param body Statement executed if the condition is met.
* \param alternative Statement executed if the condition is not met. * \param alternative Statement executed if the condition is not met.
*/ */
if_statement(const struct position position, std::unique_ptr<expression>&& prerequisite, if_statement(const struct position position, expression *prerequisite,
std::unique_ptr<statement>&& body, std::unique_ptr<statement>&& alternative = nullptr); statement *body, statement *alternative = nullptr);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
expression& prerequisite(); expression& prerequisite();
statement& body(); statement& body();
std::unique_ptr<statement>& alternative(); statement *alternative();
virtual ~if_statement() override;
}; };
/** /**
@ -401,8 +415,8 @@ namespace source
*/ */
class while_statement : public statement class while_statement : public statement
{ {
std::unique_ptr<expression> m_prerequisite; expression *m_prerequisite;
std::unique_ptr<statement> m_body; statement *m_body;
public: public:
/** /**
@ -410,37 +424,41 @@ namespace source
* \param prerequisite Condition. * \param prerequisite Condition.
* \param body Statement executed while the condition is met. * \param body Statement executed while the condition is met.
*/ */
while_statement(const struct position position, std::unique_ptr<expression>&& prerequisite, while_statement(const struct position position, expression *prerequisite,
std::unique_ptr<statement>&& body); statement *body);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
expression& prerequisite(); expression& prerequisite();
statement& body(); statement& body();
virtual ~while_statement() override;
}; };
class block : public node class block : public node
{ {
std::vector<std::unique_ptr<definition>> m_definitions; std::vector<definition *> m_definitions;
std::vector<std::unique_ptr<declaration>> m_declarations; std::vector<declaration *> m_declarations;
std::unique_ptr<statement> m_body; statement *m_body;
public: public:
block(const struct position position, std::vector<std::unique_ptr<definition>>&& definitions, block(const struct position position, std::vector<definition *>&& definitions,
std::vector<std::unique_ptr<declaration>>&& declarations, std::vector<declaration *>&& declarations,
std::unique_ptr<statement>&& body); statement *body);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
statement& body(); statement& body();
std::vector<std::unique_ptr<definition>>& definitions() noexcept; std::vector<definition *>& definitions() noexcept;
std::vector<std::unique_ptr<declaration>>& declarations() noexcept; std::vector<declaration *>& declarations() noexcept;
virtual ~block() override;
}; };
class program : public block class program : public block
{ {
public: public:
program(const struct position position, std::vector<std::unique_ptr<definition>>&& definitions, program(const struct position position, std::vector<definition *>&& definitions,
std::vector<std::unique_ptr<declaration>>&& declarations, std::vector<declaration *>&& declarations,
std::unique_ptr<statement>&& body); statement *body);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
}; };
@ -501,32 +519,36 @@ namespace source
class binary_expression : public expression class binary_expression : public expression
{ {
std::unique_ptr<expression> m_lhs; expression *m_lhs;
std::unique_ptr<expression> m_rhs; expression *m_rhs;
binary_operator m_operator; binary_operator m_operator;
public: public:
binary_expression(const struct position position, std::unique_ptr<expression>&& lhs, binary_expression(const struct position position, expression *lhs,
std::unique_ptr<expression>&& rhs, const unsigned char operation); expression *rhs, const unsigned char operation);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
expression& lhs(); expression& lhs();
expression& rhs(); expression& rhs();
binary_operator operation() const noexcept; binary_operator operation() const noexcept;
virtual ~binary_expression() override;
}; };
class unary_expression : public expression class unary_expression : public expression
{ {
std::unique_ptr<expression> m_operand; expression *m_operand;
unary_operator m_operator; unary_operator m_operator;
public: public:
unary_expression(const struct position position, std::unique_ptr<expression>&& operand, unary_expression(const struct position position, expression *operand,
const unsigned char operation); const unsigned char operation);
virtual void accept(parser_visitor *visitor) override; virtual void accept(parser_visitor *visitor) override;
expression& operand(); expression& operand();
unary_operator operation() const noexcept; unary_operator operation() const noexcept;
virtual ~unary_expression() override;
}; };
const char *print_binary_operator(const binary_operator operation); const char *print_binary_operator(const binary_operator operation);

View File

@ -18,7 +18,7 @@ namespace source
void empty_visitor::visit(procedure_definition *definition) void empty_visitor::visit(procedure_definition *definition)
{ {
for (auto& parameter : definition->parameters()) for (auto parameter : definition->parameters())
{ {
parameter->accept(this); parameter->accept(this);
} }
@ -211,11 +211,16 @@ namespace source
} }
declaration::declaration(const struct position position, const std::string& identifier, declaration::declaration(const struct position position, const std::string& identifier,
std::unique_ptr<type_expression>&& type) type_expression *type)
: definition(position, identifier), m_type(std::move(type)) : definition(position, identifier), m_type(type)
{ {
} }
declaration::~declaration()
{
delete m_type;
}
void declaration::accept(parser_visitor *visitor) void declaration::accept(parser_visitor *visitor)
{ {
visitor->visit(this); visitor->visit(this);
@ -237,8 +242,8 @@ namespace source
} }
constant_definition::constant_definition(const struct position position, const std::string& identifier, constant_definition::constant_definition(const struct position position, const std::string& identifier,
std::unique_ptr<number_literal<std::int32_t>>&& body) number_literal<std::int32_t> *body)
: definition(position, identifier), m_body(std::move(body)) : definition(position, identifier), m_body(body)
{ {
} }
@ -252,9 +257,14 @@ namespace source
return *m_body; return *m_body;
} }
constant_definition::~constant_definition()
{
delete m_body;
}
procedure_definition::procedure_definition(const struct position position, const std::string& identifier, procedure_definition::procedure_definition(const struct position position, const std::string& identifier,
std::unique_ptr<block>&& body) block *body)
: definition(position, identifier), m_body(std::move(body)) : definition(position, identifier), m_body(body)
{ {
} }
@ -268,14 +278,23 @@ namespace source
return *m_body; return *m_body;
} }
std::vector<std::unique_ptr<declaration>>& procedure_definition::parameters() noexcept std::vector<declaration *>& procedure_definition::parameters() noexcept
{ {
return m_parameters; return m_parameters;
} }
block::block(const struct position position, std::vector<std::unique_ptr<definition>>&& definitions, procedure_definition::~procedure_definition()
std::vector<std::unique_ptr<declaration>>&& declarations, {
std::unique_ptr<statement>&& body) delete m_body;
for (auto parameter : m_parameters)
{
delete parameter;
}
}
block::block(const struct position position, std::vector<definition *>&& definitions,
std::vector<declaration *>&& declarations,
statement *body)
: node(position), m_definitions(std::move(definitions)), : node(position), m_definitions(std::move(definitions)),
m_declarations(std::move(declarations)), m_body(std::move(body)) m_declarations(std::move(declarations)), m_body(std::move(body))
{ {
@ -291,20 +310,33 @@ namespace source
return *m_body; return *m_body;
} }
std::vector<std::unique_ptr<definition>>& block::definitions() noexcept std::vector<definition *>& block::definitions() noexcept
{ {
return m_definitions; return m_definitions;
} }
std::vector<std::unique_ptr<declaration>>& block::declarations() noexcept std::vector<declaration *>& block::declarations() noexcept
{ {
return m_declarations; return m_declarations;
} }
program::program(const struct position position, std::vector<std::unique_ptr<definition>>&& definitions, block::~block()
std::vector<std::unique_ptr<declaration>>&& declarations, {
std::unique_ptr<statement>&& body) for (auto definition : m_definitions)
: block(position, std::move(definitions), std::move(declarations), std::move(body)) {
delete definition;
}
for (auto declaration : m_declarations)
{
delete declaration;
}
delete m_body;
}
program::program(const struct position position, std::vector<definition *>&& definitions,
std::vector<declaration *>&& declarations,
statement *body)
: block(position, std::move(definitions), std::move(declarations), body)
{ {
} }
@ -358,8 +390,8 @@ namespace source
return m_name; return m_name;
} }
binary_expression::binary_expression(const struct position position, std::unique_ptr<expression>&& lhs, binary_expression::binary_expression(const struct position position, expression *lhs,
std::unique_ptr<expression>&& rhs, const unsigned char operation) expression *rhs, const unsigned char operation)
: expression(position), m_lhs(std::move(lhs)), m_rhs(std::move(rhs)) : expression(position), m_lhs(std::move(lhs)), m_rhs(std::move(rhs))
{ {
switch (operation) switch (operation)
@ -419,7 +451,13 @@ namespace source
return m_operator; return m_operator;
} }
unary_expression::unary_expression(const struct position position, std::unique_ptr<expression>&& operand, binary_expression::~binary_expression()
{
delete m_lhs;
delete m_rhs;
}
unary_expression::unary_expression(const struct position position, expression *operand,
const unsigned char operation) const unsigned char operation)
: expression(position), m_operand(std::move(operand)) : expression(position), m_operand(std::move(operand))
{ {
@ -451,6 +489,11 @@ namespace source
return this->m_operator; return this->m_operator;
} }
unary_expression::~unary_expression()
{
delete m_operand;
}
call_statement::call_statement(const struct position position, const std::string& name) call_statement::call_statement(const struct position position, const std::string& name)
: statement(position), m_name(name) : statement(position), m_name(name)
{ {
@ -466,11 +509,19 @@ namespace source
return m_name; return m_name;
} }
std::vector<std::unique_ptr<expression>>& call_statement::arguments() noexcept std::vector<expression *>& call_statement::arguments() noexcept
{ {
return m_arguments; return m_arguments;
} }
call_statement::~call_statement()
{
for (auto argument : m_arguments)
{
delete argument;
}
}
compound_statement::compound_statement(const struct position position) compound_statement::compound_statement(const struct position position)
: statement(position) : statement(position)
{ {
@ -481,19 +532,27 @@ namespace source
visitor->visit(this); visitor->visit(this);
} }
std::vector<std::unique_ptr<statement>>& compound_statement::statements() std::vector<statement *>& compound_statement::statements()
{ {
return m_statements; return m_statements;
} }
compound_statement::~compound_statement()
{
for (auto statement : m_statements)
{
delete statement;
}
}
void assign_statement::accept(parser_visitor *visitor) void assign_statement::accept(parser_visitor *visitor)
{ {
visitor->visit(this); visitor->visit(this);
} }
assign_statement::assign_statement(const struct position position, const std::string& lvalue, assign_statement::assign_statement(const struct position position, const std::string& lvalue,
std::unique_ptr<expression>&& rvalue) expression *rvalue)
: statement(position), m_lvalue(lvalue), m_rvalue(std::move(rvalue)) : statement(position), m_lvalue(lvalue), m_rvalue(rvalue)
{ {
} }
@ -507,10 +566,15 @@ namespace source
return *m_rvalue; return *m_rvalue;
} }
if_statement::if_statement(const struct position position, std::unique_ptr<expression>&& prerequisite, assign_statement::~assign_statement()
std::unique_ptr<statement>&& body, std::unique_ptr<statement>&& alternative) {
: statement(position), m_prerequisite(std::move(prerequisite)), m_body(std::move(body)), delete m_rvalue;
m_alternative(std::move(alternative)) }
if_statement::if_statement(const struct position position, expression *prerequisite,
statement *body, statement *alternative)
: statement(position), m_prerequisite(prerequisite), m_body(body),
m_alternative(alternative)
{ {
} }
@ -529,14 +593,25 @@ namespace source
return *m_body; return *m_body;
} }
std::unique_ptr<statement>& if_statement::alternative() statement *if_statement::alternative()
{ {
return m_alternative; return m_alternative;
} }
while_statement::while_statement(const struct position position, std::unique_ptr<expression>&& prerequisite, if_statement::~if_statement()
std::unique_ptr<statement>&& body) {
: statement(position), m_prerequisite(std::move(prerequisite)), m_body(std::move(body)) delete m_prerequisite;
delete m_body;
if (m_alternative != nullptr)
{
delete m_alternative;
}
}
while_statement::while_statement(const struct position position, expression *prerequisite,
statement *body)
: statement(position), m_prerequisite(prerequisite), m_body(body)
{ {
} }
@ -555,6 +630,12 @@ namespace source
return *m_body; return *m_body;
} }
while_statement::~while_statement()
{
delete m_prerequisite;
delete m_body;
}
const char *print_binary_operator(const binary_operator operation) const char *print_binary_operator(const binary_operator operation)
{ {
switch (operation) switch (operation)

View File

@ -73,44 +73,44 @@
%precedence THEN %precedence THEN
%precedence ELSE %precedence ELSE
%type <std::unique_ptr<elna::source::number_literal<std::int32_t>>> integer_literal; %type <elna::source::number_literal<std::int32_t> *> integer_literal;
%type <std::unique_ptr<elna::source::number_literal<double>>> float_literal; %type <elna::source::number_literal<double> *> float_literal;
%type <std::unique_ptr<elna::source::number_literal<bool>>> boolean_literal; %type <elna::source::number_literal<bool> *> boolean_literal;
%type <std::unique_ptr<elna::source::char_literal>> character_literal; %type <elna::source::char_literal *> character_literal;
%type <std::unique_ptr<elna::source::string_literal>> string_literal; %type <elna::source::string_literal *> string_literal;
%type <std::unique_ptr<elna::source::constant_definition>> constant_definition; %type <elna::source::constant_definition *> constant_definition;
%type <std::vector<std::unique_ptr<elna::source::constant_definition>>> constant_definition_part constant_definitions; %type <std::vector<elna::source::constant_definition *>> constant_definition_part constant_definitions;
%type <std::unique_ptr<elna::source::declaration>> variable_declaration; %type <elna::source::declaration *> variable_declaration;
%type <std::vector<std::unique_ptr<elna::source::declaration>>> variable_declarations variable_declaration_part %type <std::vector<elna::source::declaration *>> variable_declarations variable_declaration_part
formal_parameter_list; formal_parameter_list;
%type <std::unique_ptr<elna::source::basic_type_expression>> type_expression; %type <elna::source::basic_type_expression *> type_expression;
%type <std::unique_ptr<elna::source::expression>> expression pointer summand factor address comparand; %type <elna::source::expression *> expression pointer summand factor address comparand;
%type <std::vector<std::unique_ptr<elna::source::expression>>> expressions actual_parameter_list; %type <std::vector<elna::source::expression *>> expressions actual_parameter_list;
%type <std::unique_ptr<elna::source::variable_expression>> variable_expression; %type <elna::source::variable_expression *> variable_expression;
%type <std::unique_ptr<elna::source::compound_statement>> compound_statement; %type <elna::source::compound_statement *> compound_statement;
%type <std::unique_ptr<elna::source::assign_statement>> assign_statement; %type <elna::source::assign_statement *> assign_statement;
%type <std::unique_ptr<elna::source::call_statement>> call_statement; %type <elna::source::call_statement *> call_statement;
%type <std::unique_ptr<elna::source::while_statement>> while_statement; %type <elna::source::while_statement *> while_statement;
%type <std::unique_ptr<elna::source::if_statement>> if_statement; %type <elna::source::if_statement *> if_statement;
%type <std::unique_ptr<elna::source::statement>> statement; %type <elna::source::statement *> statement;
%type <std::vector<std::unique_ptr<elna::source::statement>>> statements optional_statements; %type <std::vector<elna::source::statement *>> statements optional_statements;
%type <std::unique_ptr<elna::source::procedure_definition>> procedure_definition; %type <elna::source::procedure_definition *> procedure_definition;
%type <std::vector<std::unique_ptr<elna::source::procedure_definition>>> procedure_definitions %type <std::vector<elna::source::procedure_definition *>> procedure_definitions
procedure_definition_part; procedure_definition_part;
%type <std::unique_ptr<elna::source::block>> block; %type <elna::source::block *> block;
%% %%
program: constant_definition_part procedure_definition_part variable_declaration_part statement DOT program: constant_definition_part procedure_definition_part variable_declaration_part statement DOT
{ {
std::vector<std::unique_ptr<elna::source::definition>> definitions($1.size() + $2.size()); std::vector<elna::source::definition *> definitions($1.size() + $2.size());
std::vector<std::unique_ptr<elna::source::definition>>::iterator definition = definitions.begin(); std::vector<elna::source::definition *>::iterator definition = definitions.begin();
for (auto& constant : $1) for (auto& constant : $1)
{ {
*definition++ = std::move(constant); *definition++ = constant;
} }
for (auto& procedure : $2) for (auto& procedure : $2)
{ {
*definition++ = std::move(procedure); *definition++ = procedure;
} }
driver.tree = std::make_unique<elna::source::program>(elna::source::position{}, driver.tree = std::make_unique<elna::source::program>(elna::source::position{},
std::move(definitions), std::move($3), std::move(definitions), std::move($3),
@ -118,21 +118,21 @@ program: constant_definition_part procedure_definition_part variable_declaration
} }
block: constant_definition_part variable_declaration_part statement block: constant_definition_part variable_declaration_part statement
{ {
std::vector<std::unique_ptr<elna::source::definition>> definitions($1.size()); std::vector<elna::source::definition *> definitions($1.size());
std::vector<std::unique_ptr<elna::source::definition>>::iterator definition = definitions.begin(); std::vector<elna::source::definition *>::iterator definition = definitions.begin();
for (auto& constant : $1) for (auto& constant : $1)
{ {
*definition++ = std::move(constant); *definition++ = constant;
} }
$$ = std::make_unique<elna::source::block>(elna::source::position{}, $$ = new elna::source::block(elna::source::position{},
std::move(definitions), std::move($2), std::move($3)); std::move(definitions), std::move($2), std::move($3));
}; };
procedure_definition: procedure_definition:
PROCEDURE IDENTIFIER formal_parameter_list SEMICOLON block SEMICOLON PROCEDURE IDENTIFIER formal_parameter_list SEMICOLON block SEMICOLON
{ {
$$ = std::make_unique<elna::source::procedure_definition>(elna::source::position{}, $$ = new elna::source::procedure_definition(elna::source::position{},
std::move($2), std::move($5)); std::move($2), $5);
std::swap($$->parameters(), $3); std::swap($$->parameters(), $3);
}; };
procedure_definitions: procedure_definitions:
@ -147,172 +147,172 @@ procedure_definition_part:
| procedure_definitions { std::swap($$, $1); } | procedure_definitions { std::swap($$, $1); }
integer_literal: INTEGER integer_literal: INTEGER
{ {
$$ = std::make_unique<elna::source::number_literal<std::int32_t>>(elna::source::make_position(@1), $1); $$ = new elna::source::number_literal<std::int32_t>(elna::source::make_position(@1), $1);
}; };
float_literal: FLOAT float_literal: FLOAT
{ {
$$ = std::make_unique<elna::source::number_literal<double>>(elna::source::make_position(@1), $1); $$ = new elna::source::number_literal<double>(elna::source::make_position(@1), $1);
}; };
character_literal: CHARACTER character_literal: CHARACTER
{ {
$$ = std::make_unique<elna::source::char_literal>(elna::source::make_position(@1), $1.at(0)); $$ = new elna::source::char_literal(elna::source::make_position(@1), $1.at(0));
}; };
string_literal: STRING string_literal: STRING
{ {
$$ = std::make_unique<elna::source::string_literal>(elna::source::make_position(@1), $1); $$ = new elna::source::string_literal(elna::source::make_position(@1), $1);
}; };
boolean_literal: BOOLEAN boolean_literal: BOOLEAN
{ {
$$ = std::make_unique<elna::source::number_literal<bool>>(elna::source::make_position(@1), $1); $$ = new elna::source::number_literal<bool>(elna::source::make_position(@1), $1);
}; };
compound_statement: BEGIN_BLOCK optional_statements END_BLOCK compound_statement: BEGIN_BLOCK optional_statements END_BLOCK
{ {
$$ = std::make_unique<elna::source::compound_statement>(elna::source::make_position(@1)); $$ = new elna::source::compound_statement(elna::source::make_position(@1));
std::swap($$->statements(), $2); std::swap($$->statements(), $2);
} }
assign_statement: IDENTIFIER ASSIGNMENT expression assign_statement: IDENTIFIER ASSIGNMENT expression
{ {
$$ = std::make_unique<elna::source::assign_statement>(elna::source::make_position(@1), $1, std::move($3)); $$ = new elna::source::assign_statement(elna::source::make_position(@1), $1, $3);
} }
call_statement: IDENTIFIER actual_parameter_list call_statement: IDENTIFIER actual_parameter_list
{ {
$$ = std::make_unique<elna::source::call_statement>(elna::source::make_position(@1), $1); $$ = new elna::source::call_statement(elna::source::make_position(@1), $1);
std::swap($$->arguments(), $2); std::swap($$->arguments(), $2);
} }
while_statement: WHILE expression DO statement while_statement: WHILE expression DO statement
{ {
$$ = std::make_unique<elna::source::while_statement>(elna::source::make_position(@1), $$ = new elna::source::while_statement(elna::source::make_position(@1),
std::move($2), std::move($4)); $2, $4);
} }
if_statement: if_statement:
IF expression THEN statement IF expression THEN statement
{ {
$$ = std::make_unique<elna::source::if_statement>(elna::source::make_position(@1), $$ = new elna::source::if_statement(elna::source::make_position(@1),
std::move($2), std::move($4)); $2, $4);
} }
| IF expression THEN statement ELSE statement | IF expression THEN statement ELSE statement
{ {
$$ = std::make_unique<elna::source::if_statement>(elna::source::make_position(@1), $$ = new elna::source::if_statement(elna::source::make_position(@1),
std::move($2), std::move($4), std::move($6)); $2, $4, $6);
} }
pointer: pointer:
integer_literal { $$ = std::move($1); } integer_literal { $$ = $1; }
| float_literal { $$ = std::move($1); } | float_literal { $$ = $1; }
| boolean_literal { $$ = std::move($1); } | boolean_literal { $$ = $1; }
| character_literal { $$ = std::move($1); } | character_literal { $$ = $1; }
| string_literal { $$ = std::move($1); } | string_literal { $$ = $1; }
| variable_expression { $$ = std::move($1); } | variable_expression { $$ = $1; }
| LEFT_PAREN expression RIGHT_PAREN { $$ = std::move($2); } | LEFT_PAREN expression RIGHT_PAREN { $$ = std::move($2); }
summand: summand:
factor { $$ = std::move($1); } factor { $$ = std::move($1); }
| factor MULTIPLICATION factor | factor MULTIPLICATION factor
{ {
$$ = std::make_unique<elna::source::binary_expression>(elna::source::make_position(@1), $$ = new elna::source::binary_expression(elna::source::make_position(@1),
std::move($1), std::move($3), '*'); $1, $3, '*');
} }
| factor DIVISION factor | factor DIVISION factor
{ {
$$ = std::make_unique<elna::source::binary_expression>(elna::source::make_position(@1), $$ = new elna::source::binary_expression(elna::source::make_position(@1),
std::move($1), std::move($3), '/'); $1, $3, '/');
} }
address: address:
pointer HAT pointer HAT
{ {
$$ = std::make_unique<elna::source::unary_expression>(elna::source::make_position(@1), $$ = new elna::source::unary_expression(elna::source::make_position(@1),
std::move($1), '^'); $1, '^');
} }
| pointer { $$ = std::move($1); } | pointer { $$ = $1; }
factor: factor:
AT address AT address
{ {
$$ = std::make_unique<elna::source::unary_expression>(elna::source::make_position(@1), $$ = new elna::source::unary_expression(elna::source::make_position(@1),
std::move($2), '@'); $2, '@');
} }
| address { $$ = std::move($1); } | address { $$ = $1; }
comparand: comparand:
summand PLUS summand summand PLUS summand
{ {
$$ = std::make_unique<elna::source::binary_expression>(elna::source::make_position(@1), $$ = new elna::source::binary_expression(elna::source::make_position(@1),
std::move($1), std::move($3), '+'); $1, $3, '+');
} }
| summand MINUS summand | summand MINUS summand
{ {
$$ = std::make_unique<elna::source::binary_expression>(elna::source::make_position(@1), $$ = new elna::source::binary_expression(elna::source::make_position(@1),
std::move($1), std::move($3), '-'); $1, $3, '-');
} }
| summand { $$ = std::move($1); } | summand { $$ = std::move($1); }
expression: expression:
comparand EQUALS comparand comparand EQUALS comparand
{ {
$$ = std::make_unique<elna::source::binary_expression>(elna::source::make_position(@1), $$ = new elna::source::binary_expression(elna::source::make_position(@1),
std::move($1), std::move($3), '='); $1, $3, '=');
} }
| comparand NOT_EQUAL comparand | comparand NOT_EQUAL comparand
{ {
$$ = std::make_unique<elna::source::binary_expression>(elna::source::make_position(@1), $$ = new elna::source::binary_expression(elna::source::make_position(@1),
std::move($1), std::move($3), 'n'); $1, $3, 'n');
} }
| comparand LESS_THAN comparand | comparand LESS_THAN comparand
{ {
$$ = std::make_unique<elna::source::binary_expression>(elna::source::make_position(@1), $$ = new elna::source::binary_expression(elna::source::make_position(@1),
std::move($1), std::move($3), '<'); $1, $3, '<');
} }
| comparand GREATER_THAN comparand | comparand GREATER_THAN comparand
{ {
$$ = std::make_unique<elna::source::binary_expression>(elna::source::make_position(@1), $$ = new elna::source::binary_expression(elna::source::make_position(@1),
std::move($1), std::move($3), '>'); $1, $3, '>');
} }
| comparand LESS_EQUAL comparand | comparand LESS_EQUAL comparand
{ {
$$ = std::make_unique<elna::source::binary_expression>(elna::source::make_position(@1), $$ = new elna::source::binary_expression(elna::source::make_position(@1),
std::move($1), std::move($3), '<'); $1, $3, '<');
} }
| comparand GREATER_EQUAL comparand | comparand GREATER_EQUAL comparand
{ {
$$ = std::make_unique<elna::source::binary_expression>(elna::source::make_position(@1), $$ = new elna::source::binary_expression(elna::source::make_position(@1),
std::move($1), std::move($3), '>'); $1, $3, '>');
} }
| comparand { $$ = std::move($1); } | comparand { $$ = std::move($1); }
expressions: expressions:
expression COMMA expressions expression COMMA expressions
{ {
std::swap($$, $3); std::swap($$, $3);
$$.emplace($$.cbegin(), std::move($1)); $$.emplace($$.cbegin(), $1);
} }
| expression { $$.emplace_back(std::move($1)); } | expression { $$.emplace_back(std::move($1)); }
variable_expression: IDENTIFIER variable_expression: IDENTIFIER
{ $$ = std::make_unique<elna::source::variable_expression>(elna::source::make_position(@1), $1); } { $$ = new elna::source::variable_expression(elna::source::make_position(@1), $1); }
statement: statement:
compound_statement { $$ = std::move($1); } compound_statement { $$ = $1; }
| assign_statement { $$ = std::move($1); } | assign_statement { $$ = $1; }
| call_statement { $$ = std::move($1); } | call_statement { $$ = $1; }
| while_statement { $$ = std::move($1); } | while_statement { $$ = $1; }
| if_statement { $$ = std::move($1); } | if_statement { $$ = $1; }
statements: statements:
statement SEMICOLON statements statement SEMICOLON statements
{ {
std::swap($$, $3); std::swap($$, $3);
$$.emplace($$.cbegin(), std::move($1)); $$.emplace($$.cbegin(), std::move($1));
} }
| statement { $$.emplace_back(std::move($1)); } | statement { $$.emplace_back($1); }
optional_statements: optional_statements:
statements { std::swap($$, $1); } statements { std::swap($$, $1); }
| /* no statements */ {} | /* no statements */ {}
type_expression: type_expression:
IDENTIFIER IDENTIFIER
{ {
$$ = std::make_unique<elna::source::basic_type_expression>(elna::source::make_position(@1), $1); $$ = new elna::source::basic_type_expression(elna::source::make_position(@1), $1);
} }
variable_declaration: IDENTIFIER COLON type_expression variable_declaration: IDENTIFIER COLON type_expression
{ {
$$ = std::make_unique<elna::source::declaration>(elna::source::make_position(@1), $$ = new elna::source::declaration(elna::source::make_position(@1),
$1, std::move($3)); $1, $3);
}; };
variable_declarations: variable_declarations:
variable_declaration COMMA variable_declarations variable_declaration COMMA variable_declarations
{ {
std::swap($$, $3); std::swap($$, $3);
$$.emplace($$.cbegin(), std::move($1)); $$.emplace($$.cbegin(), $1);
} }
| variable_declaration { $$.emplace_back(std::move($1)); } | variable_declaration { $$.emplace_back(std::move($1)); }
variable_declaration_part: variable_declaration_part:
@ -320,8 +320,8 @@ variable_declaration_part:
| VAR variable_declarations SEMICOLON { std::swap($$, $2); } | VAR variable_declarations SEMICOLON { std::swap($$, $2); }
constant_definition: IDENTIFIER EQUALS integer_literal constant_definition: IDENTIFIER EQUALS integer_literal
{ {
$$ = std::make_unique<elna::source::constant_definition>(elna::source::make_position(@1), $$ = new elna::source::constant_definition(elna::source::make_position(@1),
$1, std::move($3)); $1, $3);
}; };
constant_definitions: constant_definitions:
constant_definition COMMA constant_definitions constant_definition COMMA constant_definitions