Goal = translation_unit ; cast_expression = "\(" WS boolean_expression WS "\)" WS "cast" WS type ; translation_unit = WS unorderd_list_part WS ; unorderd_list_part = import WS unorderd_list_part | function WS unorderd_list_part | type_def line_end WS unorderd_list_part | adt_def line_end WS unorderd_list_part | if_comp WS unorderd_list_part | simple_passthrough WS unorderd_list_part | declaration_statement line_end WS unorderd_list_part | compiler_intrinsic line_end WS unorderd_list_part | import | function | type_def line_end | adt_def line_end | if_comp | simple_passthrough | declaration_statement line_end | compiler_intrinsic line_end ; type = "ref" WS pre_reffed | pre_reffed ; pre_reffed = "\*" WS pre_reffed | "void" | "bool" | "char" | "uchar" | "short" | "ushort" | "int" | "uint" | "long" | "ulong" | "float" | "double" | scoped_identifier | scoped_identifier WS template_inst | function_type ; function_type = "fun" WS "\(" WS opt_type_list WS "\)" WS ":" WS type | "run" WS "\(" WS opt_type_list WS "\)" WS ":" WS type ; dec_type = ":" WS type ; opt_type_list = type_list | ; template_inst = "<" WS type_list WS ">" ; type_list = type_list WS "," WS type | type ; template_dec = "<" WS template_param_list WS ">" ; template_param_list = template_param_list WS "," WS template_param | template_param ; template_param = identifier WS traits | identifier ; import = "import" WS identifier line_end | "import" WS identifier WS ":" WS "\*" line_end | "import" WS identifier WS ":" WS identifier_list line_end ; identifier_list = identifier | identifier WS "," WS identifier_list ; # all for optional semicolons line_break = " +" ; # why use line_white here but not below? who knows. It's wayy faster this way. Or maybe when I changed it there was a typing mistake. Noone knows. line_white = "( | )+" ; actual_white = line_white | line_break | line_break actual_white | line_white actual_white ; # Why is WS comment necessary? The null case SHOULD handle it, I think. I'm just a tad worred...... WS = actual_white | WS comment WS | WS comment | ; # cpp_comment lets us do stuff like ending a statement with a cpp comment - c comments already work as they don't eat the return maybe_line_white = "( | )+" | c_comment | maybe_line_white c_comment | maybe_line_white "( | )+" | ; line_end = maybe_line_white ";" | maybe_line_white line_break | maybe_line_white cpp_comment ; #line_end = maybe_line_white ";" | maybe_line_white line_break | maybe_line_white cpp_comment | WS c_comment line_end ; # line_end = "( | )+" ";" | "( | )+" line_break | "( | )+" cpp_comment | ";" | line_break | cpp_comment ; # line_end = WS ";" | WS line_break | WS cpp_comment ; # line_end = "( | )+" ending | ending ; # ending = ";" | line_break | cpp_comment ; if_comp = "__if_comp__" WS identifier WS statement ; #if_comp = "__if_comp__" WS identifier WS if_comp_pred ; #if_comp_pred = code_block | simple_passthrough ; simple_passthrough = "simple_passthrough" WS passthrough_params WS triple_quoted_string ; passthrough_params = "\(" WS in_passthrough_params WS ":" WS out_passthrough_params WS ":" WS opt_string WS "\)" | ; in_passthrough_params = opt_param_assign_list ; out_passthrough_params = opt_param_assign_list ; opt_param_assign_list = param_assign_list | ; param_assign_list = param_assign WS "," WS param_assign_list | param_assign ; param_assign = identifier WS "=" WS identifier | identifier ; opt_string = string | ; triple_quoted_string = "\"\"\"((\"\"(`|[0-9]|-|=| |[a-z]|\[|]|\\|;|'| |,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|[A-Z]|{|}|\||:|<|>|\?| )+)|(\"(`|[0-9]|-|=| |[a-z]|\[|]|\\|'| |,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|[A-Z]|{|}|\||:|<|>|\?| )+))*(`|[0-9]|-|=| |[a-z]|\[|]|\\|;|'| |,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|[A-Z]|{|}|\||:|<|>|\?| )*(((`|[0-9]|-|=| |[a-z]|\[|]|\\|;|'| |,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|[A-Z]|{|}|\||:|<|>|\?| )+\")|((`|[0-9]|-|=| |[a-z]|\[|]|\\|;|'| |,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|[A-Z]|{|}|\||:|<|>|\?| )+\"\")|((`|[0-9]|-|=| |[a-z]|\[|]|\\|;|'| |,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|[A-Z]|{|}|\||:|<|>|\?| )+))*\"\"\"" ; #identifier = alpha_alphanumeric ; identifier = augmented_alpha_alphanumeric ; scope_op = ":" ":" ; scoped_identifier = scoped_identifier WS scope_op WS identifier | identifier ; #Note that to prevent confilct with nested templates (T>) right_shift is a nonterminal contructed as follows right_shift = ">" ">" ; overloadable_operator = "\+" | "-" | "\*" | "/" | "%" | "^" | "&" | "\|" | "~" | "!" | "," | "=" | "\+\+" | "--" | "<<" | "<" | ">" | "<=" | ">=" | right_shift | "==" | "!=" | "&&" | "\|\|" | "\+=" | "-=" | "/=" | "%=" | "^=" | "&=" | "\|=" | "\*=" | "<<=" | ">>=" | "->" | "\(" "\)" | "\[]" | "\[]=" ; func_identifier = identifier | identifier overloadable_operator ; # allow omitting of return type (automatic void) # HACKY - typed_return has it's own internal whitespace as to not make WS typed_return-reduces to null WS ambigious typed_return = WS dec_type | ; function = "ext" WS "fun" WS func_identifier WS "\(" WS opt_typed_parameter_list WS "\)" typed_return | "fun" WS func_identifier WS template_dec WS "\(" WS opt_typed_parameter_list WS "\)" typed_return WS statement | "fun" WS func_identifier WS "\(" WS opt_typed_parameter_list WS "\)" typed_return WS statement ; lambda = "fun" WS "\(" WS opt_typed_parameter_list WS "\)" typed_return WS statement ; opt_typed_parameter_list = typed_parameter_list | typed_parameter_list WS "," WS "..." | ; typed_parameter_list = typed_parameter_list WS "," WS typed_parameter | typed_parameter ; typed_parameter = identifier WS dec_type ; opt_parameter_list = parameter_list | ; parameter_list = parameter_list WS "," WS parameter | parameter ; parameter = boolean_expression ; obj_nonterm = "obj" | "uni" ; type_def = obj_nonterm WS identifier WS template_dec WS "{" WS declaration_block WS "}" | obj_nonterm WS identifier WS "{" WS declaration_block WS "}" | obj_nonterm WS identifier WS template_dec WS traits WS "{" WS declaration_block WS "}" | obj_nonterm WS identifier WS traits WS "{" WS declaration_block WS "}" ; declaration_block = declaration_statement line_end WS declaration_block | function WS declaration_block | declaration_statement line_end | function | ; traits = "\(" WS trait_list WS "\)" ; trait_list = trait_list WS "," WS scoped_identifier | scoped_identifier ; adt_nonterm = "adt" ; adt_def = adt_nonterm WS identifier WS "{" WS adt_option_list WS "}" | adt_nonterm WS identifier WS template_dec WS "{" WS adt_option_list WS "}" ; adt_option_list = adt_option | adt_option WS "," WS adt_option_list ; adt_option = identifier | identifier WS dec_type ; if_statement = "if" WS boolean_expression WS statement | "if" WS boolean_expression WS statement WS "else" WS statement ; match_statement = "match" WS "\(" WS boolean_expression WS "\)" WS "{" WS case_statement_list WS "}" ; case_statement_list = case_statement WS case_statement_list | case_statement ; case_statement = scoped_identifier WS "\(" WS identifier WS "\)" WS statement | scoped_identifier WS "\(" WS "\)" WS statement ; while_loop = "while" WS boolean_expression WS statement ; for_loop = "for" WS "\(" WS statement WS boolean_expression line_end WS statement WS "\)" WS statement ; return_statement = "return" | "return" WS boolean_expression ; code_block = "{" WS statement_list WS "}" | "{" WS "}" ; statement_list = statement_list WS statement | statement ; statement = if_statement | match_statement | while_loop | for_loop | return_statement line_end | boolean_expression line_end | assignment_statement line_end | declaration_statement line_end | code_block | if_comp | simple_passthrough | break_statement | continue_statement | defer_statement ; break_statement = "break" ; continue_statement = "continue" ; defer_statement = "defer" WS statement ; function_call = unarad "\(" WS opt_parameter_list WS "\)" ; compiler_intrinsic = "#" identifier WS "\(" WS opt_parameter_list WS "\)" | "#" identifier WS "<" WS type_list WS ">" ; boolean_expression = boolean_expression WS "\|\|" WS and_boolean_expression | and_boolean_expression ; and_boolean_expression = and_boolean_expression WS "&&" WS bitwise_or | bitwise_or ; bitwise_or = bitwise_or WS "\|" WS bitwise_xor | bitwise_xor ; bitwise_xor = bitwise_xor WS "^" WS bitwise_and | bitwise_and ; bitwise_and = bitwise_and WS "&" WS bool_exp | bool_exp ; bool_exp = expression WS comparator WS expression | expression ; comparator = "==" | "<=" | ">=" | "!=" | "<" | ">" ; expression = expression WS "<<" WS term | expression WS right_shift WS shiftand | shiftand ; shiftand = shiftand WS "-" WS term | shiftand WS "\+" WS term | term ; term = term WS "/" WS factor | term WS "\*" WS factor | term WS "%" WS factor | factor ; factor = "\+\+" WS unarad | unarad WS "\+\+" | "--" WS unarad | unarad WS "--" | "\+" WS unarad | "-" WS unarad | "!" WS unarad | "~" WS unarad | "\*" WS unarad | "&" WS unarad | unarad ; unarad = number | scoped_identifier | scoped_identifier WS template_inst | access_operation | function_call | compiler_intrinsic | bool | string | character | "\(" WS boolean_expression WS "\)" | unarad WS "\[" WS expression WS "]" | lambda | cast_expression ; cast_expression = "\(" WS boolean_expression WS "\)" WS "cast" WS type ; number = integer | floating_literal ; access_operation = unarad WS "." WS identifier | unarad WS "->" WS identifier | unarad WS "." WS identifier WS template_inst | unarad WS "->" WS identifier WS template_inst ; assignment_statement = factor WS "=" WS boolean_expression | factor WS "\+=" WS boolean_expression | factor WS "-=" WS boolean_expression | factor WS "\*=" WS boolean_expression | factor WS "/=" WS boolean_expression | factor WS "^=" WS boolean_expression ; # if it's being assigned to, we allow type inferencing declaration_statement = "var" WS identifier WS "=" WS boolean_expression | "var" WS identifier WS dec_type WS "=" WS boolean_expression | "var" WS identifier WS dec_type | "ext" WS "var" WS identifier WS dec_type | "var" WS identifier WS "." WS identifier WS "\(" WS opt_parameter_list WS "\)" WS dec_type ; hexadecimal = "0x([0-9]|[a-f])+" ; integer = "[0-9]+u?(c|s|l)?" | hexadecimal ; floating_literal = "[0-9]+.[0-9]+(f|d)?" ; bool = "true" | "false" ; character = "'(`|[0-9]|-|=|(\\t)|[a-z]|\[|]|(\\\\)|;|(\\')|(\\n)|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|[A-Z]|{|}|\||:|\"|<|>|\?| |(\\0))'" ; keywords_also_identifiers = "obj" | "def" | "fun" | "run" | "var" | "ref" | "adt" | "cast" | "import" | "simple_passthrough" ; alpha_alphanumeric = "([a-z]|[A-Z]|_)([a-z]|[A-Z]|_|[0-9])*" ; augmented_alpha_alphanumeric = alpha_alphanumeric augmented_alpha_alphanumeric | keywords_also_identifiers augmented_alpha_alphanumeric | alpha_alphanumeric | keywords_also_identifiers ; # note the hacks around \things. Hmm, I feel like it actually shouldn't be like this. Added \\\* because I want to come back later string = triple_quoted_string | "\"([#-[]| |[]-~]|(\\\\)|(\\n)|(\\t)|(\\\*)|(\\0)| |[ -!]|(\\\"))*\"" ; comment = cpp_comment | c_comment ; cpp_comment = "//[ -~]* " ; c_comment = "(/\*/*\**(([ -)]|[0-~]|[+-.]| | )/*\**)+\*/)|(/\*\*/)" ;