-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathebnf.txt
55 lines (55 loc) · 3.17 KB
/
ebnf.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// use this to test, and this must pass at all times
// https://bnfplayground.pauliankline.com/
<all> ::= (<top_decl>)*
<top_decl> ::= "pub "? ("const " | "let " | "type " | "impl ") <destructure> (":" <signature>)? " = " (<trait> | <fn> | <struct> | <tag> | <import> | <error> | <reassign> | <expr> | <enum>)
<import> ::= "import " <chars>
<trait> ::= "trait " "{ " (<top_decl>)* " }"
<signature> ::= <val_type> | ("&" | "*")? ("[" <signature> "]" | <ident> ("." <ident>)* | <fn_type>)
<fn_type> ::= "fn" "(" <type_args> ")" ("void" | <signature>)
<type_args> ::= (<type_arg> ("," <type_arg>)*)?
<type_arg> ::= ("self " (":" <signature>)?) | <signature>
<fn> ::= "fn " "(" <args>? ") " <block>
<struct> ::= "struct " "{ " <declarators>? "}"
<error> ::= "error " ("| " <ident>)+
<if> ::= "if " "(" <or> ")" (<fn> | <block>) <else_if>* <else>?
<else_if> ::= "else " "if " "(" <or> ")" (<fn> | <block>)
<else> ::= "else " (<fn> | <block>)
<for> ::= "for " "(" <expr> ")" (<fn> | <block>)
<while> ::= "while " "(" <expr> ")" (<fn> | <block>)
<match> ::= "match " "(" <expr> ")" "{ " <arm>+ "}"
<arm> ::= <expr> "=> " (<fn> | <block> | <or>)
<tag> ::= "tag " ("| " <ident> (":" <signature>)?)+
<enum> ::= "enum" "(" <val_type> ")" ("| " <ident> ("=" <expr>)?)+
<declarators> ::= (<declarator>)*
<declarator> ::= "pub "? <ident> (":" <signature>)?
<destructure> ::= ("{ " <ident> ("," <ident>)* " }") | <ident>
<args> ::= (<arg> ("," <arg>)*)?
<arg> ::= ("self " (": " <signature>)?) | <ident> (":" <signature>)?
<inner_decl> ::= ( "const " | "let ") <destructure> (":" <signature>)? "= " <expr>
<reassign> ::= <access> ("= " <expr>)?
<block> ::= "{ " (<inner_decl> | <for> | <while> | <if> | <reassign> | <match>)* (<return> | <break>)? "}"
<return> ::= "return " <expr>?
<break> ::= "break " <expr>?
<expr> ::= <block> | <match> | <or>
<or> ::= <and> ("|| " <and>)*
<and> ::= <equality> ("&& " <equality>)*
<equality> ::= <cmp> (("!= " | "== ") <cmp>)*
<cmp> ::= <low_bin> ((">" | ">=" | "<" | "<=") <low_bin>)*
<low_bin> ::= <high_bin> (("+" | "-") <high_bin>)*
<high_bin> ::= <unary> (("*" | "/" | ".." | "%" | "as") <unary>)*
<unary> ::= (("try" | "copy" | "clone" | "!" | "-" | "&" | "*") <unary>) | <access>
<array_decl> ::= "[" (<or> ("," <or>)*)? "]"
<access> ::= <terminal> ("?" | <struct_body> | <invoke> | <array_access> | <call>)* <catch>?
<catch> ::= "catch" "(" <arg>? ")" <block>
<array_access> ::= "[" <expr> "]"
<invoke> ::= "." <ident>
<call> ::= "(" (<or> ("," <or>)*)? ")"
<struct_body> ::= "{" (<ident> ":" <or> ("," <ident> ":" <or>))? "}"
<terminal> ::= "_" | "true " | "false " | "undefined " | "self " | "never " | <num> | <ident> | <chars> | <array_decl> | <anon_fn> | "(" <expr> ")"
<anon_fn> ::= "fn " "(" <args>? ") " <block>
<ident> ::= ([a-z] | [A-Z]) ([A-Z] | [a-z] | [0-9] | "_")*
<num> ::= ([1-9] [0-9]* "."? ([0-9])+) | [0-9] "." [1-9]+ | [0-9]
<chars> ::= "\"" [a-z]* "\""
<val_type> ::= "i32" | "u32" | "i64" | "u64" | "i16" | "u16" | "u8" | "i8" | "bit" | "f64" | "d64" | "f32" | "d32" | "d128" | "f128" | "isize" | "usize" | "char" | "bool" | "any" | "scalar" | "utf8" | "utf16" | "utf32" | "utf64" | "sized"
// illegal ebnf but actual implementation
<chars> ::= #[regex(r#""([^"\\]|\\t|\\u|\\n|\\")*""#)]