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

View File

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

View File

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