-
Notifications
You must be signed in to change notification settings - Fork 0
/
fender.bnf
85 lines (73 loc) · 3.56 KB
/
fender.bnf
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
delimitedList<elem, delim, whitespace> ::= elem (whitespace? delim whitespace? elem)*
wrappedDelimitedList<begin, end, elem, delim, whitespace> ::= begin whitespace? delimitedList<elem, delim, whitespace>? whitespace? end
sep! ::= [ \t]+
newLine! ::= <nl> | <eof>
break! ::= sep? ((";" | comment? newLine) sep?)+
lineBreak! ::= sep? comment? (newLine sep?)+
lineSep! ::= (lineBreak | sep)+
comment ::= "#" [^\n]*
root! ::= (break | sep)? (statement break)* statement? break?
statement ::= (plugin | import | export | functionDeclaration | structDeclaration | declaration | assignment | return | expr) sep? comment?
return ::= "return" ("@" name)? (lineSep expr)?
declaration ::= "$" sep? name sep? "=" lineSep? expr
assignOp ::= [-+/*%^]
assignment ::= expr sep? assignOp? "=" lineSep? expr
import ::= "@import" sep filename ("::" importFields)?
filename ::= ([a-z] | [A-Z] | [0-9] | [./_])+
importFields ::= "*" | name ("::" importFields)? | importTargetMulti
importTargetMulti ::= wrappedDelimitedList<"(", ")", importFields, ",", sep>
export ::= "@export" sep ("*" | codeBody)
plugin ::= "@plugin" sep filename
binaryOperator ::= "||" | "&&" | "==" | "<=" | ">=" | ".." "="? | [-+*/^<>]
unaryOperator ::= [-!]
expr ::= ("`" label lineSep?)? or
label ::= "" name
enclosedExpr ::= "(" lineSep? expr lineSep? ")"
term ::= (unaryOperator sep?)* value sep? tailOperationChain?
lambdaParameter ::= "$"
value ::= literal | enclosedExpr | name | lambdaParameter
cmpOp ::= ">=" | "<=" | "==" | "!=" | [<>]
pow! ::= delimitedList<term, "^", lineSep>
mul! ::= delimitedList<pow, [*%/], lineSep>
add! ::= delimitedList<mul, [-+], lineSep>
range! ::= delimitedList<add, ".." "="?, lineSep>
cmp! ::= delimitedList<range, cmpOp, lineSep>
and! ::= delimitedList<cmp, "&&", lineSep>
or! ::= delimitedList<and, "||", lineSep>
alpha ::= [a-z] | [A-Z]
alphanum ::= [a-z] | [A-Z] | [0-9] | "_"
name ::= ("_" | alpha) alphanum*
literal ::= null | float | int | boolean | string | char | list | hashMap | closure | structInit
int ::= "-"? [0-9]+
list ::= wrappedDelimitedList<"[", "]", expr, ",", lineSep>
mapEntry ::= expr lineSep? ":" lineSep? expr
emptyMap ::= "[" lineSep? ":" lineSep? "]"
hashMap ::= emptyMap | wrappedDelimitedList<"[", "]", mapEntry, ",", lineSep>
float ::= "-"? ([0-9]+)? "." [0-9]+
strChar ::= [^"{]
string ::= "\"" (escapeSequence | strExpr | strChar)* "\""
strExpr ::= "{" sep? expr sep? "}"
escapeSequence ::= "\\" ("u" ([A-F] | [0-9]){4} |[^])
boolean ::= "true" | "false"
null ::= "null"
innerChar ::= [^]
char ::= "'" (escapeSequence | innerChar) "'"
invoke ::= invokeArgs | codeBody
invokeArgs ::= wrappedDelimitedList<"(", ")", expr, ",", lineSep>
structBody ::= wrappedDelimitedList<"{", "}", arg, ",", lineSep>
structDeclaration ::= "struct" sep? name lineSep? structBody
structEntry ::= name lineSep? ":" lineSep? expr
structInit ::= name "(" lineSep? delimitedList<structEntry, ",", lineSep?> lineSep? ")"
arg ::= name (sep? typeAnnotation)?
typeAnnotation ::= ":" lineSep? name
codeBody ::= "{" lineSep? (statement break)* statement? lineSep? "}"
optionalArgs ::= "[" delimitedList<arg, ",", sep> vararg? "]"
vararg ::= "..."
args ::= ("(" sep? delimitedList<arg, ",", sep> sep? ("," sep? optionalArgs)? sep? ")") | "(" sep? optionalArgs sep? ")"
closure ::= args? lineSep? codeBody
functionDeclaration ::= "fn" sep? name lineSep? args lineSep? ("=" lineSep? expr | codeBody)
fieldAccess ::= "::" lineSep? name
receiverCall ::= "." lineSep? name sep? invoke
index ::= "[" expr "]"
tailOperation ::= (sep? invoke) | (lineSep? (receiverCall | index | fieldAccess))
tailOperationChain ::= tailOperation (tailOperation)*