1#![allow(non_snake_case)]
2
3use crate::cst;
4use crate::types::rule::Rule;
5use crate::types::Span;
6use crate::types::{Cst, Vectorize};
7
8macro_rules! vectorize {
17 ($($e:expr),*) => {
18 vec![$($e.vectorize()),*].vectorize()
19 };
20}
21
22peg::parser! {
23 grammar satysfi_parser() for str {
24 use peg::ParseLiteral;
25 rule _() = spaces()
29 rule __() = comment()*
32
33 pub rule spaces() -> Vec<Span> =
34 ranges:([' ' | '\t' | '\n' | '\r'] {None} / range:comment() {Some(range)})*
35 {vectorize![ranges]}
36
37 rule p() -> usize = pos:position!() {pos}
39
40 rule DUMMY() = !"DUMMY" "DUMMY"
42 rule EOF() = ![_]
44
45 rule NON_LF() = !['\r' | '\n'] [_]
47
48 rule ASCII_DIGIT() = quiet!{['0'..='9']} / expected!("number")
50 rule ASCII_ALPHANUMERIC_HYPHEN() = quiet!{['a'..='z' | 'A'..='Z' | '0'..='9' | '-']} / expected!("alphabet, number, or hyphen")
51
52 rule kwd(word: &'static str) = ##parse_string_literal(word) !ASCII_ALPHANUMERIC_HYPHEN()
56
57 pub rule misc() -> Cst = DUMMY() { cst!(misc (0, 0) []) }
58
59 rule comment() -> Span = "%" s:p() comment_inner() e:p() ['\r' | '\n'] { Span{ start: s, end: e } }
61 rule comment_inner() = NON_LF()*
62
63 pub rule program() -> Cst = p:(program_saty() / program_satyh()) EOF() {p}
66
67 pub rule program_saty() -> Cst =
68 s:p() _
69 stage:header_stage()? _
70 headers:headers() _
71 pre:(pre:preamble() _ kwd("in") {pre})? _
72 expr:expr() _
73 e:p()
74 { cst!(program_saty (s, e) [stage, headers, pre, expr]) }
75
76 pub rule program_satyh() -> Cst =
77 s:p() _
78 stage:header_stage()? _
79 headers:headers() _
80 pre:preamble() _
81 e:p()
82 { cst!(program_satyh (s, e) [stage, headers, pre]) }
83
84 rule header_stage() -> Cst =
87 "@stage:" [' ' | '\t']* stg:stage() [' ' | '\t']* ['\r' | '\n']
88 {stg}
89
90 pub rule stage() -> Cst =
91 s:p() ("0" / "1" / "persistent") e:p()
92 { cst!(stage (s, e) []) }
93
94 pub rule headers() -> Cst =
95 s:p() v:(h: header() _ {h})* e:p()
96 { cst!(headers (s, e) [v]) }
97
98 rule header() -> Cst = header_require() / header_import() / dummy_header()
99
100 pub rule header_require() -> Cst =
101 s:p() "@require:" [' ' | '\t']* pkg:pkgname() ['\n' | '\r'] e:p()
102 { cst!(header_require (s, e) [pkg]) }
103
104 pub rule header_import() -> Cst =
105 s:p() "@import:" [' ' | '\t']* pkg:pkgname() ['\n' | '\r'] e:p()
106 { cst!(header_import (s, e) [pkg]) }
107
108 pub rule dummy_header() -> Cst =
109 s:p()
110 (
111 ("@require:" / "@import") [' ' | '\t']* ['\n' | '\r']
112 / "@" var_ptn() ['\n' | '\r']
113 / "@" ['\n' | '\r']
114 )
115 e:p()
116 { cst!(dummy_header (s, e) []) }
117
118 pub rule pkgname() -> Cst =
119 s:p() NON_LF()+ e:p()
120 { cst!(pkgname (s, e) []) }
121
122 pub rule preamble() -> Cst =
125 s:p() stmts:(statement() ++ _) e:p()
126 { cst!(preamble (s, e) [stmts]) }
127
128 #[cache]
129 rule statement() -> Cst =
130 let_stmt()
131 / let_rec_stmt()
132 / let_inline_stmt()
133 / let_block_stmt()
134 / let_math_stmt()
135 / let_mutable_stmt()
136 / type_stmt()
137 / module_stmt()
138 / open_stmt()
139 / dummy_stmt()
140
141 pub rule let_stmt() -> Cst =
142 s:p() kwd("let") _ pat:pattern() _ arg:let_stmt_argument()? _ "=" _ expr:expr() e:p()
143 { cst!(let_stmt (s, e) [pat, arg, expr]) }
144
145 rule let_stmt_argument() -> Vec<Cst> =
146 s:p() ":" _ t:type_expr() _ "|" _ a:(arg() ++ _) e:p() { vectorize![t, a] }
148 / s:p() ":" _ t:type_expr() e:p() { vectorize![t] }
149 / s:p() "|"? _ a:(arg() ++ _) e:p() { vectorize![a] }
150
151 pub rule let_rec_stmt() -> Cst =
152 s:p() kwd("let-rec") _ inner:let_rec_inner() _ inners:(let_rec_inner() ** (_ kwd("and") _)) e:p()
153 { cst!(let_rec_stmt (s, e) [inner, inners]) }
154
155 pub rule let_rec_inner() -> Cst =
156 s:p()
157 pat:pattern() _ arg:let_rec_stmt_argument()? _ "=" _ expr:expr()
158 _ arms:("|" _ arm:let_rec_matcharm() _ {arm})*
159 e:p()
160 { cst!(let_rec_inner (s, e) [pat, arg, expr, arms]) }
161 /
162 s:p()
163 pat:pattern() _ arms:("|" _ arm:let_rec_matcharm() _ {arm})*
164 e:p()
165 { cst!(let_rec_inner (s, e) [pat, arms]) }
166
167 rule let_rec_stmt_argument() -> Vec<Cst> =
168 s:p() ":" _ t:type_expr() _ "|" _ a:(arg() ++ _) e:p() { vectorize![t, a] }
169 / s:p() ":" _ t:type_expr() e:p() { vectorize![t] }
170 / s:p() a:(arg() ++ _) e:p() { vectorize![a] }
171
172 pub rule let_rec_matcharm() -> Cst =
173 s:p() a:(arg() ** _) _ "=" _ expr:expr() e:p()
174 { cst!(let_rec_matcharm (s, e) [a, expr]) }
175
176 rule let_inline_stmt() -> Cst = let_inline_stmt_ctx() / let_inline_stmt_noctx()
177 pub rule let_inline_stmt_ctx() -> Cst =
178 s:p() kwd("let-inline") _ ctx:var() _ cmd:inline_cmd_name() _ a:(arg() ** _) _ "=" _ expr:expr() e:p()
179 { cst!(let_inline_stmt_ctx (s, e) [ctx, cmd, a, expr]) }
180 pub rule let_inline_stmt_noctx() -> Cst =
181 s:p() kwd("let-inline") _ cmd:inline_cmd_name() _ pat:(pattern() ** _) _ "=" _ expr:expr() e:p()
182 { cst!(let_inline_stmt_noctx (s, e) [cmd, pat, expr]) }
183
184 rule let_block_stmt() -> Cst = let_block_stmt_ctx() / let_block_stmt_noctx()
185 pub rule let_block_stmt_ctx() -> Cst =
186 s:p() kwd("let-block") _ ctx:var() _ cmd:block_cmd_name() _ a:(arg() ** _) _ "=" _ expr:expr() e:p()
187 { cst!(let_block_stmt_ctx (s, e) [ctx, cmd, a, expr]) }
188 pub rule let_block_stmt_noctx() -> Cst =
189 s:p() kwd("let-block") _ cmd:block_cmd_name() _ pat:(pattern() ** _) _ "=" _ expr:expr() e:p()
190 { cst!(let_block_stmt_noctx (s, e) [cmd, pat, expr]) }
191
192 pub rule let_math_stmt() -> Cst =
193 s:p() kwd("let-math") _ cmd:math_cmd_name() _ a:(arg() ** _) _ "=" _ expr:expr() e:p()
194 { cst!(let_math_stmt (s, e) [cmd, a, expr]) }
195
196 pub rule let_mutable_stmt() -> Cst =
197 s:p() kwd("let-mutable") _ var:var() _ "<-" _ expr:expr() e:p()
198 { cst!(let_mutable_stmt (s, e) [var, expr]) }
199
200 pub rule type_stmt() -> Cst =
201 s:p() kwd("type") _ ts:(type_inner() ++ (_ kwd("and") _)) e:p()
202 { cst!(type_stmt (s, e) [ts]) }
203
204 pub rule type_inner() -> Cst =
205 s:p()
206 tp:(type_param() ** _) _ t:type_name() _ "=" tvs:(_ "|" _ tv:type_variant() {tv})+ _ c:constraint()*
207 e:p()
208 { cst!(type_inner (s, e) [tp, t, tvs, c]) }
209 /
210 s:p()
211 tp:(type_param() ** _) _ t:type_name() _ "=" _ tvs:(type_variant() ++ (_ "|" _)) _ c:constraint()*
212 e:p()
213 { cst!(type_inner (s, e) [tp, t, tvs, c]) }
214 /
215 s:p()
216 tp:(type_param() ** _) _ t:type_name() _ "=" _ te:type_expr() _ c:constraint()*
217 e:p()
218 { cst!(type_inner (s, e) [tp, t, te, c]) }
219
220 pub rule type_variant() -> Cst =
221 s:p() v:variant_name() _ kwd("of") _ t:type_expr() e:p() { cst!(type_variant (s, e) [v, t]) }
222 / s:p() v:variant_name() e:p() { cst!(type_variant (s, e) [v]) }
223
224 pub rule open_stmt() -> Cst =
225 s:p() kwd("open") _ m:module_name() e:p()
226 { cst!(open_stmt (s, e) [m]) }
227
228 pub rule dummy_stmt() -> Cst =
229 s:p()
230 (kwd("let") / kwd("module") / kwd("type")) _ var() ** _
231 e:p()
232 { cst!(dummy_stmt (s, e) []) }
233
234 pub rule arg() -> Cst =
235 s:p() p:pattern() e:p() { cst!(arg (s, e) [p]) }
236 / s:p() "?:" _ p:var_ptn() e:p() { cst!(arg (s, e) [p]) }
237
238 pub rule module_stmt() -> Cst =
241 s:p()
242 kwd("module") _ n:module_name() _
243 sig:(":" _ s:sig_stmt() {s})? _
244 "=" _ stmt:struct_stmt()
245 e:p()
246 { cst!(module_stmt (s, e) [n, sig, stmt]) }
247
248 pub rule sig_stmt() -> Cst =
249 s:p() kwd("sig") _ inners:(sig_inner() ** _) _ kwd("end") e:p()
250 { cst!(sig_stmt (s, e) [inners]) }
251
252 pub rule struct_stmt() -> Cst =
253 s:p() kwd("struct") _ stmts:(statement() ** _) _ kwd("end") e:p()
254 { cst!(struct_stmt (s, e) [stmts]) }
255
256 rule sig_inner() -> Cst = sig_type_stmt() / sig_val_stmt() / sig_direct_stmt() / dummy_sig_stmt()
257
258 pub rule sig_type_stmt() -> Cst =
259 s:p() kwd("type") _ tps:(type_param() ** _) _ v:var() _ cs:(constraint() ** _) e:p()
260 { cst!(sig_type_stmt (s, e) [tps, v, cs]) }
261
262 pub rule sig_val_stmt() -> Cst =
263 s:p()
264 kwd("val") _
265 v:(var() / "(" _ b:bin_operator() _ ")" {b} / inline_cmd_name() / block_cmd_name()) _
266 ":" _ t: type_expr() _ cs:(constraint() ** _)
267 e:p()
268 { cst!(sig_val_stmt (s, e) [v, t, cs]) }
269
270 pub rule sig_direct_stmt() -> Cst =
271 s:p()
272 kwd("direct") _
273 cmd:(inline_cmd_name() / block_cmd_name()) _
274 ":" _ t: type_expr() _ cs:(constraint() ** _)
275 e:p()
276 { cst!(sig_direct_stmt (s, e) [cmd, t, cs]) }
277
278 pub rule dummy_sig_stmt() -> Cst =
279 s:p()
280 !kwd("end") _ var_ptn()
281 e:p()
282 { cst!(dummy_sig_stmt (s, e) []) }
283
284 pub rule type_expr() -> Cst =
287 s:p()
288 typeprods:(
289 t:type_optional() _ "?->" _ {t}
290 /
291 t:type_prod() _ "->" _ {t}
292 )* _
293 typeprod:type_prod()
294 e:p()
295 { cst!(type_expr (s, e) [typeprods, typeprod]) }
296
297 pub rule type_optional() -> Cst = s:p() t:type_prod() e:p() { cst!(type_optional (s, e) [t.inner]) }
298
299 pub rule type_prod() -> Cst =
300 s:p() t:type_unary() ts:(_ "*" _ t:type_unary() {t})* e:p()
301 { cst!(type_prod (s, e) [t, ts]) }
302
303 #[cache]
304 rule type_unary() -> Cst =
305 type_inline_cmd()
306 / type_block_cmd()
307 / type_math_cmd()
308 / type_application()
309 / "(" _ t:type_expr() _ ")" {t}
310 / type_record()
311 / type_param()
312
313 pub rule type_inline_cmd() -> Cst = s:p() t:type_list() _ kwd("inline-cmd") e:p() { cst!(type_inline_cmd (s, e) [t]) }
314 pub rule type_block_cmd() -> Cst = s:p() t:type_list() _ kwd("block-cmd") e:p() { cst!(type_block_cmd (s, e) [t]) }
315 pub rule type_math_cmd() -> Cst = s:p() t:type_list() _ kwd("math-cmd") e:p() { cst!(type_math_cmd (s, e) [t]) }
316
317 rule type_list() -> Vec<Cst> =
318 s:p() "[" _ "]" e:p() { vec![] }
319 / s:p() "[" _ t:type_list_unit()
320 ts:(_ ";" _ t:type_list_unit() {t})* _
321 ";"? _ "]" e:p()
322 { vectorize![t, ts] }
323
324 rule type_list_unit() -> Cst =
325 type_list_unit_optional()
326 / type_expr()
327
328 pub rule type_list_unit_optional() -> Cst =
329 s:p() t:type_prod() _ "?" e:p()
330 { cst!(type_list_unit_optional (s, e) [t]) }
331
332 pub rule type_application() -> Cst =
333 s:p() t:type_application_unit() _ ts:(type_application_unit()** _) e:p()
334 { cst!(type_application (s, e) [t, ts]) }
335
336 rule type_application_unit() -> Cst =
337 "(" _ t:type_expr() _ ")" {t}
338 / type_param()
339 / type_name()
340
341 pub rule type_name() -> Cst =
342 s:p() t:(var() / modvar()) e:p()
343 { cst!(type_name (s, e) [t]) }
344
345 pub rule type_record() -> Cst =
346 s:p() "(|" _ "|)" e:p() { cst!(type_record (s, e) []) }
347 / s:p() "(|" _ ts:(type_record_unit() ++ (_ ";" _)) _ ";"? _ "|)" e:p() { cst!(type_record (s, e) [ts]) }
348
349 pub rule type_record_unit() -> Cst =
350 s:p() v:var() _ ":" _ t:type_expr() e:p()
351 { cst!(type_record_unit (s, e) [v, t]) }
352
353 pub rule type_param() -> Cst =
354 s:p() "'" t:var_ptn() e:p()
355 { cst!(type_param (s, e) [t]) }
356
357 pub rule constraint() -> Cst =
358 s:p() kwd("constraint") _ t:type_param() _ "::" _ r:type_record() e:p()
359 { cst!(constraint (s, e) [t, r]) }
360
361 pub rule pat_as() -> Cst =
364 s:p() p:pat_cons() v:(_ kwd("as") _ v:var() {v})? e:p() { cst!(pat_as (s, e) [p, v]) }
365
366 #[cache]
367 pub rule pat_cons() -> Cst =
368 s:p() p:pattern() _ "::" _ m:pat_as() e:p() { cst!(pat_cons (s, e) [p, m]) }
369 / s:p() p:pat_variant() e:p() { cst!(pat_cons (s, e) [p]) }
370 / s:p() p:pattern() e:p() { cst!(pat_cons (s, e) [p]) }
371
372 #[cache]
373 pub rule pattern() -> Cst =
374 s:p() p:pat_list() e:p() { cst!(pattern (s, e) [p]) }
375 / s:p() "(" _ b:bin_operator() _ ")" e:p() { cst!(pattern (s, e) [b]) }
376 / s:p() "(" _ u:unary_operator() _ ")" e:p() { cst!(pattern (s, e) [u]) }
377 / s:p() "(" _ p:pat_as() _ ")" e:p() { cst!(pattern (s, e) [p]) }
378 / s:p() p:pat_tuple() e:p() { cst!(pattern (s, e) [p]) }
379 / s:p() "_" e:p() { cst!(pattern (s, e) []) }
380 / s:p() "~"? v:var() e:p() { cst!(pattern (s, e) [v]) }
381 / s:p() l:constant() e:p() { cst!(pattern (s, e) [l]) }
382
383 pub rule pat_variant() -> Cst =
384 s:p() v:variant_name() _ p:pattern()? e:p()
385 { cst!(pat_variant (s, e) [v, p]) }
386
387 pub rule pat_list() -> Cst =
388 s:p() "[" _ "]" e:p() { cst!(pat_list (s, e) []) }
389 / s:p() "[" _ ms:(pat_as() ** (_ ";" _)) _ ";"? _ "]" e:p() { cst!(pat_list (s, e) [ms]) }
390
391 pub rule pat_tuple() -> Cst =
392 s:p() "(" _ m:pat_as() _ "," _ ms:(pat_as() ++ (_ "," _)) _ ")" e:p()
393 { cst!(pat_tuple (s, e) [m, ms]) }
394
395 pub rule expr() -> Cst =
397 s:p() expr:(
398 match_expr()
399 / bind_stmt()
400 / ctrl_while()
401 / ctrl_if()
402 / lambda()
403 / assignment()
404 / dyadic_expr()
405 / unary_operator_expr()
406 / command_application()
407 / application()
408 / unary()
409 / variant_constructor()
410 ) e:p()
411 { cst!(expr (s, e) [expr]) }
412
413 pub rule match_expr() -> Cst =
414 s:p() kwd("match") _ expr:expr() _ kwd("with") _ "|"? _ arms:(match_arm() ** (_ "|" _)) e:p()
415 { cst!(match_expr (s, e) [expr, arms]) }
416
417 pub rule bind_stmt() -> Cst =
418 s:p() stmt:(let_stmt() / let_rec_stmt() / let_math_stmt() / let_mutable_stmt() / open_stmt())
419 _ kwd("in") _ expr:expr() e:p()
420 { cst!(bind_stmt (s, e) [stmt, expr]) }
421
422 pub rule match_arm() -> Cst =
423 s:p()
424 ptn:pat_as() _ guard:match_guard()? _ "->" _ expr:(!match_expr() e:expr() {e})
425 e:p()
426 { cst!(match_arm (s, e) [ptn, guard, expr]) }
427
428 pub rule match_guard() -> Cst =
429 s:p()
430 kwd("when") _ cond:(!match_expr() e:expr() {e})
431 e:p()
432 { cst!(match_guard (s, e) [cond]) }
433
434 pub rule ctrl_while() -> Cst =
435 s:p() kwd("while") _ cond:expr() _ kwd("do") _
436 expr:(!(match_expr() / bind_stmt()) e:expr() {e})
437 e:p()
438 { cst!(ctrl_while (s, e) [cond, expr]) }
439
440 pub rule ctrl_if() -> Cst =
441 s:p() kwd("if") _ cond:expr() _ kwd("then") _ et:expr() _ kwd("else") _ ee:expr() e:p()
442 { cst!(ctrl_if (s, e) [cond, et, ee]) }
443
444 pub rule lambda() -> Cst =
445 s:p() kwd("fun") _ ptns:(pattern() ++ _) _ "->" _ expr: expr_inner_lambda() e:p()
446 { cst!(lambda (s, e) [ptns, expr]) }
447
448 pub rule assignment() -> Cst =
449 s:p() v:var() _ "<-" _ expr: expr_inner_lambda() e:p()
450 { cst!(assignment (s, e) [v, expr]) }
451
452 rule expr_inner_lambda() -> Cst =
453 dyadic_expr() / unary_operator_expr() / application() / unary() / variant_constructor()
454
455 pub rule dyadic_expr() -> Cst =
456 s:p()
457 t1:(unary_operator_expr() / application() / unary() / variant_constructor())
458 _ op:bin_operator()
459 _ t2:(dyadic_expr() / application() / unary() / variant_constructor())
460 e:p()
461 { cst!(dyadic_expr (s, e) [t1, op, t2]) }
462
463 pub rule unary_operator_expr() -> Cst =
464 s:p() op:unary_operator() _ expr:(application() / unary()) e:p()
465 { cst!(unary_operator_expr (s, e) [op, expr]) }
466
467 pub rule unary_operator() -> Cst =
468 s:p() ("-" / kwd("not") ) e:p()
469 { cst!(unary_operator (s, e) []) }
470
471 pub rule application() -> Cst =
472 s:p()
473 v:(unary()) _
474 args:(application_args() ++ _)
475 e:p()
476 { cst!(application (s, e) [v, args]) }
477
478 rule application_args() -> Cst = application_args_optional() / application_args_normal()
479
480 pub rule application_args_optional() -> Cst =
481 s:p() "?:" _ u:(unary()) e:p() { cst!(application_args_optional (s, e) [u]) }
482 / s:p() "?*" e:p() { cst!(application_args_optional (s, e) []) }
483
484 pub rule application_args_normal() -> Cst =
485 s:p() u:(unary() / variant_name()) e:p()
486 { cst!(application_args_normal (s, e) [u]) }
487
488 pub rule command_application() -> Cst =
489 s:p() kwd("command") _ n:inline_cmd_name() e:p()
490 { cst!(command_application (s, e) [n]) }
491
492 pub rule variant_constructor() -> Cst =
493 s:p() v:variant_name() _ u:unary()? e:p()
494 { cst!(variant_constructor (s, e) [v, u]) }
495
496 #[cache]
499 pub rule unary() -> Cst =
500 s:p()
501 prefix:(p:unary_prefix() _ {p})?
502 body:((
503 block_text()
504 / horizontal_text()
505 / math_text()
506 / record()
507 / list()
508 / tuple()
509 / "(" _ op:bin_operator() _ ")" {op}
510 / "(" _ expr:expr() _ ")" {expr}
511 / constant()
512 / expr_with_mod()
513 / modvar()
514 / var()
515 / dummy_modvar_incomplete()
516 ) ++ (_ "#" _))
517 e:p()
518 { cst!(unary (s, e) [prefix, body]) }
519
520 pub rule unary_prefix() -> Cst = s:p() ("!" / "&" / "~") e:p() { cst!(unary_prefix (s, e) []) }
521
522 pub rule block_text() -> Cst =
523 s:p() "'" v:vertical() e:p()
524 { cst!(block_text (s, e) [v]) }
525
526 pub rule horizontal_text() -> Cst =
527 s:p() h:horizontal() e:p()
528 { cst!(horizontal_text (s, e) [h]) }
529
530 pub rule math_text() -> Cst =
531 s:p() "${" _ m:math() _ "}" e:p()
532 { cst!(math_text (s, e) [m]) }
533
534 pub rule record() -> Cst =
535 s:p() "(|" _ "|)" e:p() { cst!(record (s, e) []) }
536 / s:p() "(|" _ u:unary() _ kwd("with") _ i:record_inner() _ "|)" e:p() { cst!(record (s, e) [u, i]) }
537 / s:p() "(|" _ i:record_inner() _ "|)" e:p() { cst!(record (s, e) [i]) }
538
539 rule record_inner() -> Vec<Cst> =
540 s:p() units:(record_unit() ++ (_ ";" _)) _ ";"? e:p()
541 { units }
542
543 pub rule record_unit() -> Cst =
544 s:p() v:var_ptn() _ "=" _ expr:expr() e:p()
545 { cst!(record_unit (s, e) [v, expr]) }
546
547 pub rule list() -> Cst =
548 s:p() "[" _ "]" e:p() { cst!(list (s, e) []) }
549 / s:p() "[" _ exprs:(expr() ++ (_ ";" _)) _ ";"? _ "]" e:p() { cst!(list (s, e) [exprs]) }
550
551 pub rule tuple() -> Cst =
552 s:p() "(" _ expr:expr() _ "," _ exprs:(expr() ++ (_ "," _)) _ ")" e:p() { cst!(tuple (s, e) [expr, exprs]) }
553
554 pub rule bin_operator() -> Cst =
555 s:p() !bin_operator_except() (bin_operator_start() bin_operator_succ()* / "::" / kwd("mod")) e:p()
556 { cst!(bin_operator (s, e) []) }
557 rule bin_operator_start() =
558 [ '-' | '+' | '*' | '/' | '^' | '&' | '|' | '=' | '<' | '>' ]
559 rule bin_operator_succ() =
560 [ '-' | '+' | '*' | '/' | '^' | '&' | '|' | '=' | '<' | '>'
561 | '!' | ':' | '~' | '\'' | '.' | '?' ]
562 rule bin_operator_except() = ("->" / "<-" / "|") !bin_operator_succ()
563
564 pub rule expr_with_mod() -> Cst =
565 s:p() m:module_name() ".(" _ expr:expr() _ ")" e:p()
566 { cst!(expr_with_mod (s, e) [m, expr]) }
567
568 pub rule var() -> Cst =
569 s:p() !(reserved_word() !ASCII_ALPHANUMERIC_HYPHEN()) var_ptn() e:p()
570 { cst!(var (s, e) []) }
571
572 pub rule var_ptn() -> Cst =
573 s:p() ['a'..='z'] ASCII_ALPHANUMERIC_HYPHEN()* e:p()
574 { cst!(var_ptn (s, e) []) }
575
576 pub rule dummy_modvar_incomplete() -> Cst =
577 s:p() module_name() "." e:p()
578 { cst!(dummy_modvar_incomplete (s, e) []) }
579
580 rule reserved_word() =
582 ( "constraint"
583 / "inline-cmd" / "block-cmd" / "math-cmd"
584 / "let-mutable" / "let-inline" / "let-block" / "let-math" / "let-rec"
585 / "controls" / "command" / "before" / "module" / "direct" / "struct"
586 / "cycle" / "match" / "while" / "false"
587 / "else" / "open" / "then" / "true" / "type" / "when" / "with"
588 / "and" / "end" / "fun" / "let" / "mod" / "not" / "sig" / "val"
589 / "as" / "do" / "if" / "in" / "of")
590
591
592 pub rule modvar() -> Cst =
593 s:p() modname:module_name() "." var:var_ptn() e:p()
594 { cst!(modvar (s, e) [modname, var]) }
595
596 pub rule mod_cmd_name() -> Cst =
597 s:p() modname:module_name() "." var:cmd_name_ptn() e:p()
598 { cst!(mod_cmd_name (s, e) [modname, var]) }
599
600 pub rule module_name() -> Cst =
601 s:p() ['A' ..= 'Z'] ASCII_ALPHANUMERIC_HYPHEN()* e:p()
602 { cst!(module_name (s, e) []) }
603
604 pub rule variant_name() -> Cst =
605 s:p() ['A' ..= 'Z'] ASCII_ALPHANUMERIC_HYPHEN()* e:p()
606 { cst!(variant_name (s, e) []) }
607
608 rule constant() -> Cst =
610 const_unit()
611 / const_bool()
612 / const_string()
613 / const_float()
614 / const_length()
615 / const_int()
616
617 pub rule const_unit() -> Cst =
618 s:p() "(" _ ")" e:p() { cst!(const_unit (s, e) []) }
619
620 pub rule const_bool() -> Cst =
621 s:p() (kwd("true") / kwd("false")) e:p() {cst!(const_bool (s, e) [])}
622
623 pub rule const_int() -> Cst =
624 s:p() (const_int_decimal() / const_int_hex() / "0") e:p() { cst!(const_int (s, e) []) }
625 rule const_int_decimal() = ['1'..='9'] ASCII_DIGIT()*
626 rule const_int_hex() = "0" ['x' | 'X'] ['0'..='9' | 'A'..='F']+
627
628 pub rule const_float() -> Cst =
629 s:p() const_float_inner() !length_unit() e:p()
630 { cst!(const_float (s, e) []) }
631 rule const_float_inner() = ASCII_DIGIT()+ "." ASCII_DIGIT()* / "." ASCII_DIGIT()+
632
633 pub rule const_length() -> Cst =
634 s:p() length_digit() length_unit() e:p()
635 { cst!(const_length (s, e) []) }
636
637 rule length_digit() = "-"? (const_float_inner() / const_int_decimal() / "0")
638 rule length_unit() = ['a'..='z'] ['0'..='9' | 'a'..='z' | 'A' ..='Z' | '-']*
639
640 pub rule const_string() -> Cst =
641 s:p() "@"? "#"? qs:string_quotes() (!string_inner(qs) [_])+ qe:string_quotes() "#"? e:p()
642 {?
643 if qs == qe {
644 Ok(cst!(const_string (s, e) []))
645 } else {
646 Err("number of back quotation does not match.")
647 }
648 }
649 rule string_quotes() -> usize = n:"`"+ {n.len()}
650 rule string_inner(qs: usize) = "`"*<{qs}>
651
652 pub rule inline_cmd() -> Cst = (
654 s:p() name:inline_cmd_name() _
655 opt:((cmd_expr_arg() / cmd_expr_option())** _) _ opttext:(";" {vec![]} / cmd_text_arg() ++ _) e:p()
656 {
657 cst!(inline_cmd (s, e) [name, opt, opttext])
658 }
659 )
660
661 pub rule inline_cmd_name() -> Cst =
662 s:p() r"\" inner:(mod_cmd_name() / cmd_name_ptn()) "@"? e:p()
663 { cst!(inline_cmd_name (s, e) [inner]) }
664
665 pub rule cmd_name_ptn() -> Cst =
666 s:p() ['A'..='Z' | 'a'..='z'] ASCII_ALPHANUMERIC_HYPHEN()* e:p()
667 { cst!(cmd_name_ptn (s, e) []) }
668
669 pub rule block_cmd() -> Cst = (
670 s:p() name:block_cmd_name() _
671 opt:((cmd_expr_arg() / cmd_expr_option())** _) _ opttext:(";" {vec![]} / cmd_text_arg() ++ _) e:p()
672 {
673 cst!(block_cmd (s, e) [name, opt, opttext])
674 }
675 )
676
677 pub rule block_cmd_name() -> Cst =
678 s:p() "+" inner:(mod_cmd_name() / cmd_name_ptn()) "@"? e:p()
679 { cst!(block_cmd_name (s, e) [inner]) }
680
681 pub rule cmd_expr_arg() -> Cst =
682 s:p() inner:cmd_expr_arg_inner() e:p() { cst!(cmd_expr_arg (s, e) [inner]) }
683
684 pub rule cmd_expr_option() -> Cst =
685 s:p() "?:" _ inner:cmd_expr_arg_inner() e:p() { cst!(cmd_expr_option (s, e) [inner]) }
686 / s:p() "?*" e:p() { cst!(cmd_expr_option (s, e) []) }
687
688 rule cmd_expr_arg_inner() -> Cst =
689 const_unit()
690 / list()
691 / record()
692 / "~"? "(" _ expr:expr() _ ")" { expr }
693
694 pub rule cmd_text_arg() -> Cst =
695 s:p()
696 inner:(vertical() / horizontal())
697 e:p()
698 { cst!(cmd_text_arg (s, e) [inner]) }
699
700 pub rule math_cmd() -> Cst =
701 s:p() cmd:math_cmd_name() _ args:((math_cmd_expr_arg() / math_cmd_expr_option()) ** _) e:p()
702 { cst!(math_cmd (s, e) [cmd, args]) }
703
704 pub rule math_cmd_name() -> Cst =
705 s:p() r"\" inner:(mod_cmd_name() / cmd_name_ptn()) e:p()
706 { cst!(math_cmd_name (s, e) [inner]) }
707
708 pub rule math_cmd_expr_arg() -> Cst =
709 s:p() arg:math_cmd_expr_arg_inner() e:p() { cst!(math_cmd_expr_arg (s, e) [arg]) }
710
711 pub rule math_cmd_expr_option() -> Cst =
712 s:p() "?:" _ arg:math_cmd_expr_arg_inner() e:p() { cst!(math_cmd_expr_option (s, e) [arg]) }
713
714 rule math_cmd_expr_arg_inner() -> Cst =
715 "{" _ m:math() _ "}" {m}
716 / "!" h:horizontal() {h}
717 / "!" v:vertical() {v}
718 / "!(" _ expr:expr() _ ")" {expr}
719 / "!" l:list() {l}
720 / "!" r:record() {r}
721
722 rule horizontal() -> Cst =
732 "{"
734 h:(
735 horizontal_list()
736 / horizontal_bullet_list()
737 / horizontal_single()
738 )
739 "}"
740 {h}
741
742 pub rule horizontal_single() -> Cst =
743 s:p() __ inners:(horizontal_token() ** __) __ e:p() { cst!(horizontal_single (s, e) [inners]) }
744
745 rule horizontal_token() -> Cst =
746 const_string()
747 / inline_cmd()
748 / inline_text_embedding()
749 / math_text()
750 / horizontal_escaped_char()
751 / regular_text()
752 / dummy_inline_cmd_incomplete()
753
754 pub rule inline_text_embedding() -> Cst =
755 s:p() "#" inner:(var_ptn() / modvar()) _ ";" e:p()
756 { cst!(inline_text_embedding (s, e) [inner]) }
757
758 pub rule regular_text() -> Cst =
759 s:p() $(!horizontal_special_char() [_])+ e:p()
760 { cst!(regular_text (s, e) []) }
761
762 pub rule dummy_inline_cmd_incomplete() -> Cst =
763 s:p()
764 "\\" (var_ptn() / modvar() / dummy_modvar_incomplete())?
765 e:p()
766 { cst!(dummy_inline_cmd_incomplete (s, e) []) }
767
768 pub rule horizontal_escaped_char() -> Cst =
769 s:p() "\\" (horizontal_special_char() / horizontal_escapable()) e:p()
770 { cst!(horizontal_escaped_char (s, e) []) }
771
772 rule horizontal_special_char() =
773 ['@' | '`' | '\\' | '{' | '}' | '%' | '|' | '*' | '$' | '#' | ';']
774
775 rule horizontal_escapable() =
776 ['[' | ']' | '(' | ')' | ' ']
777
778 pub rule horizontal_list() -> Cst =
779 s:p() _ "|" inners:horizontal_list_inner()+ _ e:p()
780 { cst!(horizontal_list (s, e) [inners]) }
781 rule horizontal_list_inner() -> Cst = inner:horizontal_single() "|" {inner}
782
783 pub rule horizontal_bullet_list() -> Cst =
784 s:p() inners:horizontal_bullet()+ e:p() { cst!(horizontal_bullet_list (s, e) [inners]) }
785
786 pub rule horizontal_bullet() -> Cst =
787 s:p()
788 _ star:horizontal_bullet_star() _ single:horizontal_single() _
789 e:p()
790 { cst!(horizontal_bullet (s, e) [star, single]) }
791
792 pub rule horizontal_bullet_star() -> Cst =
793 s:p() "*"+ e:p()
794 { cst!(horizontal_bullet_star (s, e) []) }
795
796 pub rule vertical() -> Cst =
799 s:p() "<" _ vs:(vertical_element() ** _) _ ">" e:p()
800 { cst!(vertical (s, e) [vs]) }
801
802 rule vertical_element() -> Cst = block_cmd() / block_text_embedding() / dummy_block_cmd_incomplete()
803
804 pub rule block_text_embedding() -> Cst =
805 s:p() "#" inner:(var_ptn() / modvar()) _ ";" e:p()
806 { cst!(block_text_embedding (s, e) [inner]) }
807
808 pub rule dummy_block_cmd_incomplete() -> Cst =
809 s:p()
810 "+" (var_ptn() / modvar() / dummy_modvar_incomplete())?
811 e:p()
812 { cst!(dummy_block_cmd_incomplete (s, e) []) }
813
814 rule math() -> Cst = math_list() / math_single()
817
818 pub rule math_list() -> Cst =
819 s:p() "|" ms:(_ m:math_single() _ "|" {m})+ e:p() { cst!(math_list (s, e) [ms]) }
820
821 pub rule math_single() -> Cst =
822 s:p() ts:(math_token() ** _) e:p()
823 { cst!(math_single (s, e) [ts]) }
824
825 pub rule math_token() -> Cst =
826 s:p() u:math_unary() _ sup:math_sup() _ sub:math_sub() e:p() { cst!(math_token (s, e) [u, sup, sub]) }
827 / s:p() u:math_unary() _ sub:math_sub() _ sup:math_sup() e:p() { cst!(math_token (s, e) [u, sub, sup]) }
828 / s:p() u:math_unary() _ sup:math_sup() e:p() { cst!(math_token (s, e) [u, sup]) }
829 / s:p() u:math_unary() _ sub:math_sub() e:p() { cst!(math_token (s, e) [u, sub]) }
830 / s:p() u:math_unary() e:p() { cst!(math_token (s, e) [u]) }
831
832 pub rule math_sup() -> Cst = "^" s:p() _ g:math_group() e:p() { cst!(math_sup (s, e) [g]) }
833 pub rule math_sub() -> Cst = "_" s:p() _ g:math_group() e:p() { cst!(math_sub (s, e) [g]) }
834 rule math_group() -> Cst = "{" _ m:math_single() _ "}" {m} / math_unary()
835
836 pub rule math_unary() -> Cst =
837 s:p() [^ '+' | '-' | '*' | '/' | ':' | '=' | '<' | '>' | '~' | '.' | ',' | '`' | '?' | ' ' |
838 '\t' | '\n' | '\r' | '\\' | '{' | '}' | '%' | '|' | '$' | '#' | ';' | '\'' | '^' | '_' | '!' ] e:p() {
839 cst!(math_unary (s, e) [])
840 }
841 / s:p() r"\" math_special_char() e:p() { cst!(math_unary (s, e) []) }
842 / s:p() math_symbol() e:p() { cst!(math_unary (s, e) []) }
843 / s:p() m:math_cmd() e:p() { cst!(math_unary (s, e) [m]) }
844 / s:p() m:math_embedding() e:p() { cst!(math_unary (s, e) [m]) }
845
846 pub rule math_embedding() -> Cst =
847 s:p() "#" inner:(var_ptn() / modvar()) e:p()
848 { cst!(math_embedding (s, e) [inner]) }
849
850 rule math_special_char() = [
851 ' ' | '!' | '"' | '#' | '$' | '%' | '&' | '\''
852 | '(' | ')' | '*' | '+' | ',' | '-' | '.' | '/'
853 | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
854 | ':' | ';' | '<' | '=' | '>' | '?' | '@' | '[' | '\\'
855 | ']' | '^' | '_' | '`' | '{' | '|' | '}' | '~'
856 ]
857 rule math_symbol() =
858 ['-' | '+' | '*' | '/' | ':' | '=' | '<' | '>' | '~' | '\'' | '.' | ',' | '?' | '`']+
859
860 }
861}
862
863pub use self::satysfi_parser::*;