diff --git a/README.md b/README.md new file mode 100644 index 0000000..66d2692 --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +# Tree-Sitter parser for Ada + +The grammar is adapted from the work done by Stephen Leak for the +Emacs ada-mode. It was translated (partially for now) to tree-sitter +syntax, and slightly changed to reduce some conflicts. Tree-sitter +doesn't need a full syntax tree, so we can take some shortcuts in +the grammar. + + +## Installation + +Execute the following commands: +``` + npm install + npm run test +``` + diff --git a/README.txt b/README.txt deleted file mode 100644 index 123ffe3..0000000 --- a/README.txt +++ /dev/null @@ -1,8 +0,0 @@ -Tree-Sitter parser for Ada - - -Use: - - npm install - npm run test - diff --git a/corpus/statements.txt b/corpus/statements.txt index d5788db..212f1a5 100644 --- a/corpus/statements.txt +++ b/corpus/statements.txt @@ -261,3 +261,103 @@ end P; (identifier))))))))))))))) (name (identifier)))))) + +================================================================================ +Raise exception +================================================================================ + +procedure P is +begin + raise Constraint_Error; + raise Constraint_Error with "msg"; +end; + +-------------------------------------------------------------------------------- + +(compilation + (compilation_unit + (proper_body + (subprogram_body + (subprogram_specification + (procedure_specification + (name + (identifier)))) + (handled_sequence_of_statements + (sequence_of_statements + (statement + (simple_statement + (raise_statement + (name + (identifier))))) + (statement + (simple_statement + (raise_statement + (name + (identifier)) + (expression + (relation + (simple_expression + (term + (factor + (primary + (string_literal)))))))))))))))) + +================================================================================ +Function calls +================================================================================ + +procedure P is + A : Integer; +begin + A := Func (B => 1); +end; + +-------------------------------------------------------------------------------- + +(compilation + (compilation_unit + (proper_body + (subprogram_body + (subprogram_specification + (procedure_specification + (name + (identifier)))) + (non_empty_declarative_part + (declarative_item_pragma + (object_declaration + (defining_identifier_list + (identifier)) + (subtype_indication + (name + (identifier)))))) + (handled_sequence_of_statements + (sequence_of_statements + (statement + (simple_statement + (assignment_statement + (name + (identifier)) + (assign_value + (expression + (relation + (simple_expression + (term + (factor + (primary + (name + (function_call + (name + (identifier)) + (actual_parameter_part + (parameter_association + (component_choice_list + (selector_name + (identifier))) + (assoc_expression + (expression + (relation + (simple_expression + (term + (factor + (primary + (numeric_literal)))))))))))))))))))))))))))) diff --git a/corpus/subprograms.txt b/corpus/subprograms.txt index 516b306..a12ff52 100644 --- a/corpus/subprograms.txt +++ b/corpus/subprograms.txt @@ -108,7 +108,6 @@ end; (aspect_mark (identifier))))))))) - ================================================================================ functions ================================================================================ @@ -261,6 +260,64 @@ function F2 (A : Integer) return Boolean (name (identifier))))))))))))))))) +================================================================================ +Expression function declare +================================================================================ + +function F2 (A : Integer) return Boolean + is (declare B : constant Integer := A + 1; begin B); + +-------------------------------------------------------------------------------- + +(compilation + (compilation_unit + (expression_function_declaration + (function_specification + (name + (identifier)) + (parameter_and_result_profile + (formal_part + (parameter_specification_list + (parameter_specification + (defining_identifier_list + (identifier)) + (name + (identifier))))) + (result_profile + (name + (identifier))))) + (aggregate + (declare_expression + (declare_item + (object_declaration + (defining_identifier_list + (identifier)) + (subtype_indication + (name + (identifier))) + (assign_value + (expression + (relation + (simple_expression + (term + (factor + (primary + (name + (identifier))))) + (binary_adding_operator) + (term + (factor + (primary + (numeric_literal)))))))))) + (expression + (relation + (simple_expression + (term + (factor + (primary + (name + (identifier))))))))))))) + ================================================================================ Expression function raise ================================================================================ @@ -464,142 +521,142 @@ function F5 (A : Integer) return Boolean (name (identifier)))))))))))))))))))))))) -====== +================================================================================ Expression function case -====== +================================================================================ function F (A : Integer) return Boolean is (case A + 1 is when 0 .. 1 | 3 .. 4 => True, when others => False); ------- +-------------------------------------------------------------------------------- - (compilation - (compilation_unit - (expression_function_declaration - (function_specification - (name - (identifier)) - (parameter_and_result_profile - (formal_part - (parameter_specification_list - (parameter_specification - (defining_identifier_list - (identifier)) - (name - (identifier))))) - (result_profile +(compilation + (compilation_unit + (expression_function_declaration + (function_specification + (name + (identifier)) + (parameter_and_result_profile + (formal_part + (parameter_specification_list + (parameter_specification + (defining_identifier_list + (identifier)) (name (identifier))))) - (aggregate - (conditional_expression - (case_expression - (expression - (relation + (result_profile + (name + (identifier))))) + (aggregate + (conditional_expression + (case_expression + (expression + (relation + (simple_expression + (term + (factor + (primary + (name + (identifier))))) + (binary_adding_operator) + (term + (factor + (primary + (numeric_literal))))))) + (case_expression_alternative + (discrete_choice_list + (discrete_choice + (range_g (simple_expression (term (factor (primary - (name - (identifier))))) - (binary_adding_operator) + (numeric_literal))))) + (simple_expression (term (factor (primary (numeric_literal))))))) - (case_expression_alternative - (discrete_choice_list - (discrete_choice - (range_g - (simple_expression - (term - (factor - (primary - (numeric_literal))))) - (simple_expression - (term - (factor - (primary - (numeric_literal))))))) - (discrete_choice - (range_g - (simple_expression - (term - (factor - (primary - (numeric_literal))))) - (simple_expression - (term - (factor - (primary - (numeric_literal)))))))) - (expression - (relation - (simple_expression - (term - (factor - (primary - (name - (identifier))))))))) - (case_expression_alternative - (discrete_choice_list - (discrete_choice)) - (expression - (relation - (simple_expression - (term - (factor - (primary - (name - (identifier))))))))))))))) + (discrete_choice + (range_g + (simple_expression + (term + (factor + (primary + (numeric_literal))))) + (simple_expression + (term + (factor + (primary + (numeric_literal)))))))) + (expression + (relation + (simple_expression + (term + (factor + (primary + (name + (identifier))))))))) + (case_expression_alternative + (discrete_choice_list + (discrete_choice)) + (expression + (relation + (simple_expression + (term + (factor + (primary + (name + (identifier))))))))))))))) -===== +================================================================================ Expression function quantified -===== +================================================================================ function F (A : My_Array) return Boolean is (for some E of A => E = 1); ------- +-------------------------------------------------------------------------------- - (compilation - (compilation_unit - (expression_function_declaration - (function_specification - (name - (identifier)) - (parameter_and_result_profile - (formal_part - (parameter_specification_list - (parameter_specification - (defining_identifier_list - (identifier)) - (name - (identifier))))) - (result_profile +(compilation + (compilation_unit + (expression_function_declaration + (function_specification + (name + (identifier)) + (parameter_and_result_profile + (formal_part + (parameter_specification_list + (parameter_specification + (defining_identifier_list + (identifier)) (name (identifier))))) - (aggregate - (quantified_expression - (quantifier) - (iterator_specification - (identifier) - (name - (identifier))) - (assoc_expression - (expression - (relation - (simple_expression - (term - (factor - (primary - (name - (identifier)))))) - (relational_operator) - (simple_expression - (term - (factor - (primary - (numeric_literal))))))))))))) + (result_profile + (name + (identifier))))) + (aggregate + (quantified_expression + (quantifier) + (iterator_specification + (identifier) + (name + (identifier))) + (assoc_expression + (expression + (relation + (simple_expression + (term + (factor + (primary + (name + (identifier)))))) + (relational_operator) + (simple_expression + (term + (factor + (primary + (numeric_literal))))))))))))) diff --git a/grammar.js b/grammar.js index 79d71e3..0d145cf 100644 --- a/grammar.js +++ b/grammar.js @@ -77,6 +77,7 @@ module.exports = grammar({ [$.defining_identifier_list, $.object_renaming_declaration, $.exception_renaming_declaration, $._direct_name], [$.defining_identifier_list, $._direct_name], + [$.defining_identifier_list, $.object_renaming_declaration], // 'generic' . 'package' ... [$.generic_formal_part, $.generic_renaming_declaration], @@ -104,6 +105,9 @@ module.exports = grammar({ // 'type' identifier 'is' 'new' subtype_indication . 'with' . [$.private_extension_declaration, $.derived_type_definition], + [$.function_call, $.procedure_call_statement], + [$.function_call, $.name], + ], // inline: $ => [ @@ -136,10 +140,8 @@ module.exports = grammar({ // Simpler definition for games than the standard grammer // name: $ => choice( -// $._direct_name, // $.explicit_dereference, // $.selected_component, -// $.attribute_reference, // $.function_call, // $.character_literal, // $.qualified_expression, @@ -158,12 +160,11 @@ module.exports = grammar({ '.', $.name, )), -// repeat(seq( -// '.', -// $.identifier, -// )), ), $.attribute_reference, + $.function_call, + //$.string_literal, // from ada-mode, but seems wrong. + // // Added to primary instead ), name_list: $ => comma_separated_list_of($.name), @@ -511,6 +512,7 @@ module.exports = grammar({ reservedWord('null'), $.aggregate, $.name, + $.string_literal, // ada-mode puts this in name instead // $.allocator, ), access_type_definition: $ => seq( @@ -569,7 +571,7 @@ module.exports = grammar({ comma_separated_list_of($.parameter_association), $.conditional_expression, $.quantified_expression, -// $.declare_expression, + $.declare_expression, ), ')', ), @@ -599,6 +601,16 @@ module.exports = grammar({ ), $.assoc_expression, ), + declare_expression: $ => seq( + reservedWord('declare'), + repeat($.declare_item), + reservedWord('begin'), + $.expression, + ), + declare_item: $ => choice( + $.object_declaration, + $.object_renaming_declaration, + ), quantifier: $ => choice( reservedWord('all'), reservedWord('some'), @@ -626,7 +638,7 @@ module.exports = grammar({ choice( $.conditional_expression, $.quantified_expression, -// $.declare_expression, + $.declare_expression, ), ')', ), @@ -1499,7 +1511,7 @@ module.exports = grammar({ // $.requeue_statement, $.delay_statement, // $.abort_statement, -// $.raise_statement, + $.raise_statement, $.pragma_g, ), statement: $ => seq( @@ -1558,6 +1570,17 @@ module.exports = grammar({ optional($.actual_parameter_part), ';', ), + raise_statement: $ => seq( + reservedWord('raise'), + optional(seq( + $.name, + optional(seq( + reservedWord('with'), + $.expression, // ada-mode allows "raise CE with raise with ..." + )), + )), + ';', + ), loop_statement: $ => seq( optional($.loop_label), optional($.iteration_scheme),