End while and if statements with the end token
This commit is contained in:
parent
ef667e3ace
commit
e95be9626f
18
README.md
18
README.md
@ -34,7 +34,7 @@ program = [ "type" type_definitions ";" ]
|
|||||||
[ constant_part ]
|
[ constant_part ]
|
||||||
{ procedure_definition }
|
{ procedure_definition }
|
||||||
[ variable_part ]
|
[ variable_part ]
|
||||||
compound_statement ".";
|
"begin" [ statement_list ] "end" ".";
|
||||||
|
|
||||||
procedure_definition = "proc" ident formal_parameter_list ";" ( block | "extern" ) ";";
|
procedure_definition = "proc" ident formal_parameter_list ";" ( block | "extern" ) ";";
|
||||||
|
|
||||||
@ -45,14 +45,18 @@ block = [ constant_part ]
|
|||||||
constant_part = "const" ident "=" integer { "," ident "=" integer } ";";
|
constant_part = "const" ident "=" integer { "," ident "=" integer } ";";
|
||||||
variable_part = "var" variable_declarations ";";
|
variable_part = "var" variable_declarations ";";
|
||||||
|
|
||||||
statement = compound_statement
|
statement = ident ":=" expression
|
||||||
| ident ":=" expression
|
|
||||||
| ident actual_parameter_list
|
| ident actual_parameter_list
|
||||||
| "while" condition "do" statement
|
| while_do
|
||||||
| "if" expression "then" statement [ else statement ];
|
| if_then_else;
|
||||||
|
|
||||||
|
|
||||||
|
while_do = "while" condition "do" [ statement_list ] "end";
|
||||||
|
if_then_else = "if" expression
|
||||||
|
"then" [ statement_list ]
|
||||||
|
[ else statement_list ] "end";
|
||||||
|
|
||||||
statement_list = statement {";" statement };
|
statement_list = statement {";" statement };
|
||||||
compound_statement = "begin" [ statement_list ] "end";
|
|
||||||
|
|
||||||
condition = "odd" expression |
|
condition = "odd" expression |
|
||||||
expression ("="|"#"|"<"|"<="|">"|">=") expression;
|
expression ("="|"#"|"<"|"<="|">"|">=") expression;
|
||||||
@ -86,7 +90,7 @@ variable_declarations = variable_declaration { ";" variable_declaration };
|
|||||||
variable_declaration = ident ":" type_expression;
|
variable_declaration = ident ":" type_expression;
|
||||||
|
|
||||||
type_expression = "array" integer "of" type_expression
|
type_expression = "array" integer "of" type_expression
|
||||||
| "^" type_expression
|
| "pointer" "to" type_expression
|
||||||
| "record" field_list "end"
|
| "record" field_list "end"
|
||||||
| ident;
|
| ident;
|
||||||
|
|
||||||
|
@ -443,13 +443,11 @@ namespace source
|
|||||||
|
|
||||||
class compound_statement : public statement
|
class compound_statement : public statement
|
||||||
{
|
{
|
||||||
std::vector<statement *> m_statements;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit compound_statement(const struct position position);
|
std::vector<statement *> statements;
|
||||||
virtual void accept(parser_visitor *visitor) override;
|
|
||||||
|
|
||||||
std::vector<statement *>& statements();
|
compound_statement(const struct position position, std::vector<statement *>&& statements);
|
||||||
|
virtual void accept(parser_visitor *visitor) override;
|
||||||
|
|
||||||
virtual ~compound_statement() override;
|
virtual ~compound_statement() override;
|
||||||
};
|
};
|
||||||
@ -556,8 +554,8 @@ namespace source
|
|||||||
class if_statement : public statement
|
class if_statement : public statement
|
||||||
{
|
{
|
||||||
expression *m_prerequisite;
|
expression *m_prerequisite;
|
||||||
statement *m_body;
|
compound_statement *m_body;
|
||||||
statement *m_alternative;
|
compound_statement *m_alternative;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -567,12 +565,12 @@ namespace source
|
|||||||
* \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, expression *prerequisite,
|
if_statement(const struct position position, expression *prerequisite,
|
||||||
statement *body, statement *alternative = nullptr);
|
compound_statement *body, compound_statement *alternative = nullptr);
|
||||||
virtual void accept(parser_visitor *visitor) override;
|
virtual void accept(parser_visitor *visitor) override;
|
||||||
|
|
||||||
expression& prerequisite();
|
expression& prerequisite();
|
||||||
statement& body();
|
compound_statement& body();
|
||||||
statement *alternative();
|
compound_statement *alternative();
|
||||||
|
|
||||||
virtual ~if_statement() override;
|
virtual ~if_statement() override;
|
||||||
};
|
};
|
||||||
@ -583,7 +581,7 @@ namespace source
|
|||||||
class while_statement : public statement
|
class while_statement : public statement
|
||||||
{
|
{
|
||||||
expression *m_prerequisite;
|
expression *m_prerequisite;
|
||||||
statement *m_body;
|
compound_statement *m_body;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@ -592,11 +590,11 @@ namespace source
|
|||||||
* \param body Statement executed while the condition is met.
|
* \param body Statement executed while the condition is met.
|
||||||
*/
|
*/
|
||||||
while_statement(const struct position position, expression *prerequisite,
|
while_statement(const struct position position, expression *prerequisite,
|
||||||
statement *body);
|
compound_statement *body);
|
||||||
virtual void accept(parser_visitor *visitor) override;
|
virtual void accept(parser_visitor *visitor) override;
|
||||||
|
|
||||||
expression& prerequisite();
|
expression& prerequisite();
|
||||||
statement& body();
|
compound_statement& body();
|
||||||
|
|
||||||
virtual ~while_statement() override;
|
virtual ~while_statement() override;
|
||||||
};
|
};
|
||||||
|
@ -43,7 +43,7 @@ namespace source
|
|||||||
|
|
||||||
void empty_visitor::visit(compound_statement *statement)
|
void empty_visitor::visit(compound_statement *statement)
|
||||||
{
|
{
|
||||||
for (auto& nested_statement : statement->statements())
|
for (const auto nested_statement : statement->statements)
|
||||||
{
|
{
|
||||||
nested_statement->accept(this);
|
nested_statement->accept(this);
|
||||||
}
|
}
|
||||||
@ -766,8 +766,8 @@ namespace source
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
compound_statement::compound_statement(const struct position position)
|
compound_statement::compound_statement(const struct position position, std::vector<statement *>&& statements)
|
||||||
: statement(position)
|
: statement(position), statements(std::move(statements))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -776,14 +776,9 @@ namespace source
|
|||||||
visitor->visit(this);
|
visitor->visit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<statement *>& compound_statement::statements()
|
|
||||||
{
|
|
||||||
return m_statements;
|
|
||||||
}
|
|
||||||
|
|
||||||
compound_statement::~compound_statement()
|
compound_statement::~compound_statement()
|
||||||
{
|
{
|
||||||
for (auto statement : m_statements)
|
for (auto statement : statements)
|
||||||
{
|
{
|
||||||
delete statement;
|
delete statement;
|
||||||
}
|
}
|
||||||
@ -836,7 +831,7 @@ namespace source
|
|||||||
}
|
}
|
||||||
|
|
||||||
if_statement::if_statement(const struct position position, expression *prerequisite,
|
if_statement::if_statement(const struct position position, expression *prerequisite,
|
||||||
statement *body, statement *alternative)
|
compound_statement *body, compound_statement *alternative)
|
||||||
: statement(position), m_prerequisite(prerequisite), m_body(body),
|
: statement(position), m_prerequisite(prerequisite), m_body(body),
|
||||||
m_alternative(alternative)
|
m_alternative(alternative)
|
||||||
{
|
{
|
||||||
@ -852,12 +847,12 @@ namespace source
|
|||||||
return *m_prerequisite;
|
return *m_prerequisite;
|
||||||
}
|
}
|
||||||
|
|
||||||
statement& if_statement::body()
|
compound_statement& if_statement::body()
|
||||||
{
|
{
|
||||||
return *m_body;
|
return *m_body;
|
||||||
}
|
}
|
||||||
|
|
||||||
statement *if_statement::alternative()
|
compound_statement *if_statement::alternative()
|
||||||
{
|
{
|
||||||
return m_alternative;
|
return m_alternative;
|
||||||
}
|
}
|
||||||
@ -874,7 +869,7 @@ namespace source
|
|||||||
}
|
}
|
||||||
|
|
||||||
while_statement::while_statement(const struct position position, expression *prerequisite,
|
while_statement::while_statement(const struct position position, expression *prerequisite,
|
||||||
statement *body)
|
compound_statement *body)
|
||||||
: statement(position), m_prerequisite(prerequisite), m_body(body)
|
: statement(position), m_prerequisite(prerequisite), m_body(body)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -889,7 +884,7 @@ namespace source
|
|||||||
return *m_prerequisite;
|
return *m_prerequisite;
|
||||||
}
|
}
|
||||||
|
|
||||||
statement& while_statement::body()
|
compound_statement& while_statement::body()
|
||||||
{
|
{
|
||||||
return *m_body;
|
return *m_body;
|
||||||
}
|
}
|
||||||
|
@ -76,6 +76,12 @@ type {
|
|||||||
record {
|
record {
|
||||||
return yy::parser::make_RECORD(this->location);
|
return yy::parser::make_RECORD(this->location);
|
||||||
}
|
}
|
||||||
|
pointer {
|
||||||
|
return yy::parser::make_POINTER(this->location);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
return yy::parser::make_TO(this->location);
|
||||||
|
}
|
||||||
true {
|
true {
|
||||||
return yy::parser::make_BOOLEAN(true, this->location);
|
return yy::parser::make_BOOLEAN(true, this->location);
|
||||||
}
|
}
|
||||||
|
@ -62,8 +62,8 @@
|
|||||||
%token <std::string> CHARACTER "character"
|
%token <std::string> CHARACTER "character"
|
||||||
%token <std::string> STRING "string"
|
%token <std::string> STRING "string"
|
||||||
%token <bool> BOOLEAN
|
%token <bool> BOOLEAN
|
||||||
%token IF WHILE DO
|
%token IF WHILE DO THEN ELSE
|
||||||
%token CONST VAR PROCEDURE ARRAY OF TYPE RECORD
|
%token CONST VAR PROCEDURE ARRAY OF TYPE RECORD POINTER TO
|
||||||
%token BEGIN_BLOCK END_BLOCK EXTERN
|
%token BEGIN_BLOCK END_BLOCK EXTERN
|
||||||
%token LEFT_PAREN RIGHT_PAREN LEFT_SQUARE RIGHT_SQUARE SEMICOLON DOT COMMA
|
%token LEFT_PAREN RIGHT_PAREN LEFT_SQUARE RIGHT_SQUARE SEMICOLON DOT COMMA
|
||||||
%token AND OR NOT
|
%token AND OR NOT
|
||||||
@ -71,9 +71,6 @@
|
|||||||
%token PLUS MINUS MULTIPLICATION DIVISION
|
%token PLUS MINUS MULTIPLICATION DIVISION
|
||||||
%token ASSIGNMENT COLON HAT AT
|
%token ASSIGNMENT COLON HAT AT
|
||||||
|
|
||||||
%precedence THEN
|
|
||||||
%precedence ELSE
|
|
||||||
|
|
||||||
%type <elna::source::literal *> literal;
|
%type <elna::source::literal *> literal;
|
||||||
%type <elna::source::constant_definition *> constant_definition;
|
%type <elna::source::constant_definition *> constant_definition;
|
||||||
%type <std::vector<elna::source::constant_definition *>> constant_part constant_definitions;
|
%type <std::vector<elna::source::constant_definition *>> constant_part constant_definitions;
|
||||||
@ -84,7 +81,6 @@
|
|||||||
%type <elna::source::expression *> expression pointer summand factor comparand logical_operand;
|
%type <elna::source::expression *> expression pointer summand factor comparand logical_operand;
|
||||||
%type <std::vector<elna::source::expression *>> expressions actual_parameter_list;
|
%type <std::vector<elna::source::expression *>> expressions actual_parameter_list;
|
||||||
%type <elna::source::designator_expression *> designator_expression;
|
%type <elna::source::designator_expression *> designator_expression;
|
||||||
%type <elna::source::compound_statement *> compound_statement;
|
|
||||||
%type <elna::source::assign_statement *> assign_statement;
|
%type <elna::source::assign_statement *> assign_statement;
|
||||||
%type <elna::source::call_statement *> call_statement;
|
%type <elna::source::call_statement *> call_statement;
|
||||||
%type <elna::source::while_statement *> while_statement;
|
%type <elna::source::while_statement *> while_statement;
|
||||||
@ -167,11 +163,6 @@ procedure_definitions:
|
|||||||
procedure_part:
|
procedure_part:
|
||||||
/* no procedure definitions */ {}
|
/* no procedure definitions */ {}
|
||||||
| procedure_definitions { std::swap($$, $1); }
|
| procedure_definitions { std::swap($$, $1); }
|
||||||
compound_statement: BEGIN_BLOCK optional_statements END_BLOCK
|
|
||||||
{
|
|
||||||
$$ = new elna::source::compound_statement(elna::source::make_position(@1));
|
|
||||||
std::swap($$->statements(), $2);
|
|
||||||
}
|
|
||||||
assign_statement: designator_expression ASSIGNMENT expression
|
assign_statement: designator_expression ASSIGNMENT expression
|
||||||
{
|
{
|
||||||
$$ = new elna::source::assign_statement(elna::source::make_position(@1), $1, $3);
|
$$ = new elna::source::assign_statement(elna::source::make_position(@1), $1, $3);
|
||||||
@ -181,21 +172,22 @@ call_statement: IDENTIFIER actual_parameter_list
|
|||||||
$$ = new 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 optional_statements END_BLOCK
|
||||||
{
|
{
|
||||||
$$ = new elna::source::while_statement(elna::source::make_position(@1),
|
auto body = new elna::source::compound_statement(elna::source::make_position(@3), std::move($4));
|
||||||
$2, $4);
|
$$ = new elna::source::while_statement(elna::source::make_position(@1), $2, body);
|
||||||
}
|
}
|
||||||
if_statement:
|
if_statement:
|
||||||
IF expression THEN statement
|
IF expression THEN optional_statements END_BLOCK
|
||||||
{
|
{
|
||||||
$$ = new elna::source::if_statement(elna::source::make_position(@1),
|
auto then = new elna::source::compound_statement(elna::source::make_position(@3), std::move($4));
|
||||||
$2, $4);
|
$$ = new elna::source::if_statement(elna::source::make_position(@1), $2, then);
|
||||||
}
|
}
|
||||||
| IF expression THEN statement ELSE statement
|
| IF expression THEN optional_statements ELSE optional_statements END_BLOCK
|
||||||
{
|
{
|
||||||
$$ = new elna::source::if_statement(elna::source::make_position(@1),
|
auto then = new elna::source::compound_statement(elna::source::make_position(@3), std::move($4));
|
||||||
$2, $4, $6);
|
auto _else = new elna::source::compound_statement(elna::source::make_position(@5), std::move($6));
|
||||||
|
$$ = new elna::source::if_statement(elna::source::make_position(@1), $2, then, _else);
|
||||||
}
|
}
|
||||||
literal:
|
literal:
|
||||||
INTEGER
|
INTEGER
|
||||||
@ -315,8 +307,7 @@ designator_expression:
|
|||||||
$$ = new 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 { $$ = $1; }
|
assign_statement { $$ = $1; }
|
||||||
| assign_statement { $$ = $1; }
|
|
||||||
| call_statement { $$ = $1; }
|
| call_statement { $$ = $1; }
|
||||||
| while_statement { $$ = $1; }
|
| while_statement { $$ = $1; }
|
||||||
| if_statement { $$ = $1; }
|
| if_statement { $$ = $1; }
|
||||||
@ -344,9 +335,9 @@ type_expression:
|
|||||||
{
|
{
|
||||||
$$ = new elna::source::array_type_expression(elna::source::make_position(@1), $4, $2);
|
$$ = new elna::source::array_type_expression(elna::source::make_position(@1), $4, $2);
|
||||||
}
|
}
|
||||||
| HAT type_expression
|
| POINTER TO type_expression
|
||||||
{
|
{
|
||||||
$$ = new elna::source::pointer_type_expression(elna::source::make_position(@1), $2);
|
$$ = new elna::source::pointer_type_expression(elna::source::make_position(@1), $3);
|
||||||
}
|
}
|
||||||
| RECORD field_list END_BLOCK
|
| RECORD field_list END_BLOCK
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user