-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgoose.ebnf
274 lines (185 loc) · 8.03 KB
/
goose.ebnf
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
digit_excluding_zero = "1".."9" ;
digit = "0" | digit_excluding_zero ;
hex_digit = digit | "a".."f" | "A".."F" ;
octal_digit = "0".."7" ;
binary_digit = "0" | "1" ;
letter = "a".."z" | "A".."Z" ;
number_literal = integer_literal | float_literal ;
numeric_separator = "_" ;
integer_literal = decimal_literal
| octal_literal
| hex_literal
| binary_literal ;
decimal_literal = digit, { [ numeric_separator ], digit } ;
octal_literal = "0o", octal_digit, { [ numeric_separator ], octal_digit } ;
hex_literal = "0x", hex_digit, { [ numeric_separator ], hex_digit } ;
binary_literal = "0b", binary_digit, { [ numeric_separator ], binary_digit } ;
float_literal = [ decimal_literal ], [ ".", [ decimal_literal ] ], [ exponent_part ];
exponent_part = ( "e" | "E" ), [ ( "+" | "-" ) ], decimal_literal ;
boolean_literal = "true" | "false" ;
null_literal = "null" ;
string_literal = '"', { string_character | string_escape | string_expression_interpolation | string_identifier_interpolation }, '"' ;
string_character = ? any character except " or \ ? ;
string_escape = "\\", (
'"' | "\\" | "n" | "r" | "t" | "0" | "$"
| ( "x", hex_digit, hex_digit )
| ( "o", octal_digit, octal_digit, octal_digit )
| ( "u", hex_digit, hex_digit, hex_digit, hex_digit )
| ( "U", hex_digit, hex_digit, hex_digit, hex_digit, hex_digit, hex_digit, hex_digit, hex_digit )
) ;
string_expression_interpolation = "${", expression, "}" ;
string_identifier_interpolation = "$", identifier ;
identifier_start_character = letter | "_" ;
identifier_character = identifier_start_character | digit ;
identifier = identifier_start_character, { identifier_character } ;
overloadable_operator = "+" | "-" | "*" | "/" | "%" | "**"
| ">" | "<" | ">=" | "<="
| "++" | "--"
| "?"
| "<<" | ">>" | "~" | "|" | "^"
| "==" | "!=" | "<=>" ;
operator = overloadable_operator
| "+=" | "-=" | "*=" | "/=" | "%=" | "**="
| "&&" | "||" | "!" | "??"
| "&&=" | "||=" | "??="
| "&=" | "|=" | "^=" | "<<=" | ">>="
| "::" | "->" | "." ;
prefix_operator = "+" | "-" | "!" | "~" ;
postfix_operator = "++" | "--" | "?" ;
file = module ;
module = { statement };
statement = expression
| let_statement
| const_statement
| assign_statement
| native_statement
| labeled_statement
| if_statement
| repeat_statement
| for_statement
| return_statement
| yield_statement
| branch_statement
| struct_statement
| inc_dec_statement
| export_statement
| import_statement
| operator_statement
| macro_statement ;
expression = binary_expression
| unary_expression
| paren_expression
| call_expression
| identifier
| string_literal
| composite_literal
| array_literal
| array_initializer
| selector_expression
| bind_expression
| bracket_selector_expression
| slice_expression
| number_literal
| boolean_literal
| null_literal
| function_expression
| if_expression
| do_expression
| generator_expression
| range_expression
| match_expression ;
let_statement = "let", identifier, [ ":", type_expression ], [ "=", expression ] ;
const_statement = "const", identifier, [ ":", type_expression ], "=", expression ;
assign_statement = identifier, "=", expression ;
native_statement = "native", ( let_statement
| const_statement
| function_expression
| struct_statement
| operator_statement
| generator_expression ) ;
labeled_statement = identifier, ":", statement ;
if_statement = "if", expression, { statement }, [ "else", { statement } ], "end" ;
repeat_statement = repeat_count_statement
| repeat_while_statement
| repeat_forever_statement ;
repeat_count_statement = "repeat", expression, "times", { statement }, "end" ;
repeat_while_statement = "repeat", "while", expression, { statement }, "end" ;
repeat_forever_statement = "repeat", "forever", { statement }, "end" ;
for_statement = "for", identifier, "in", expression, { statement }, "end" ;
return_statement = "return", [ expression ] ;
yield_statement = "yield", [ expression ] ;
branch_statement = ( "break" | "continue" ), [ identifier ] ;
struct_statement = "struct", identifier, "(", [ struct_field, { ",", struct_field } ], ")", [ "init", { statement }, "end" ] ;
struct_field = [ ":" ], identifier, [ ":", type_expression ], [ "=", expression ] ;
inc_dec_statement = identifier, ( "++" | "--" ) ;
export_statement = "export", (
statement
| ( "{", [ export_list_item, { ",", export_list_item } ], "}" )
| module_spec
) ;
export_list_item = identifier
| ( identifier, "as", identifier ) ;
import_statement = "import", module_spec ;
module_spec = specifier, [
( "as", identifier )
| ( "show", module_spec_show )
] ;
module_spec_show = "..." | ( "{" , [ module_spec_list_item, { ",", module_spec_list_item } ], "}" ) ;
module_spec_list_item = identifier
| ( identifier, "as", identifier )
| ( "...", identifier ) ;
specifier = string_literal ;
operator_statement = "operator", identifier, overloadable_operator, "(", [ function_parameter, { ",", function_parameter } ], ")", [ ":", type_expression ], { statement }, "end" ;
binary_expression = expression, operator, expression ;
unary_expression = ( prefix_operator, expression )
| ( expression, postfix_operator ) ;
paren_expression = "(", expression, ")" ;
call_expression = expression, "(", [ expression, { ",", expression } ], ")" ;
(* TODO: kv pairs in args *)
selector_expression = expression, ".", identifier ;
bind_expression = expression, "::", identifier ;
bracket_selector_expression = expression, "[", expression, "]" ;
slice_expression = expression, "[", (
( expression, ":", expression )
| ( ":", expression )
| ( expression, ":" )
), "]" ;
composite_literal = "{", [ composite_literal_item, { ",", composite_literal_item } ], "}" ;
composite_literal_item = ( identifier | ( "[", expression, "]" ) ), ":", expression ;
array_literal = "[", [ expression, { ",", expression } ], "]" ;
array_initializer = "[", expression, ";", expression, "]" ;
function_expression = [ "memo" ], "fn", [ [ identifier, "." ], identifier ], "(", [ function_parameter, { ",", function_parameter } ], ")", [ ":", type_expression ], (
( { statement }, "end" )
| ( "->", expression )
) ;
function_parameter = [ ":" ], identifier, [ ":", type_expression ], [ "=", expression ] ;
if_expression = "if", expression, "then", expression, [ "else", expression ] ;
do_expression = "do", { statement }, "end" ;
generator_expression = [ "memo" ], "generator", [ [ identifier, "." ], identifier ], "(", [ function_parameter, { ",", function_parameter } ], ")", [ ":", type_expression ], { statement }, "end" ;
range_expression = expression, "to", expression, [ "step", expression ] ;
match_expression = "match", expression, [ match_arm, { match_arm } ], "end" ;
match_arm = match_clause, [ match_guard ], "->", expression ;
match_guard = "if", expression ;
match_clause = match_pattern | "else" ;
match_pattern = number_literal | string_literal | identifier
| match_binding
| match_array
| match_composite
| match_type
| match_range ;
match_binding = "$", identifier ;
match_array = "[", [ match_tuple_item, { ",", match_tuple_item } ], "]" ;
(* TODO: flesh out *)
match_tuple_item = match_pattern ;
match_composite = "{", [ match_composite_item, { ",", match_composite_item } ], "}" ;
match_composite_item = ( identifier | ( "[", expression, "]" ) ), ":", match_pattern ;
match_type = type_expression, "(", match_binding, ")" ;
match_range = match_pattern, "to", match_pattern ;
macro_statement = "macro", identifier, "!", "(", [ identifier, { ",", identifier } ], ")", "->", expression ;
procedural_macro_statement = "procmacro", identifier, "!", "(", [ identifier, { ",", identifier } ], ")", { statement }, "end" ;
macro_invocation = identifier, "!", "(", { token_tree }, ")" ;
token_tree = ( ? any token ? - ( "(" | ")" | "{" | "}" | "[", "]" ) ) | token_group ;
token_group = ( "(", { token_tree }, ")" )
| ( "{", { token_tree }, "}" )
| ( "[", { token_tree }, "]" ) ;
type_expression = "TODO: type_expression" ;