Skip to content

Instantly share code, notes, and snippets.

@charbelrami
Created January 26, 2024 13:41
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save charbelrami/f56a07e5347d4779143065e676480de4 to your computer and use it in GitHub Desktop.
Save charbelrami/f56a07e5347d4779143065e676480de4 to your computer and use it in GitHub Desktop.
Elm EBNF grammar
program = [ comment ], [ "port" ], "module", module_name, "exposing", "(", exposed_list, ")", { import_statement }, { declaration }, { comment };
module_name = identifier, { ".", identifier }, [ comment ];
exposed_list = identifier | "(", identifier, { ",", identifier }, ")", [ comment ] | "..";
import_statement = "import", module_name, [ import_alias ], [ "exposing", "(", exposed_list, ")" ], [ comment ];
import_alias = "as", identifier, [ comment ];
declaration = type_declaration
| type_alias_declaration
| port_declaration
| function_declaration
| value_declaration, [ comment ];
type_declaration = "type", identifier, [ type_parameters ], "=", union_variant, { "|", union_variant }, [ comment ];
union_variant = constructor, { type }, [ comment ];
constructor = identifier, [ comment ];
type_alias_declaration = "type", "alias", identifier, [ type_parameters ], "=", type, [ comment ];
port_declaration = "port", identifier, [ ":", type ], [ comment ];
function_declaration = identifier, [ type_annotation ], function_arguments, "=", expression, [ comment ];
type_annotation = ":", type, [ comment ];
function_arguments = identifier, { identifier }, [ comment ];
value_declaration = identifier, "=", expression, [ comment ];
type = simple_type
| function_type
| record_type
| tuple_type
| parametric_type
| list_type
| type_var
| parenthesized_type;
simple_type = identifier;
function_type = type, "->", type, [ comment ];
record_type = "{", [ field, { ",", field } ], "}", [ comment ];
field = identifier, ":", type, [ comment ];
tuple_type = "(", type, ",", type, { ",", type }, ")", [ comment ];
parametric_type = identifier, type_parameters;
list_type = "List", type;
type_var = identifier;
parenthesized_type = "(", type, ")", [ comment ];
type_parameters = " ", type, { " ", type }, [ comment ];
expression = literal
| identifier
| function_application
| lambda_expression
| "(", expression, ")"
| expression, binary_operator, expression
| "if", expression, "then", expression, "else", expression
| "let", declarations, "in", expression
| record_expression
| list_expression
| case_expression
| tuple_expression
| operator_as_function
| record_update
| tagged_union_constructor, [ comment ];
function_application = expression, expression, [ comment ];
lambda_expression = "\\", pattern, "->", expression, [ comment ];
record_expression = "{", [ field_expression, { ",", field_expression } ], "}", [ comment ];
field_expression = identifier, "=", expression, [ comment ];
list_expression = "[", [ expression, { ",", expression } ], "]", [ comment ];
case_expression = "case", expression, "of", { pattern, "->", expression }, [ comment ];
tuple_expression = "(", expression, ",", expression, { ",", expression }, ")", [ comment ];
operator_as_function = "(", binary_operator, ")", [ comment ];
record_update = "{", identifier, "|", [ field_expr, { ",", field_expr } ], "}", [ comment ];
tagged_union_constructor = constructor, expression, [ comment ];
pattern = identifier | "_" | literal | "(", pattern, ")" | record_pattern | tuple_pattern | list_pattern | alias_pattern | tagged_union_pattern, [ comment ];
record_pattern = "{", [ pattern_field, { ",", pattern_field } ], "}", [ comment ];
pattern_field = identifier, [ "=", pattern ], [ comment ];
tuple_pattern = "(", pattern, ",", pattern, { ",", pattern }, ")", [ comment ];
list_pattern = "[", [ pattern, { ",", pattern } ], "]", [ comment ];
alias_pattern = identifier, "@", pattern, [ comment ];
tagged_union_pattern = constructor, [ pattern ], [ comment ];
declarations = { declaration }, [ comment ];
binary_operator = "+" | "-" | "*" | "/" | "&&" | "||" | "==" | "<" | ">" | "<=" | ">=" | "::" | "|>";
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");
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";
literal = number_literal | string_literal | char_literal | "True" | "False";
number_literal = digit, { digit | "_" };
string_literal = """", { string_character }, """";
char_literal = "'", character, "'";
string_character = ? any character except newline and the enclosing quote marks, including escape sequences ?;
character = printable_except_quote;
printable_except_quote = ? any printable character except the enclosing quote marks (' and ") ?;
single_line_comment = "--", { all_characters_except_newline };
multi_line_comment = "{-", { multi_line_comment_content | multi_line_comment }, "-}";
multi_line_comment_content = ? all characters including newlines except for sequences {- and -} ?;
comment = single_line_comment | multi_line_comment;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment