(* Waltzing Template Language Grammar (EBNF) *) (* This grammar defines the syntax for .wtz template files *) (* Root rule - a template file *) template = { template_element } ; template_element = use_statement | import_statement | struct_definition | enum_definition | function_definition | template_node ; (* Rust imports *) use_statement = "@use" , rust_path , [ "as" , identifier ] ; rust_path = identifier , { "::" , identifier } ; (* Template imports *) import_statement = "@import" , string_literal , "as" , identifier ; (* Type definitions *) struct_definition = "@struct" , [ attribute_list ] , identifier , [ generic_params ] , "{" , { struct_field } , "}" ; struct_field = identifier , [ attribute_list ] , ":" , type_expression , [ "," ] ; enum_definition = "@enum" , [ attribute_list ] , identifier , [ generic_params ] , "{" , { enum_variant } , "}" ; enum_variant = identifier , [ "(" , { type_expression , [ "," ] } , ")" ] , [ "," ] ; (* Attribute lists for structs, enums, and fields *) attribute_list = "[" , [ attribute , { "," , attribute } ] , "]" ; attribute = identifier , [ "(" , attribute_content , ")" ] ; attribute_content = ? any character sequence with balanced parentheses ? ; generic_params = "<" , identifier , { "," , identifier } , ">" ; type_expression = rust_type ; (* Function definitions *) function_definition = "@fn" , identifier , parameter_list , content_block ; parameter_list = "(" , [ parameter , { "," , parameter } ] , ")" ; parameter = identifier , ":" , rust_type , [ "=" , default_value ] ; default_value = expression ; content_block = "{" , { template_node } , "}" ; (* Template nodes *) template_node = html_element | template_expression | template_control_flow | text_content | comment ; (* HTML elements *) html_element = "<" , tag_name , { html_attribute } , [ "/" ] , ">" | "<" , tag_name , { html_attribute } , ">" , { template_node } , "" ; tag_name = identifier ; html_attribute = attribute_name , [ "=" , attribute_value ] ; attribute_name = identifier | "@" , expression_identifier ; attribute_value = string_literal | template_expression | "@" , "{" , expression , "}" ; (* Template expressions *) template_expression = simple_expression | complex_expression | safe_expression ; simple_expression = "@" , expression_path ; complex_expression = "@" , "{" , expression , "}" ; safe_expression = "@" , "safe" , "(" , expression , [ "," , expression ] , ")" ; expression_path = identifier , { "." , identifier | "[" , expression , "]" } ; (* Control flow *) template_control_flow = if_statement | for_loop | match_statement | break_statement | continue_statement ; if_statement = "@if" , [ "let" , pattern , "=" ] , expression , content_block , { else_if_branch } , [ else_branch ] ; else_if_branch = "else" , "if" , [ "let" , pattern , "=" ] , expression , content_block ; else_branch = "else" , content_block ; for_loop = "@for" , [ identifier , ":" ] , "(" , pattern , "in" , expression , ")" , content_block ; match_statement = "@match" , "(" , expression , ")" , "{" , { match_arm } , "}" ; match_arm = pattern , [ "if" , expression ] , "=>" , content_block , [ "," ] ; break_statement = "@break" , [ ":" , identifier ] , [ ";" ] ; continue_statement = "@continue" , [ ":" , identifier ] , [ ";" ] ; (* Patterns (Rust-like) *) pattern = wildcard_pattern | identifier_pattern | struct_pattern | tuple_pattern | enum_pattern | literal_pattern | range_pattern ; wildcard_pattern = "_" ; identifier_pattern = identifier ; struct_pattern = path , "{" , { field_pattern , [ "," ] } , [ ".." ] , "}" ; field_pattern = identifier , [ ":" , pattern ] ; tuple_pattern = "(" , pattern , { "," , pattern } , [ "," ] , ")" ; enum_pattern = path , [ "(" , { pattern , [ "," ] } , ")" ] ; literal_pattern = literal ; range_pattern = expression , ".." , [ "=" ] , expression ; path = identifier , { "::" , identifier } ; (* Expressions (subset of Rust expressions) *) expression = binary_expression | unary_expression | primary_expression ; binary_expression = expression , binary_operator , expression ; unary_expression = unary_operator , expression ; primary_expression = literal | path | method_call | field_access | index_access | parenthesized_expression | struct_literal | array_literal | closure_expression ; method_call = expression , "." , identifier , "(" , [ argument_list ] , ")" ; field_access = expression , "." , identifier ; index_access = expression , "[" , expression , "]" ; parenthesized_expression = "(" , expression , ")" ; struct_literal = path , "{" , { struct_field_init , [ "," ] } , [ ".." , expression ] , "}" ; struct_field_init = identifier , ":" , expression ; array_literal = "[" , [ expression , { "," , expression } , [ "," ] ] , "]" ; closure_expression = "|" , [ parameter_list ] , "|" , ( expression | content_block ) ; argument_list = expression , { "," , expression } ; (* Operators *) binary_operator = "+" | "-" | "*" | "/" | "%" | "==" | "!=" | "<" | ">" | "<=" | ">=" | "&&" | "||" | "&" | "|" | "^" | "<<" | ">>" ; unary_operator = "!" | "-" | "*" | "&" | "&mut" ; (* Literals *) literal = string_literal | raw_string_literal | char_literal | number_literal | boolean_literal ; string_literal = '"' , { string_char | escape_sequence } , '"' ; raw_string_literal = "r" , { "#" } , '"' , { raw_string_char } , '"' , { "#" } ; char_literal = "'" , ( char | escape_sequence ) , "'" ; number_literal = integer_literal | float_literal ; boolean_literal = "true" | "false" ; integer_literal = decimal_literal | hex_literal | octal_literal | binary_literal ; decimal_literal = digit , { digit | "_" } , [ integer_suffix ] ; hex_literal = "0x" , hex_digit , { hex_digit | "_" } , [ integer_suffix ] ; octal_literal = "0o" , octal_digit , { octal_digit | "_" } , [ integer_suffix ] ; binary_literal = "0b" , binary_digit , { binary_digit | "_" } , [ integer_suffix ] ; float_literal = decimal_literal , "." , { digit } , [ exponent ] , [ float_suffix ] | decimal_literal , exponent , [ float_suffix ] | decimal_literal , float_suffix ; exponent = ( "e" | "E" ) , [ "+" | "-" ] , digit , { digit } ; integer_suffix = "i8" | "i16" | "i32" | "i64" | "i128" | "isize" | "u8" | "u16" | "u32" | "u64" | "u128" | "usize" ; float_suffix = "f32" | "f64" ; (* Character classes *) string_char = ? any character except '"' and '\' ? ; raw_string_char = ? any character ? ; escape_sequence = "\" , ( "n" | "r" | "t" | "\" | "'" | '"' | "0" | "x" , hex_digit , hex_digit | "u" , "{" , { hex_digit } , "}" ) ; char = ? any character except '\'' and '\' ? ; digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ; hex_digit = digit | "a" | "b" | "c" | "d" | "e" | "f" | "A" | "B" | "C" | "D" | "E" | "F" ; octal_digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" ; binary_digit = "0" | "1" ; identifier = ( letter | "_" ) , { letter | digit | "_" } ; letter = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" | "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" ; (* Rust types *) rust_type = primitive_type | reference_type | generic_type | path_type | tuple_type | array_type | slice_type ; primitive_type = "i8" | "i16" | "i32" | "i64" | "i128" | "isize" | "u8" | "u16" | "u32" | "u64" | "u128" | "usize" | "f32" | "f64" | "bool" | "char" | "str" ; reference_type = [ "&" , [ "mut" ] ] , rust_type ; generic_type = path , "<" , rust_type , { "," , rust_type } , ">" ; path_type = identifier , { "::" , identifier } ; tuple_type = "(" , [ rust_type , { "," , rust_type } , [ "," ] ] , ")" ; array_type = "[" , rust_type , ";" , expression , "]" ; slice_type = "[" , rust_type , "]" ; (* Text and comments *) text_content = ? any character sequence not starting with '@' or '<' ? ; comment = template_comment | html_comment ; template_comment = "@*" , { ? any character ? } , "*@" ; html_comment = "" ; (* Language switching *) language_switch = "@`" , language_name , content_block ; language_name = "html" | "css" | "js" | "javascript" ; (* Special constructs *) escape_at = "@@" ; (* Literal @ symbol *) (* Function tags - template function calls using HTML-like syntax *) function_tag = self_closing_function_tag | container_function_tag ; self_closing_function_tag = "<@" , function_path , { function_attribute } , [ "/" ] , ">" ; container_function_tag = "<@" , function_path , { function_attribute } , ">" , { template_node } , "" ; function_path = identifier , [ "::" , identifier ] ; function_attribute = attribute_reference | named_attribute | boolean_attribute ; attribute_reference = "@" , [ "&" ] , identifier ; named_attribute = identifier , "=" , function_attribute_value ; boolean_attribute = identifier ; function_attribute_value = string_literal | "@" , expression | unquoted_value ; unquoted_value = ? sequence of characters not containing whitespace, '>', '/', or '=' ? ; (* Legacy component call syntax - deprecated in favor of function_tag *) component_call = "<@" , component_path , { html_attribute } , [ "/" ] , ">" | "<@" , component_path , { html_attribute } , ">" , { template_node } , "" ; component_path = identifier , { "::" , identifier } ;