fix(grammar): Simplify and improve EBNF definition

Signed-off-by: erick-alcachofa <erick@artichoke.dev>

The EBNF grammar definition contained several redundancies,
inconsistencies, and minor omissions. This commit refactors the grammar
to make it more concise, readable, and robust for parsing.

Key changes include:

- **Rule Simplification**: Redundant intermediate rules (`fn_params`,
  `statements`, `assign_expression`) have been removed. Rules like
  `code_block` and `import_target` are now more concisely expressed
  using standard EBNF operators (`?`, `*`).

- **EOF Enforcement**: The top-level `program` rule now requires an
  `<eof>` token. This is a crucial fix to ensure the parser consumes the
  entire file and fails on trailing invalid tokens.

- **Optional Generics**: Generic parameters (`<... >`) are now correctly
  marked as optional on `function`, `struct`, and `enum` declarations,
  which was the original intent.

- **Flexible For-Loops**: The update/increment expression (the third
  part) in a C-style `for` loop is now optional, aligning with behavior
  in languages like C and C++.

- **Primary Expressions**: Primary type expressions failed to parse
  correctly namespaced elements and types, now it's fixed and improved.
This commit is contained in:
erick-alcachofa 2025-10-05 14:49:50 -06:00
parent bb58b17528
commit f5be339f43
Signed by: me
GPG Key ID: 6FA5F8643444BAFA

View File

@ -7,7 +7,6 @@
================================================================================ ================================================================================
*/ */
/* --- Program Structure --- */ /* --- Program Structure --- */
/* A program is a sequence of top-level declarations and statements. */ /* A program is a sequence of top-level declarations and statements. */
@ -18,6 +17,7 @@
| <struct_declaration> | <struct_declaration>
| <enum_declaration> | <enum_declaration>
| <function_declaration> )* | <function_declaration> )*
<eof>
<module_statement> = <module_statement> =
"export"? "module" <namespaced_identifier> "{" "export"? "module" <namespaced_identifier> "{"
@ -32,8 +32,7 @@
"import" <import_target> ";" "import" <import_target> ";"
<import_target> = <import_target> =
<namespaced_identifier> <namespaced_identifier> ( "::" "*" )?
| <namespaced_identifier> "::" "*"
<alias_statement> = <alias_statement> =
"using" <identifier> "=" <namespaced_identifier> ";" "using" <identifier> "=" <namespaced_identifier> ";"
@ -43,10 +42,7 @@
/* Rules for defining functions, structs, enums, and their components. */ /* Rules for defining functions, structs, enums, and their components. */
<function_declaration> = <function_declaration> =
"export"? "fn" <identifier> <generic_params> "(" <fn_params> ")" ( "->" <type> )? <code_block> "export"? "fn" <identifier> <generic_params>? "(" <fn_params_list>? ")" ( "->" <type> )? <code_block>
<fn_params> =
<fn_params_list>?
<fn_params_list> = <fn_params_list> =
"this" <type> ("," <fn_param> ( "," <fn_param> )* )? "this" <type> ("," <fn_param> ( "," <fn_param> )* )?
@ -56,7 +52,7 @@
<identifier> ":" <type> <identifier> ":" <type>
<struct_declaration> = <struct_declaration> =
"export"? "struct" <identifier> <generic_params> "{" <struct_members> "}" "export"? "struct" <identifier> <generic_params>? "{" <struct_members> "}"
<struct_members> = <struct_members> =
<struct_member> ( "," <struct_member> )* <struct_member> ( "," <struct_member> )*
@ -65,7 +61,7 @@
<identifier> ":" <type> <identifier> ":" <type>
<enum_declaration> = <enum_declaration> =
"export"? "enum" <identifier> <generic_params> "{" <enum_members> "}" "export"? "enum" <identifier> <generic_params>? "{" <enum_members> "}"
<enum_members> = <enum_members> =
<enum_member> ( "," <enum_member> )* <enum_member> ( "," <enum_member> )*
@ -74,7 +70,7 @@
<identifier> ( "(" <type> ")" )? <identifier> ( "(" <type> ")" )?
<generic_params> = <generic_params> =
( "<" <generic_params_list> ">" )? "<" <generic_params_list> ">"
<generic_params_list> = <generic_params_list> =
<generic_param> ( "," <generic_param> )* <generic_param> ( "," <generic_param> )*
@ -87,10 +83,7 @@
/* Rules for code blocks, variable declarations, and control structures. */ /* Rules for code blocks, variable declarations, and control structures. */
<code_block> = <code_block> =
"{" <statements>? "}" "{" <statement>* "}"
<statements> =
<statement> ( <statement> )*
<statement> = <statement> =
<variable_declaration> ";" <variable_declaration> ";"
@ -101,7 +94,7 @@
| <return_statement> ";" | <return_statement> ";"
| <break_statement> ";" | <break_statement> ";"
| <continue_statement> ";" | <continue_statement> ";"
| <expression_statement> | <expression> ";"
| <alias_statement> | <alias_statement>
| <match_statement> | <match_statement>
| <switch_statement> | <switch_statement>
@ -135,7 +128,7 @@
) )
<c_for_statement> = <c_for_statement> =
"for" "(" <variable_declaration>? ";" <expression> ";" <expression> ")" "for" "(" <variable_declaration>? ";" <expression> ";" <expression>? ")"
<code_block> <code_block>
<range_for_statement> = <range_for_statement> =
@ -182,17 +175,11 @@
<return_statement> = <return_statement> =
"return" <expression>? "return" <expression>?
<expression_statement> =
<expression> ";"
/* --- Expressions & Operator Precedence --- */ /* --- Expressions & Operator Precedence --- */
/* The full expression hierarchy, from lowest to highest precedence. */ /* The full expression hierarchy, from lowest to highest precedence. */
<expression> = <expression> =
<assign_expression>
<assign_expression> =
<bool_or_expression> ( ( <assign_op> | <compound_assign_op> ) <expression> )? <bool_or_expression> ( ( <assign_op> | <compound_assign_op> ) <expression> )?
<bool_or_expression> = <bool_or_expression> =
@ -227,16 +214,17 @@
/* The highest-precedence expressions, including literals and grouped expressions. */ /* The highest-precedence expressions, including literals and grouped expressions. */
<primary_type_expression> = <primary_type_expression> =
<char_literal> <grouped_expression>
| <scoped_access_expression>
| <reflection_expression>
| <struct_literal>
| <type_name>
| <char_literal>
| <null_literal> | <null_literal>
| <string_literal> | <string_literal>
| <number_literal> | <number_literal>
| <boolean_literal> | <boolean_literal>
| <grouped_expression>
| <identifier> | <identifier>
| <struct_literal>
| <scoped_access_expression>
| <reflection_expression>
<grouped_expression> = <grouped_expression> =
"(" <expression> ")" "(" <expression> ")"
@ -245,7 +233,7 @@
<type_name> "::" <identifier> <type_name> "::" <identifier>
<reflection_expression> = <reflection_expression> =
( <primary_expression> | <type_name> | <scoped_access_expression> ) ".@" <identifier>? ( <type_name> | <scoped_access_expression> ) ".@" <identifier>?
<fn_call_arguments> = <fn_call_arguments> =
"(" <expression_list> ")" "(" <expression_list> ")"
@ -292,9 +280,10 @@
<suffix_op> = <suffix_op> =
"[" <expression>? ":" <expression>? "]" "[" <expression>? ":" <expression>? "]"
| "[" <expression> "]" | "[" <expression> "]"
| ".[" <expression> "]"
| "." <identifier> | "." <identifier>
| "->" <identifier> | "->" <identifier>
| ".@" <identifier>?
| ".[" <expression> "]"
| ".#" | ".#"
| ".*" | ".*"
@ -302,7 +291,7 @@
/* Rules for defining types, type names, and type qualifiers. */ /* Rules for defining types, type names, and type qualifiers. */
<type> = <type> =
<type_qualifier_chain> <type_name> <type_qualifier_chain>? <type_name>
<type_qualifier_chain> = <type_qualifier_chain> =
( "*" | "[]" ) <type_qualifier_chain>? ( "*" | "[]" ) <type_qualifier_chain>?
@ -345,4 +334,4 @@
<nonzero_digit> = [1-9] <nonzero_digit> = [1-9]
<empty> = E /* Represents an empty terminal string */ <empty> = E /* Represents an empty terminal string */
<eof> = /* End Of File */