formula := space? expression+ expression = string_join | comparison | arithmetic | thing thing = function | brackets | any_reference | string | percentage | number | boolean | prefix | named_reference argument = expression | null function := /[A-Z]+/ `'(' space argument? (space `',' space argument)* space `')' brackets := `'(' space expression+ space `')' string_join := (arithmetic | thing) (space `"&" space (arithmetic | thing))+ arithmetic := thing (space operator space thing)+ comparison := (arithmetic | thing) space comparator space (arithmetic | thing) comparator := '>=' | '<=' | '<>' | '>' | '<' | '=' string := `'"' /(""|[^"])*/ `'"' any_reference = external_reference | any_internal_reference any_internal_reference = table_reference | local_table_reference | quoted_sheet_reference | sheet_reference | sheetless_reference percentage := /[-+]?[0-9]+\.?[0-9]*/ `'%' number := /[-+]?[0-9]+\.?[0-9]*([eE][-+]?[0-9]+)?/ operator := '+' | '-' | '/' | '*' | '^' external_reference := /\[\d+\]!?/ any_internal_reference table_reference := table_name `'[' (range_structured_reference | complex_structured_reference | simple_structured_reference) `']' local_table_reference := `'[' (range_structured_reference | complex_structured_reference | overly_structured_reference | simple_structured_reference) `']' table_name = /[.\p{Word}]+/ range_structured_reference = /\[[^\u005d]*\],\[[^\u005d]*\]:\[[^\u005d]*\]/ complex_structured_reference = /\[[^\u005d]*\],\[[^\u005d]*\]/ overly_structured_reference = `'[' simple_structured_reference `']' simple_structured_reference = /[^\u005d]*/ named_reference := /[\p{Word}#][\p{Word}.!]*/ quoted_sheet_reference := single_quoted_string `'!' (sheetless_reference | named_reference) sheet_reference := /[\p{Word}][\p{Word}_.]+/ `'!' (sheetless_reference | named_reference) single_quoted_string = `"'" /[^']*/ `"'" sheetless_reference = column_range | row_range | area | cell column_range := column `':' column row_range := row `':' row area := reference `':' reference cell := reference row = /\$?\d+/ column = /\$?[A-Za-z]{1,3}/ reference = /\$?[A-Za-z]{1,3}\$?[0-9]+(?![0-9A-Za-z_])/ boolean = boolean_true | boolean_false boolean_true := `'TRUE' boolean_false := `'FALSE' prefix := /[-+]/ thing space = `/[ \n]*/ null := &','