diff --git a/schala-lang/language/src/parsing.rs b/schala-lang/language/src/parsing.rs index e8c1379..8af6ad8 100644 --- a/schala-lang/language/src/parsing.rs +++ b/schala-lang/language/src/parsing.rs @@ -3,8 +3,10 @@ //! //! //! # Schala EBNF Grammar -//! Terminal productions are in 'single quotes' or UPPERCASE if they are a class of tokens, -//! or otherwise not representable in ASCII. +//! This document is the authoritative grammar of Schala, represented in something approximating +//! Extended Backus-Naur form. Terminal productions are in "double quotes", or UPPERCASE +//! if they represent a class of tokens rather than an specific string, or are otherwise +//! unreprsentable in ASCII. //! //! ## Top level structure //! @@ -15,7 +17,9 @@ //! block := "{" (statement delimiter)* "}" //! declaration := type_declaration | func_declaration | binding_declaration | impl_declaration //! ``` -//! ## Declarations - Types +//! ## Declarations +//! +//! ### Types //! ``` //! type_declaration := "type" type_declaration_body //! type_declaration_body := "alias" type_alias | "mut"? type_singleton_name "=" type_body @@ -25,8 +29,8 @@ //! typed_identifier_list := typed_identifier* //! typed_identifier := IDENTIFIER type_anno //! ``` -//! ## Declaration - Functions -//! +//! ### Functions +//! //! ``` //! func_declaration := func_signature func_body //! func_body := ε | nonempty_func_body @@ -36,29 +40,29 @@ //! formal_param_list := "(" (formal_param ",")* ")" //! formal_param := IDENTIFIER type_anno+ //! ``` -//! -//! ## Declaration - Variable bindings +//! +//! ### Variable bindings //! ```binding_declaration := "let" "mut"? IDENTIFIER "=" expresion``` -//! -//! ## Declaration - Interface -//! +//! +//! ### Interfaces +//! //! ``` //! interface_declaration := "interface" type_singleton_name signature_block //! impl_declaration := "impl" type_singleton_name decl_block | "impl" type_singleton_name "for" type_name decl_block //! decl_block := "{" (func_declaration)* "}" //! signature_block := "{" (func_signature)* "}" //! ``` -//! -//! ## Type Annotations -//! +//! +//! ### Type Annotations +//! //! ``` -//! type_anno := (":" type_name)+ +//! type_anno := ":" type_name //! type_name := type_singleton_name | "(" type_names ")" //! type_names := ε | type_name (, type_name)* //! type_singleton_name = IDENTIFIER (type_params)* //! type_params := "<" type_name (, type_name)* ">" //! ``` -//! +//! //! ## Expressions //! ``` //! expression := precedence_expr type_anno+ @@ -66,26 +70,24 @@ //! prefix_expr := prefix_op call_expr //! prefix_op := "+" | "-" | "!" | "~" //! call_expr := index_expr ( "(" expr_list ")" )* | ε -//! ``` -//! -//! ``` //! expr_list := expression ("," expression)* | ε //! index_expr := primary ( "[" (expression ("," (expression)* | ε) "]" )* //! primary := literal | paren_expr | if_expr | for_expr | while_expr | identifier_expr | lambda_expr | anonymous_struct | list_expr +//! expr_or_block := "{" (statement delimiter)* "}" | expr //! ``` -//! -//! ## Primary expressions -//! +//! +//! ### Primary expressions +//! //! ``` //! list_expr := "[" (expression, ",")* "]" -//! lambda_expr := "\\" lambda_param_list type_anno+ nonempty_func_body +//! lambda_expr := "\" lambda_param_list type_anno+ nonempty_func_body //! lambda_param_list := formal_param_list | formal_param //! paren_expr := LParen paren_inner RParen //! paren_inner := (expression ",")* //! identifier_expr := named_struct | IDENTIFIER //! ``` -//! -//! Expression literals +//! +//! ## Literals //! ``` //! literal := "true" | "false" | number_literal | STR_LITERAL //! named_struct := IDENTIFIER record_block @@ -93,7 +95,7 @@ //! record_entry := IDENTIFIER ":" expression //! anonymous_struct := TODO //! ``` -//! +//! //! A `float_literal` can still be assigned to an int in type-checking //! ``` //! number_literal := int_literal | float_literal @@ -101,8 +103,8 @@ //! float_literal := digits ("." digits) //! digits := (DIGIT_GROUP underscore)+ //! ``` -//! -//! ## Patterns +//! +//! ### Patterns //! ``` //! pattern := "(" (pattern, ",")* ")" | simple_pattern //! simple_pattern := pattern_literal | record_pattern | tuple_struct_pattern @@ -112,12 +114,8 @@ //! record_pattern_entry := IDENTIFIER | IDENTIFIER ":" Pattern //! tuple_struct_pattern := IDENTIFIER "(" (pattern, ",")* ")" //! ``` -//! -//! ``` -//! expr_or_block := "{" (statement delimiter)* "}" | expr -//! ``` -//! -//! ## If-expressions +//! +//! ### If-expressions //! ``` //! if_expr := "if" discriminator ("then" condititional | "is" simple_pattern_match | guard_block) //! discriminator := precedence_expr (operator)+ @@ -128,16 +126,16 @@ //! guard_arm := guard "->" expr_or_block //! guard := "is" pattern | (operator)+ precedence_expr //! ``` -//! -//! ## While expressions +//! +//! ### While expressions //! ``` //! while_expr := "while" while_cond "{" (statement delimiter)* "}" //! while_cond := ε | expression | expression "is" pattern //TODO maybe is-expresions should be primary //! ``` -//! +//! //! //TODO this implies there must be at least one enumerator, which the parser doesn"t support right //! //this second, and maybe should fail later anyway -//! ## For-expressions +//! ### For-expressions //! ``` //! for_expr := "for" (enumerator | "{" enumerators "}") for_expr_body //! for_expr_body := "return" expression | "{" (statement delimiter)* "}"