diff options
Diffstat (limited to 'boot/parser.yy')
| -rw-r--r-- | boot/parser.yy | 210 |
1 files changed, 101 insertions, 109 deletions
diff --git a/boot/parser.yy b/boot/parser.yy index 4ef2de4..ef887ab 100644 --- a/boot/parser.yy +++ b/boot/parser.yy @@ -60,6 +60,10 @@ along with GCC; see the file COPYING3. If not see %define api.token.raw %define api.token.constructor %define api.value.type variant +%define api.value.automove +%define parse.error detailed +%define parse.lac full +%expect 0 // Assert zero shift/reduce conflicts. %parse-param {elna::boot::lexer& lexer} %param {elna::boot::driver& driver} @@ -76,7 +80,7 @@ along with GCC; see the file COPYING3. If not see %token <std::string> TRAIT %token <std::int32_t> INTEGER %token <std::uint32_t> WORD -%token <float> FLOAT +%token <double> FLOAT %token <std::string> CHARACTER %token <std::string> STRING %token <bool> BOOLEAN @@ -162,78 +166,70 @@ along with GCC; see the file COPYING3. If not see program: import_part constant_part type_part variable_part procedure_part statement_part return_statement "end" "." { - boot::unit *tree = new boot::unit(boot::make_position(@1), - std::move($1), std::move($2), std::move($3), std::move($4), std::move($5), - std::move($6), $7); + boot::unit *tree = new boot::unit(boot::make_position(@$), $1, $2, $3, $4, $5, $6, $7); driver.tree.reset(tree); } procedure_body: constant_part variable_part statement_part return_statement "end" - { - $$ = std::make_unique<boot::procedure_body>(std::move($1), std::move($2), std::move($3), $4); - } + { $$ = std::make_unique<boot::procedure_body>($1, $2, $3, $4); } statement_part: /* no statements */ {} - | "begin" statements { std::swap($$, $2); } + | "begin" statements { $$ = $2; } identifier_definition: IDENTIFIER "*" { $$ = boot::identifier_definition{ $1, true }; } | IDENTIFIER { $$ = boot::identifier_definition{ $1, false }; } identifier_definitions: identifier_definition "," identifier_definitions { - std::swap($$, $3); + $$ = $3; $$.emplace($$.cbegin(), $1); } - | identifier_definition { $$.emplace_back(std::move($1)); } + | identifier_definition { $$.emplace_back($1); } return_declaration: /* proper procedure */ {} | ":" "!" { $$ = boot::procedure_type_expression::return_t(std::monostate{}); } | ":" type_expression { $$ = boot::procedure_type_expression::return_t($2); } procedure_heading: "(" optional_fields ")" return_declaration - { - $$ = new boot::procedure_type_expression(boot::make_position(@1), std::move($2), std::move($4)); - } + { $$ = new boot::procedure_type_expression(boot::make_position(@$), $2, $4); } procedure_declaration: "proc" identifier_definition procedure_heading procedure_body { - $$ = new boot::procedure_declaration(boot::make_position(@1), std::move($2), $3, - std::move(*$4)); + $$ = new boot::procedure_declaration(boot::make_position(@$), $2, $3, std::move(*$4)); } | "proc" identifier_definition procedure_heading "extern" { - $$ = new boot::procedure_declaration(boot::make_position(@1), std::move($2), $3); + $$ = new boot::procedure_declaration(boot::make_position(@$), $2, $3); } procedure_part: /* no procedure declarations */ {} | procedure_declaration procedure_part { - std::swap($$, $2); - $$.emplace($$.cbegin(), std::move($1)); + $$ = $2; + $$.emplace($$.cbegin(), $1); } call_expression: designator_expression actual_parameter_list { - $$ = new boot::procedure_call(boot::make_position(@1), $1); - std::swap($$->arguments, $2); + $$ = new boot::procedure_call(boot::make_position(@$), $1, $2); } cast_expression: "cast" "(" expression ":" type_expression ")" - { $$ = new boot::cast_expression(boot::make_position(@1), $5, $3); } + { $$ = new boot::cast_expression(boot::make_position(@$), $5, $3); } elsif_do_statements: "elsif" expression "do" statements elsif_do_statements { - boot::conditional_statements *branch = new boot::conditional_statements($2, std::move($4)); - std::swap($5, $$); + boot::conditional_statements *branch = new boot::conditional_statements($2, $4); + $$ = $5; $$.emplace($$.begin(), branch); } | /* no branches */ {} else_statements: - "else" statements { $$ = new std::vector<boot::statement *>(std::move($2)); } + "else" statements { $$ = new std::vector<boot::statement *>($2); } | { $$ = nullptr; } elsif_then_statements: "elsif" expression "then" statements elsif_then_statements { - boot::conditional_statements *branch = new boot::conditional_statements($2, std::move($4)); - std::swap($5, $$); + boot::conditional_statements *branch = new boot::conditional_statements($2, $4); + $$ = $5; $$.emplace($$.begin(), branch); } | /* no branches */ {} @@ -241,18 +237,17 @@ return_statement: "return" expression { $$ = $2; } | /* no return statement */ { $$ = nullptr; } literal: - INTEGER { $$ = new boot::literal<std::int32_t>(boot::make_position(@1), $1); } - | WORD { $$ = new boot::literal<std::uint32_t>(boot::make_position(@1), $1); } - | FLOAT { $$ = new boot::literal<double>(boot::make_position(@1), $1); } - | BOOLEAN { $$ = new boot::literal<bool>(boot::make_position(@1), $1); } - | CHARACTER { $$ = new boot::literal<unsigned char>(boot::make_position(@1), $1.at(0)); } - | "nil" { $$ = new boot::literal<std::nullptr_t>(boot::make_position(@1), nullptr); } - | STRING { $$ = new boot::literal<std::string>(boot::make_position(@1), $1); } + INTEGER { $$ = new boot::literal<std::int32_t>(boot::make_position(@$), $1); } + | WORD { $$ = new boot::literal<std::uint32_t>(boot::make_position(@$), $1); } + | FLOAT { $$ = new boot::literal<double>(boot::make_position(@$), $1); } + | BOOLEAN { $$ = new boot::literal<bool>(boot::make_position(@$), $1); } + | CHARACTER { $$ = new boot::literal<unsigned char>(boot::make_position(@$), $1.at(0)); } + | "nil" { $$ = new boot::literal<std::nullptr_t>(boot::make_position(@$), nullptr); } + | STRING { $$ = new boot::literal<std::string>(boot::make_position(@$), $1); } traits_expression: TRAIT "(" type_expressions ")" { - $$ = new boot::traits_expression(boot::make_position(@1), $1); - std::swap($3, $$->parameters); + $$ = new boot::traits_expression(boot::make_position(@$), $1, $3); } simple_expression: literal { $$ = $1; } @@ -263,11 +258,11 @@ simple_expression: | "(" expression ")" { $$ = $2; } | IDENTIFIER "{" field_initializers "}" { - $$ = new boot::record_constructor_expression(boot::make_position(@1), std::move($1), std::move($3)); + $$ = new boot::record_constructor_expression(boot::make_position(@$), $1, $3); } | "[" INTEGER "]" type_expression "{" expressions "}" { - $$ = new boot::array_constructor_expression(boot::make_position(@1), $2, $4, std::move($6)); + $$ = new boot::array_constructor_expression(boot::make_position(@$), $2, $4, $6); } operand: unary_expression { $$ = $1; } @@ -278,185 +273,183 @@ expression: binary_expression: expression "*" expression { - $$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::multiplication); + $$ = new boot::binary_expression(boot::make_position(@$), $1, $3, boot::binary_operator::multiplication); } | expression "/" expression { - $$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::division); + $$ = new boot::binary_expression(boot::make_position(@$), $1, $3, boot::binary_operator::division); } | expression "%" expression { - $$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::remainder); + $$ = new boot::binary_expression(boot::make_position(@$), $1, $3, boot::binary_operator::remainder); } | expression "+" expression { - $$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::sum); + $$ = new boot::binary_expression(boot::make_position(@$), $1, $3, boot::binary_operator::sum); } | expression "-" expression { - $$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::subtraction); + $$ = new boot::binary_expression(boot::make_position(@$), $1, $3, boot::binary_operator::subtraction); } | expression "=" expression { - $$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::equals); + $$ = new boot::binary_expression(boot::make_position(@$), $1, $3, boot::binary_operator::equals); } | expression "<>" expression { - $$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::not_equals); + $$ = new boot::binary_expression(boot::make_position(@$), $1, $3, boot::binary_operator::not_equals); } | expression "<" expression { - $$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::less); + $$ = new boot::binary_expression(boot::make_position(@$), $1, $3, boot::binary_operator::less); } | expression ">" expression { - $$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::greater); + $$ = new boot::binary_expression(boot::make_position(@$), $1, $3, boot::binary_operator::greater); } | expression "<=" expression { - $$ = new boot::binary_expression(boot::make_position(@2), $1, $3, - boot::binary_operator::less_equal); + $$ = new boot::binary_expression(boot::make_position(@$), $1, $3, boot::binary_operator::less_equal); } | expression ">=" expression { - $$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::greater_equal); + $$ = new boot::binary_expression(boot::make_position(@$), $1, $3, boot::binary_operator::greater_equal); } | expression "&" expression { - $$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::conjunction); + $$ = new boot::binary_expression(boot::make_position(@$), $1, $3, boot::binary_operator::conjunction); } | expression "or" expression { - $$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::disjunction); + $$ = new boot::binary_expression(boot::make_position(@$), $1, $3, boot::binary_operator::disjunction); } | expression "xor" expression { - $$ = new boot::binary_expression(boot::make_position(@2), $1, $3, - boot::binary_operator::exclusive_disjunction); + $$ = new boot::binary_expression(boot::make_position(@$), $1, $3, boot::binary_operator::exclusive_disjunction); } | expression "<<" expression { - $$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::shift_left); + $$ = new boot::binary_expression(boot::make_position(@$), $1, $3, boot::binary_operator::shift_left); } | expression ">>" expression { - $$ = new boot::binary_expression(boot::make_position(@2), $1, $3, boot::binary_operator::shift_right); + $$ = new boot::binary_expression(boot::make_position(@$), $1, $3, boot::binary_operator::shift_right); } unary_expression: "@" operand { - $$ = new boot::unary_expression(boot::make_position(@1), $2, boot::unary_operator::reference); + $$ = new boot::unary_expression(boot::make_position(@$), $2, boot::unary_operator::reference); } | "~" operand { - $$ = new boot::unary_expression(boot::make_position(@1), $2, boot::unary_operator::negation); + $$ = new boot::unary_expression(boot::make_position(@$), $2, boot::unary_operator::negation); } | "-" operand { - $$ = new boot::unary_expression(boot::make_position(@1), $2, boot::unary_operator::minus); + $$ = new boot::unary_expression(boot::make_position(@$), $2, boot::unary_operator::minus); } expressions: expression "," expressions { - std::swap($$, $3); + $$ = $3; $$.emplace($$.cbegin(), $1); } | expression { $$.push_back($1); } type_expressions: type_expression "," type_expressions { - std::swap($$, $3); + $$ = $3; $$.emplace($$.cbegin(), $1); } | type_expression { $$.push_back($1); } designator_expression: simple_expression "[" expression "]" - { $$ = new boot::array_access_expression(boot::make_position(@2), $1, $3); } + { $$ = new boot::array_access_expression(boot::make_position(@$), $1, $3); } | simple_expression "." IDENTIFIER - { $$ = new boot::field_access_expression(boot::make_position(@2), $1, $3); } + { $$ = new boot::field_access_expression(boot::make_position(@$), $1, $3); } | simple_expression "^" - { $$ = new boot::dereference_expression(boot::make_position(@1), $1); } + { $$ = new boot::dereference_expression(boot::make_position(@$), $1); } | IDENTIFIER - { $$ = new boot::named_expression(boot::make_position(@1), $1); } + { $$ = new boot::named_expression(boot::make_position(@$), $1); } statement: designator_expression ":=" expression - { $$ = new boot::assign_statement(boot::make_position(@1), $1, $3); } + { $$ = new boot::assign_statement(boot::make_position(@$), $1, $3); } | "while" expression "do" statements elsif_do_statements "end" { - boot::conditional_statements *body = new boot::conditional_statements($2, std::move($4)); - $$ = new boot::while_statement(boot::make_position(@1), body, std::move($5)); + boot::conditional_statements *body = new boot::conditional_statements($2, $4); + $$ = new boot::while_statement(boot::make_position(@$), body, $5); } | "if" expression "then" statements elsif_then_statements else_statements "end" { - boot::conditional_statements *then = new boot::conditional_statements($2, std::move($4)); - $$ = new boot::if_statement(boot::make_position(@1), then, std::move($5), $6); + boot::conditional_statements *then = new boot::conditional_statements($2, $4); + $$ = new boot::if_statement(boot::make_position(@$), then, $5, $6); } | call_expression { $$ = $1; } | "defer" statements "end" - { $$ = new boot::defer_statement(boot::make_position(@1), std::move($2)); } + { $$ = new boot::defer_statement(boot::make_position(@$), $2); } | "case" expression "of" switch_cases else_statements "end" - { $$ = new boot::case_statement(boot::make_position(@1), $2, std::move($4), $5); } + { $$ = new boot::case_statement(boot::make_position(@$), $2, $4, $5); } | { $$ = new boot::empty_statement(boot::make_position(@$)); } switch_case: case_labels ":" statements - { $$ = { .labels = std::move($1), .statements = std::move($3) }; } + { $$ = { .labels = $1, .statements = $3 }; } switch_cases: switch_case "|" switch_cases { - std::swap($$, $3); + $$ = $3; $$.emplace($$.cbegin(), $1); } | switch_case { $$.push_back($1); } case_labels: expression "," case_labels { - std::swap($$, $3); + $$ = $3; $$.emplace($$.cbegin(), $1); } | expression { $$.push_back($1); } statements: statements ";" statement { - std::swap($$, $1); + $$ = $1; $$.insert($$.cend(), $3); } | statement { $$.push_back($1); } field_declaration: - identifiers ":" type_expression { $$ = std::make_pair(std::move($1), std::shared_ptr<boot::type_expression>($3)); } + identifiers ":" type_expression { $$ = std::make_pair($1, std::shared_ptr<boot::type_expression>($3)); } required_fields: field_declaration ";" required_fields { - std::swap($$, $3); + $$ = $3; $$.emplace($$.cbegin(), $1); } | field_declaration { $$.emplace_back($1); } optional_fields: - required_fields { std::swap($$, $1); } + required_fields { $$ = $1; } | /* no fields */ {} field_initializer: - IDENTIFIER ":" expression { $$.name = std::move($1); $$.value = $3; } + IDENTIFIER ":" expression { $$.name = $1; $$.value = $3; } field_initializers: field_initializer "," field_initializers { - std::swap($$, $3); + $$ = $3; $$.emplace($$.cbegin(), $1); } | field_initializer { $$.push_back($1); } type_expression: "[" INTEGER "]" type_expression { - $$ = new boot::array_type_expression(boot::make_position(@1), $4, $2); + $$ = new boot::array_type_expression(boot::make_position(@$), $4, $2); } | "^" type_expression { - $$ = new boot::pointer_type_expression(boot::make_position(@1), $2); + $$ = new boot::pointer_type_expression(boot::make_position(@$), $2); } | "record" optional_fields "end" { - $$ = new boot::record_type_expression(boot::make_position(@1), std::move($2)); + $$ = new boot::record_type_expression(boot::make_position(@$), $2); } | "record" "(" IDENTIFIER ")" optional_fields "end" { - $$ = new boot::record_type_expression(boot::make_position(@1), std::move($5), std::move($3)); + $$ = new boot::record_type_expression(boot::make_position(@$), $5, $3); } | "proc" procedure_heading { @@ -464,97 +457,96 @@ type_expression: } | "(" identifiers ")" { - $$ = new boot::enumeration_type_expression(boot::make_position(@1), std::move($2)); + $$ = new boot::enumeration_type_expression(boot::make_position(@$), $2); } | IDENTIFIER { - $$ = new boot::named_expression(boot::make_position(@1), $1); + $$ = new boot::named_expression(boot::make_position(@$), $1); } identifiers: IDENTIFIER "," identifiers { - std::swap($$, $3); - $$.emplace($$.cbegin(), std::move($1)); + $$ = $3; + $$.emplace($$.cbegin(), $1); } - | IDENTIFIER { $$.emplace_back(std::move($1)); } + | IDENTIFIER { $$.emplace_back($1); } variable_declaration: identifier_definitions ":" type_expression { std::shared_ptr<boot::type_expression> shared_type{ $3 }; - $$ = new boot::variable_declaration( boot::make_position(@2), std::move($1), shared_type); + $$ = new boot::variable_declaration( boot::make_position(@$), $1, shared_type); } | identifier_definitions ":" type_expression ":=" "extern" { std::shared_ptr<boot::type_expression> shared_type{ $3 }; - $$ = new boot::variable_declaration( boot::make_position(@2), std::move($1), shared_type, - std::monostate{}); + $$ = new boot::variable_declaration( boot::make_position(@$), $1, shared_type, std::monostate{}); } | identifier_definitions ":" type_expression ":=" expression { std::shared_ptr<boot::type_expression> shared_type{ $3 }; - $$ = new boot::variable_declaration( boot::make_position(@2), std::move($1), shared_type, $5); + $$ = new boot::variable_declaration( boot::make_position(@$), $1, shared_type, $5); } variable_declarations: /* no variable declarations */ {} | variable_declaration variable_declarations { - std::swap($$, $2); + $$ = $2; $$.insert(std::cbegin($$), $1); } variable_part: /* no variable declarations */ {} - | "var" variable_declarations { std::swap($$, $2); } + | "var" variable_declarations { $$ = $2; } constant_declaration: identifier_definition ":=" expression { - $$ = new boot::constant_declaration(boot::make_position(@1), std::move($1), $3); + $$ = new boot::constant_declaration(boot::make_position(@$), $1, $3); } constant_declarations: constant_declaration constant_declarations { - std::swap($$, $2); + $$ = $2; $$.insert(std::cbegin($$), $1); } | /* no constant definitions */ {} constant_part: /* no constant definitions */ {} - | "const" constant_declarations { std::swap($$, $2); } + | "const" constant_declarations { $$ = $2; } import_declaration: IDENTIFIER "." import_declaration { - std::swap($$, $3); - $$.emplace($$.cbegin(), std::move($1)); + $$ = $3; + $$.emplace($$.cbegin(), $1); } - | IDENTIFIER { $$.emplace_back(std::move($1)); } + | IDENTIFIER { $$.emplace_back($1); } import_declarations: import_declaration "," import_declarations { - std::swap($$, $3); - $$.emplace($$.cbegin(), new boot::import_declaration(boot::make_position(@1), std::move($1))); + $$ = $3; + $$.emplace($$.cbegin(), new boot::import_declaration(boot::make_position(@$), $1)); } | import_declaration { - $$.emplace_back(new boot::import_declaration(boot::make_position(@1), std::move($1))); + $$.emplace_back(new boot::import_declaration(boot::make_position(@$), $1)); } import_part: /* no import declarations */ {} - | "import" import_declarations { std::swap($$, $2); } + | "import" import_declarations { $$ = $2; } type_declaration: identifier_definition "=" type_expression { - $$ = new boot::type_declaration(boot::make_position(@1), std::move($1), $3); + $$ = new boot::type_declaration(boot::make_position(@$), $1, $3); } type_declarations: type_declaration type_declarations { - std::swap($$, $2); + $$ = $2; $$.insert($$.cbegin(), $1); } | /* no type definitions */ {} type_part: /* no type definitions */ {} - | "type" type_declarations { std::swap($$, $2); } + | "type" type_declarations { $$ = $2; } actual_parameter_list: "(" ")" {} - | "(" expressions ")" { std::swap($$, $2); } + | "(" expressions ")" { $$ = $2; } %% void yy::parser::error(const location_type& loc, const std::string& message) |
