1use crate::{
2 ParseResult, Parser, ParserExt, ParserHandle, ParserNoValue, ParserOutput, ParserRegistry,
3 pratt::PrattParserAssociativity,
4 shorthand::{
5 DynamicPrattParserRule, alpha, alpha_low, alpha_up, alphanum, alt, any, debug, digit,
6 digit_hex, dyn_inspect, dyn_map, dyn_map_err, dyn_pratt, ext_depth, ext_exchange,
7 ext_variants, ext_wrap, id, id_continue, id_start, ignore, inject, list, lit, map, map_err,
8 nl, not, number_float, number_int, number_int_pos, oc, omap, oom, opt, pred, prefix, regex,
9 rep, seq, seq_del, slot_empty, source, string, suffix, template, word, zom,
10 },
11};
12use std::{collections::HashMap, error::Error, sync::RwLock};
13
14#[derive(Default)]
15struct SlotsExtension {
16 slots: RwLock<HashMap<String, ParserHandle>>,
17}
18
19impl SlotsExtension {
20 fn make(&self, name: impl ToString) -> Option<ParserHandle> {
21 let parser = slot_empty();
22 self.slots
23 .write()
24 .ok()?
25 .insert(name.to_string(), parser.clone());
26 Some(parser)
27 }
28
29 fn take(&self, name: &str) -> Option<ParserHandle> {
30 self.slots.write().ok()?.remove(name)
31 }
32}
33
34struct SlotExtensionSlotParser(ParserHandle);
35
36impl Parser for SlotExtensionSlotParser {
37 fn parse<'a>(&self, registry: &ParserRegistry, input: &'a str) -> ParseResult<'a> {
38 let (input, value) = self.0.parse(registry, input)?;
39 let name = value.consume::<String>().ok().unwrap();
40 if let Some(result) = registry
41 .extension::<SlotsExtension>()
42 .expect("Could not access SlotExtension")
43 .make(&name)
44 {
45 Ok((input, ParserOutput::new(result).ok().unwrap()))
46 } else {
47 Err(format!("Could not make `{name}` slot parser").into())
48 }
49 }
50}
51
52struct SlotExtensionExtWrapParser(ParserHandle);
53
54impl Parser for SlotExtensionExtWrapParser {
55 fn parse<'a>(&self, registry: &ParserRegistry, input: &'a str) -> ParseResult<'a> {
56 let (input, value) = self.0.parse(registry, input)?;
57 let mut values = value.consume::<Vec<ParserOutput>>().ok().unwrap();
58 let item = values.remove(1).consume::<ParserHandle>().ok().unwrap();
59 let name = values.remove(0).consume::<String>().ok().unwrap();
60 if let Some(slot) = registry
61 .extension::<SlotsExtension>()
62 .expect("Could not access SlotExtension")
63 .take(&name)
64 {
65 Ok((input, ParserOutput::new(ext_wrap(item, slot)).ok().unwrap()))
66 } else {
67 Err(format!("Could not take `{name}` slot parser").into())
68 }
69 }
70}
71
72pub struct Generator {
73 parsers: Vec<(String, ParserHandle, Option<String>)>,
75}
76
77impl Generator {
78 pub fn new(grammar: &str) -> Result<Self, Box<dyn Error>> {
79 let registry = Self::registry();
80 Ok(Self {
81 parsers: main()
82 .parse(®istry, grammar)?
83 .1
84 .consume::<Vec<(String, ParserHandle, Option<String>)>>()
85 .ok()
86 .unwrap(),
87 })
88 }
89
90 pub fn install(&self, registry: &ParserRegistry) -> Result<(), Box<dyn Error>> {
91 for (id, parser, extender) in &self.parsers {
92 registry.add_parser(id, parser.clone());
93 if let Some(id) = extender.as_ref() {
94 registry.extend(id, parser.clone())?;
95 }
96 }
97 Ok(())
98 }
99
100 pub fn parser(&self, id: &str) -> Option<ParserHandle> {
101 self.parsers
102 .iter()
103 .find_map(|(k, v, _)| if k == id { Some(v.clone()) } else { None })
104 }
105
106 pub fn iter(&self) -> impl Iterator<Item = (&str, ParserHandle, Option<&str>)> {
107 self.parsers
108 .iter()
109 .map(|(id, parser, extender)| (id.as_str(), parser.clone(), extender.as_deref()))
110 }
111
112 fn registry() -> ParserRegistry {
113 ParserRegistry::default()
114 .with_extension(SlotsExtension::default())
115 .with_parser("item", item())
116 .with_parser("debug", parser_debug())
117 .with_parser("source", parser_source())
118 .with_parser("ext_exchange", parser_ext_exchange())
119 .with_parser("ext_depth", parser_ext_depth())
120 .with_parser("ext_variants", parser_ext_variants())
121 .with_parser("ext_wrap", parser_ext_wrap())
122 .with_parser("inspect", parser_inspect())
123 .with_parser("map", parser_map())
124 .with_parser("map_err", parser_map_err())
125 .with_parser("pratt", parser_pratt())
126 .with_parser("alt", parser_alt())
127 .with_parser("seq", parser_seq())
128 .with_parser("seq_del", parser_seq_del())
129 .with_parser("zom", parser_zom())
130 .with_parser("oom", parser_oom())
131 .with_parser("not", parser_not())
132 .with_parser("opt", parser_opt())
133 .with_parser("pred", parser_pred())
134 .with_parser("slot", parser_slot())
135 .with_parser("rep", parser_rep())
136 .with_parser("inject", parser_inject())
137 .with_parser("lit", parser_lit())
138 .with_parser("regex", parser_regex())
139 .with_parser("template", parser_template())
140 .with_parser("oc", parser_oc())
141 .with_parser("prefix", parser_prefix())
142 .with_parser("suffix", parser_suffix())
143 .with_parser("string", parser_string())
144 .with_parser("list", parser_list())
145 .with_parser("any", parser_any())
146 .with_parser("nl", parser_nl())
147 .with_parser("digit_hex", parser_digit_hex())
148 .with_parser("digit", parser_digit())
149 .with_parser("number_int_pos", parser_number_int_pos())
150 .with_parser("number_int", parser_number_int())
151 .with_parser("number_float", parser_number_float())
152 .with_parser("alphanum", parser_alphanum())
153 .with_parser("alpha_low", parser_alpha_low())
154 .with_parser("alpha_up", parser_alpha_up())
155 .with_parser("alpha", parser_alpha())
156 .with_parser("word", parser_word())
157 .with_parser("id_start", parser_id_start())
158 .with_parser("id_continue", parser_id_continue())
159 .with_parser("id", parser_id())
160 .with_parser("ows", parser_ows())
161 .with_parser("ws", parser_ws())
162 .with_parser("ignore", parser_ignore())
163 }
164}
165
166fn main() -> ParserHandle {
167 map(
168 oc(list(rule(), ws(), true), ows(), ows()),
169 |values: Vec<ParserOutput>| {
170 values
171 .into_iter()
172 .map(|value| {
173 value
174 .consume::<(String, ParserHandle, Option<String>)>()
175 .ok()
176 .unwrap()
177 })
178 .collect::<Vec<_>>()
179 },
180 )
181}
182
183fn identifier() -> ParserHandle {
184 alt([string("`", "`"), id()])
185}
186
187fn boolean() -> ParserHandle {
188 map(alt([lit("true"), lit("false")]), |value: String| {
189 value.parse::<bool>().unwrap()
190 })
191}
192
193fn rule() -> ParserHandle {
194 map(
195 seq_del(
196 ows(),
197 [
198 identifier(),
199 opt(prefix(prefix(identifier(), ows()), lit("->"))),
200 lit("=>"),
201 inject("item"),
202 ],
203 ),
204 |mut values: Vec<ParserOutput>| {
205 let parser = values.remove(3).consume::<ParserHandle>().ok().unwrap();
206 let extends = values.remove(1).consume::<String>().ok();
207 let id = values.remove(0).consume::<String>().ok().unwrap();
208 (id, parser, extends)
209 },
210 )
211}
212
213fn comment() -> ParserHandle {
214 map(
215 regex(r"(\s*/\*[^\*/]+\*/\s*|\s*//[^\r\n]+[\r\n]\s*)+"),
216 |_: String| ParserNoValue,
217 )
218}
219
220fn ws() -> ParserHandle {
221 alt([comment(), crate::shorthand::ws()])
222}
223
224fn ows() -> ParserHandle {
225 alt([comment(), crate::shorthand::ows()])
226}
227
228fn item() -> ParserHandle {
229 alt([
230 inject("debug"),
231 inject("source"),
232 inject("ext_exchange"),
233 inject("ext_depth"),
234 inject("ext_variants"),
235 inject("ext_wrap"),
236 inject("inspect"),
237 inject("map"),
238 inject("map_err"),
239 inject("pratt"),
240 inject("alt"),
241 inject("seq"),
242 inject("seq_del"),
243 inject("zom"),
244 inject("oom"),
245 inject("not"),
246 inject("opt"),
247 inject("pred"),
248 inject("slot"),
249 inject("rep"),
250 inject("inject"),
251 inject("lit"),
252 inject("regex"),
253 inject("template"),
254 inject("oc"),
255 inject("prefix"),
256 inject("suffix"),
257 inject("string"),
258 inject("list"),
259 inject("any"),
260 inject("nl"),
261 inject("digit_hex"),
262 inject("digit"),
263 inject("number_int_pos"),
264 inject("number_int"),
265 inject("number_float"),
266 inject("alphanum"),
267 inject("alpha_low"),
268 inject("alpha_up"),
269 inject("alpha"),
270 inject("word"),
271 inject("id_start"),
272 inject("id_continue"),
273 inject("id"),
274 inject("ows"),
275 inject("ws"),
276 inject("ignore"),
277 ])
278}
279
280fn parser_list() -> ParserHandle {
281 map_err(
282 map(
283 oc(
284 seq_del(ws(), [inject("item"), inject("item"), boolean()]),
285 suffix(lit("{"), ows()),
286 prefix(lit("}"), ows()),
287 ),
288 |mut values: Vec<ParserOutput>| {
289 let permissive = values.remove(2).consume::<bool>().ok().unwrap();
290 let delimiter = values.remove(1).consume::<ParserHandle>().ok().unwrap();
291 let item = values.remove(0).consume::<ParserHandle>().ok().unwrap();
292 list(item, delimiter, permissive)
293 },
294 ),
295 |_| "Expected list".into(),
296 )
297}
298
299fn parser_debug() -> ParserHandle {
300 map_err(
301 map(
302 prefix(seq([string("`", "`"), inject("item")]), lit("@")),
303 |mut values: Vec<ParserOutput>| {
304 let item = values.remove(1).consume::<ParserHandle>().ok().unwrap();
305 let id = values.remove(0).consume::<String>().ok().unwrap();
306 debug(id, item)
307 },
308 ),
309 |_| "Expected debug".into(),
310 )
311}
312
313fn parser_source() -> ParserHandle {
314 map_err(
315 map(prefix(inject("item"), lit("=")), |value: ParserHandle| {
316 source(value)
317 }),
318 |_| "Expected source".into(),
319 )
320}
321
322fn parser_ext_exchange() -> ParserHandle {
323 map_err(
324 map(
325 oc(
326 inject("item"),
327 seq_del(ows(), [lit("#"), lit("exchange"), suffix(lit("{"), ows())]),
328 prefix(lit("}"), ows()),
329 ),
330 |value: ParserHandle| ext_exchange(value),
331 ),
332 |_| "Expected extendable exchange".into(),
333 )
334}
335
336fn parser_ext_depth() -> ParserHandle {
337 map_err(
338 map(
339 oc(
340 inject("item"),
341 seq_del(ows(), [lit("#"), lit("depth"), suffix(lit("{"), ows())]),
342 prefix(lit("}"), ows()),
343 ),
344 |value: ParserHandle| ext_depth(value),
345 ),
346 |_| "Expected extendable depth".into(),
347 )
348}
349
350fn parser_ext_variants() -> ParserHandle {
351 map_err(
352 omap(
353 seq_del(ows(), [lit("#"), lit("variants"), lit("{"), lit("}")]),
354 |_| ParserOutput::new(ext_variants()).ok().unwrap(),
355 ),
356 |_| "Expected extendable variants".into(),
357 )
358}
359
360fn parser_ext_wrap() -> ParserHandle {
361 map_err(
362 SlotExtensionExtWrapParser(oc(
363 seq_del(ws(), [identifier(), inject("item")]),
364 seq_del(ows(), [lit("#"), lit("wrapper"), suffix(lit("{"), ows())]),
365 prefix(lit("}"), ows()),
366 ))
367 .into_handle(),
368 |_| "Expected extendable wrapper".into(),
369 )
370}
371
372fn parser_inspect() -> ParserHandle {
373 map_err(
374 map(
375 oc(
376 seq_del(ws(), [inject("item"), string("\"", "\"")]),
377 seq_del(ows(), [lit("%"), lit("inspect"), suffix(lit("{"), ows())]),
378 prefix(lit("}"), ows()),
379 ),
380 |mut values: Vec<ParserOutput>| {
381 let callback = values.remove(1).consume::<String>().ok().unwrap();
382 let item = values.remove(0).consume::<ParserHandle>().ok().unwrap();
383 dyn_inspect(item, callback)
384 },
385 ),
386 |_| "Expected inspection".into(),
387 )
388}
389
390fn parser_map() -> ParserHandle {
391 map_err(
392 map(
393 oc(
394 seq_del(ws(), [inject("item"), string("\"", "\"")]),
395 seq_del(ows(), [lit("%"), lit("map"), suffix(lit("{"), ows())]),
396 prefix(lit("}"), ows()),
397 ),
398 |mut values: Vec<ParserOutput>| {
399 let callback = values.remove(1).consume::<String>().ok().unwrap();
400 let item = values.remove(0).consume::<ParserHandle>().ok().unwrap();
401 dyn_map(item, callback)
402 },
403 ),
404 |_| "Expected mapping".into(),
405 )
406}
407
408fn parser_map_err() -> ParserHandle {
409 map_err(
410 map(
411 oc(
412 seq_del(ws(), [inject("item"), string("\"", "\"")]),
413 seq_del(ows(), [lit("%"), lit("maperr"), suffix(lit("{"), ows())]),
414 prefix(lit("}"), ows()),
415 ),
416 |mut values: Vec<ParserOutput>| {
417 let callback = values.remove(1).consume::<String>().ok().unwrap();
418 let item = values.remove(0).consume::<ParserHandle>().ok().unwrap();
419 dyn_map_err(item, callback)
420 },
421 ),
422 |_| "Expected error mapping".into(),
423 )
424}
425
426fn pratt_rule_prefix() -> ParserHandle {
427 map_err(
428 map(
429 oc(
430 seq_del(
431 ws(),
432 [lit("prefix"), string("\"", "\""), string("\"", "\"")],
433 ),
434 lit("<"),
435 lit(">"),
436 ),
437 |mut values: Vec<ParserOutput>| {
438 let transformer_function_name = values.remove(2).consume::<String>().ok().unwrap();
439 let operator_function_name = values.remove(1).consume::<String>().ok().unwrap();
440 DynamicPrattParserRule::Prefix {
441 operator_function_name,
442 transformer_function_name,
443 }
444 },
445 ),
446 |_| "Expected Pratt prefix rule".into(),
447 )
448}
449
450fn pratt_rule_prefix_op() -> ParserHandle {
451 map_err(
452 map(
453 oc(
454 seq_del(
455 ws(),
456 [
457 lit("prefix"),
458 lit("op"),
459 string("\"", "\""),
460 string("\"", "\""),
461 ],
462 ),
463 lit("<"),
464 lit(">"),
465 ),
466 |mut values: Vec<ParserOutput>| {
467 let transformer_function_name = values.remove(3).consume::<String>().ok().unwrap();
468 let operator = values.remove(2).consume::<String>().ok().unwrap();
469 DynamicPrattParserRule::PrefixOp {
470 operator,
471 transformer_function_name,
472 }
473 },
474 ),
475 |_| "Expected Pratt prefix rule".into(),
476 )
477}
478
479fn pratt_rule_postfix() -> ParserHandle {
480 map_err(
481 map(
482 oc(
483 seq_del(
484 ws(),
485 [lit("postfix"), string("\"", "\""), string("\"", "\"")],
486 ),
487 lit("<"),
488 lit(">"),
489 ),
490 |mut values: Vec<ParserOutput>| {
491 let transformer_function_name = values.remove(2).consume::<String>().ok().unwrap();
492 let operator_function_name = values.remove(1).consume::<String>().ok().unwrap();
493 DynamicPrattParserRule::Postfix {
494 operator_function_name,
495 transformer_function_name,
496 }
497 },
498 ),
499 |_| "Expected Pratt postfix rule".into(),
500 )
501}
502
503fn pratt_rule_postfix_op() -> ParserHandle {
504 map_err(
505 map(
506 oc(
507 seq_del(
508 ws(),
509 [
510 lit("postfix"),
511 lit("op"),
512 string("\"", "\""),
513 string("\"", "\""),
514 ],
515 ),
516 lit("<"),
517 lit(">"),
518 ),
519 |mut values: Vec<ParserOutput>| {
520 let transformer_function_name = values.remove(3).consume::<String>().ok().unwrap();
521 let operator = values.remove(2).consume::<String>().ok().unwrap();
522 DynamicPrattParserRule::PostfixOp {
523 operator,
524 transformer_function_name,
525 }
526 },
527 ),
528 |_| "Expected Pratt postfix rule".into(),
529 )
530}
531
532fn pratt_rule_infix() -> ParserHandle {
533 map_err(
534 map(
535 oc(
536 seq_del(
537 ws(),
538 [
539 lit("infix"),
540 string("\"", "\""),
541 string("\"", "\""),
542 alt([lit("left"), lit("right")]),
543 ],
544 ),
545 lit("<"),
546 lit(">"),
547 ),
548 |mut values: Vec<ParserOutput>| {
549 let associativity = values.remove(3).consume::<String>().ok().unwrap();
550 let transformer = values.remove(2).consume::<String>().ok().unwrap();
551 let operator = values.remove(1).consume::<String>().ok().unwrap();
552 DynamicPrattParserRule::Infix {
553 operator_function_name: operator,
554 transformer_function_name: transformer,
555 associativity: match associativity.as_str() {
556 "left" => PrattParserAssociativity::Left,
557 "right" => PrattParserAssociativity::Right,
558 _ => unreachable!(),
559 },
560 }
561 },
562 ),
563 |_| "Expected Pratt infix rule".into(),
564 )
565}
566
567fn pratt_rule_infix_op() -> ParserHandle {
568 map_err(
569 map(
570 oc(
571 seq_del(
572 ws(),
573 [
574 lit("infix"),
575 lit("op"),
576 string("\"", "\""),
577 string("\"", "\""),
578 alt([lit("left"), lit("right")]),
579 ],
580 ),
581 lit("<"),
582 lit(">"),
583 ),
584 |mut values: Vec<ParserOutput>| {
585 let associativity = values.remove(4).consume::<String>().ok().unwrap();
586 let transformer_function_name = values.remove(3).consume::<String>().ok().unwrap();
587 let operator = values.remove(2).consume::<String>().ok().unwrap();
588 DynamicPrattParserRule::InfixOp {
589 operator,
590 transformer_function_name,
591 associativity: match associativity.as_str() {
592 "left" => PrattParserAssociativity::Left,
593 "right" => PrattParserAssociativity::Right,
594 _ => unreachable!(),
595 },
596 }
597 },
598 ),
599 |_| "Expected Pratt infix rule".into(),
600 )
601}
602
603fn pratt_rule_set() -> ParserHandle {
604 map_err(
605 map(
606 oc(
607 list(
608 alt([
609 pratt_rule_prefix_op(),
610 pratt_rule_prefix(),
611 pratt_rule_postfix_op(),
612 pratt_rule_postfix(),
613 pratt_rule_infix_op(),
614 pratt_rule_infix(),
615 ]),
616 ws(),
617 false,
618 ),
619 suffix(lit("["), ows()),
620 prefix(lit("]"), ows()),
621 ),
622 |values: Vec<ParserOutput>| {
623 values
624 .into_iter()
625 .map(|value| value.consume::<DynamicPrattParserRule>().ok().unwrap())
626 .collect::<Vec<_>>()
627 },
628 ),
629 |_| "Expected Pratt rule set".into(),
630 )
631}
632
633fn parser_pratt() -> ParserHandle {
634 map_err(
635 map(
636 oc(
637 seq_del(
638 ws(),
639 [
640 inject("item"),
641 lit("->"),
642 list(pratt_rule_set(), ws(), false),
643 ],
644 ),
645 seq_del(ows(), [lit("%"), lit("pratt"), suffix(lit("{"), ows())]),
646 prefix(lit("}"), ows()),
647 ),
648 |mut values: Vec<ParserOutput>| {
649 let rules = values
650 .remove(2)
651 .consume::<Vec<ParserOutput>>()
652 .ok()
653 .unwrap();
654 let rules = rules
655 .into_iter()
656 .map(|value| value.consume::<Vec<DynamicPrattParserRule>>().ok().unwrap())
657 .collect::<Vec<_>>();
658 let tokenizer_parser = values.remove(0).consume::<ParserHandle>().ok().unwrap();
659 dyn_pratt(tokenizer_parser, rules)
660 },
661 ),
662 |_| "Expected error mapping".into(),
663 )
664}
665
666fn parser_alt() -> ParserHandle {
667 map_err(
668 map(
669 oc(
670 list(inject("item"), ws(), false),
671 suffix(lit("["), ows()),
672 prefix(lit("]"), ows()),
673 ),
674 |values: Vec<ParserOutput>| {
675 let parsers = values
676 .into_iter()
677 .map(|value| value.consume::<ParserHandle>().ok().unwrap())
678 .collect::<Vec<_>>();
679 alt(parsers)
680 },
681 ),
682 |_| "Expected alternations".into(),
683 )
684}
685
686fn parser_seq() -> ParserHandle {
687 map_err(
688 map(
689 oc(
690 list(inject("item"), ws(), false),
691 suffix(lit("("), ows()),
692 prefix(lit(")"), ows()),
693 ),
694 |values: Vec<ParserOutput>| {
695 let parsers = values
696 .into_iter()
697 .map(|value| value.consume::<ParserHandle>().ok().unwrap())
698 .collect::<Vec<_>>();
699 seq(parsers)
700 },
701 ),
702 |_| "Expected sequence".into(),
703 )
704}
705
706fn parser_seq_del() -> ParserHandle {
707 map_err(
708 map(
709 seq_del(
710 ows(),
711 [
712 oc(
713 inject("item"),
714 suffix(lit("|"), ows()),
715 prefix(lit("|"), ows()),
716 ),
717 oc(
718 list(inject("item"), ws(), false),
719 suffix(lit("("), ows()),
720 prefix(lit(")"), ows()),
721 ),
722 ],
723 ),
724 |mut values: Vec<ParserOutput>| {
725 let parsers = values
726 .remove(1)
727 .consume::<Vec<ParserOutput>>()
728 .ok()
729 .unwrap();
730 let delimiter = values.remove(0).consume::<ParserHandle>().ok().unwrap();
731 let parsers = parsers
732 .into_iter()
733 .map(|value| value.consume::<ParserHandle>().ok().unwrap())
734 .collect::<Vec<_>>();
735 seq_del(delimiter, parsers)
736 },
737 ),
738 |_| "Expected delimited sequence".into(),
739 )
740}
741
742fn parser_zom() -> ParserHandle {
743 map_err(
744 map(prefix(inject("item"), lit("*")), |value: ParserHandle| {
745 zom(value)
746 }),
747 |_| "Expected zero or more".into(),
748 )
749}
750
751fn parser_oom() -> ParserHandle {
752 map_err(
753 map(prefix(inject("item"), lit("+")), |value: ParserHandle| {
754 oom(value)
755 }),
756 |_| "Expected one or more".into(),
757 )
758}
759
760fn parser_not() -> ParserHandle {
761 map_err(
762 map(prefix(inject("item"), lit("!")), |value: ParserHandle| {
763 not(value)
764 }),
765 |_| "Expected negation".into(),
766 )
767}
768
769fn parser_opt() -> ParserHandle {
770 map_err(
771 map(prefix(inject("item"), lit("?")), |value: ParserHandle| {
772 opt(value)
773 }),
774 |_| "Expected optional".into(),
775 )
776}
777
778fn parser_pred() -> ParserHandle {
779 map_err(
780 map(prefix(inject("item"), lit("^")), |value: ParserHandle| {
781 pred(value)
782 }),
783 |_| "Expected prediction".into(),
784 )
785}
786
787fn parser_slot() -> ParserHandle {
788 map_err(
789 SlotExtensionSlotParser(oc(identifier(), lit("<"), lit(">"))).into_handle(),
790 |_| "Expected slot".into(),
791 )
792}
793
794fn parser_rep() -> ParserHandle {
795 map_err(
796 map(
797 seq([number_int_pos(), inject("item")]),
798 |mut values: Vec<ParserOutput>| {
799 let parser = values.remove(1).consume::<ParserHandle>().ok().unwrap();
800 let occurrences = values
801 .remove(0)
802 .consume::<String>()
803 .ok()
804 .unwrap()
805 .parse()
806 .unwrap();
807 rep(parser, occurrences)
808 },
809 ),
810 |_| "Expected repetition".into(),
811 )
812}
813
814fn parser_inject() -> ParserHandle {
815 map_err(
816 map(prefix(identifier(), lit("$")), |value: String| {
817 inject(value)
818 }),
819 |_| "Expected injection".into(),
820 )
821}
822
823fn parser_lit() -> ParserHandle {
824 map_err(map(string("\"", "\""), |value: String| lit(value)), |_| {
825 "Expected literal".into()
826 })
827}
828
829fn parser_regex() -> ParserHandle {
830 map_err(
831 map(string("~~~(", ")~~~"), |value: String| regex(value)),
832 |_| "Expected regex".into(),
833 )
834}
835
836fn parser_template() -> ParserHandle {
837 map_err(
838 map(
839 oc(
840 seq([
841 inject("item"),
842 opt(prefix(string("\"", "\""), ws())),
843 prefix(string("```", "```"), ws()),
844 ]),
845 seq_del(ows(), [lit("template"), suffix(lit("{"), ows())]),
846 prefix(lit("}"), ows()),
847 ),
848 |mut values: Vec<ParserOutput>| {
849 let content = values.remove(2).consume::<String>().ok().unwrap();
850 let rule = values.remove(1).consume::<String>().ok();
851 let item = values.remove(0).consume::<ParserHandle>().ok().unwrap();
852 template(item, rule, content)
853 },
854 ),
855 |_| "Expected template".into(),
856 )
857}
858
859fn parser_oc() -> ParserHandle {
860 map_err(
861 map(
862 oc(
863 seq_del(ws(), [inject("item"), inject("item"), inject("item")]),
864 seq_del(ows(), [lit("oc"), suffix(lit("{"), ows())]),
865 prefix(lit("}"), ows()),
866 ),
867 |mut values: Vec<ParserOutput>| {
868 let close = values.remove(2).consume::<ParserHandle>().ok().unwrap();
869 let open = values.remove(1).consume::<ParserHandle>().ok().unwrap();
870 let item = values.remove(0).consume::<ParserHandle>().ok().unwrap();
871 oc(item, open, close)
872 },
873 ),
874 |_| "Expected open-close".into(),
875 )
876}
877
878fn parser_prefix() -> ParserHandle {
879 map_err(
880 map(
881 oc(
882 seq_del(ws(), [inject("item"), inject("item")]),
883 seq_del(ows(), [lit("prefix"), suffix(lit("{"), ows())]),
884 prefix(lit("}"), ows()),
885 ),
886 |mut values: Vec<ParserOutput>| {
887 let before = values.remove(1).consume::<ParserHandle>().ok().unwrap();
888 let item = values.remove(0).consume::<ParserHandle>().ok().unwrap();
889 prefix(item, before)
890 },
891 ),
892 |_| "Expected prefix".into(),
893 )
894}
895
896fn parser_suffix() -> ParserHandle {
897 map_err(
898 map(
899 oc(
900 seq_del(ws(), [inject("item"), inject("item")]),
901 seq_del(ows(), [lit("suffix"), suffix(lit("{"), ows())]),
902 prefix(lit("}"), ows()),
903 ),
904 |mut values: Vec<ParserOutput>| {
905 let after = values.remove(1).consume::<ParserHandle>().ok().unwrap();
906 let item = values.remove(0).consume::<ParserHandle>().ok().unwrap();
907 suffix(item, after)
908 },
909 ),
910 |_| "Expected suffix".into(),
911 )
912}
913
914fn parser_string() -> ParserHandle {
915 map_err(
916 map(
917 oc(
918 seq_del(ws(), [string("\"", "\""), string("\"", "\"")]),
919 seq_del(ows(), [lit("string"), suffix(lit("{"), ows())]),
920 prefix(lit("}"), ows()),
921 ),
922 |mut values: Vec<ParserOutput>| {
923 let close = values.remove(1).consume::<String>().ok().unwrap();
924 let open = values.remove(0).consume::<String>().ok().unwrap();
925 string(&open, &close)
926 },
927 ),
928 |_| "Expected string".into(),
929 )
930}
931
932fn parser_any() -> ParserHandle {
933 map_err(map(lit("any"), |_: String| any()), |_| {
934 "Expected any".into()
935 })
936}
937
938fn parser_nl() -> ParserHandle {
939 map_err(map(lit("nl"), |_: String| nl()), |_| {
940 "Expected new line".into()
941 })
942}
943
944fn parser_digit_hex() -> ParserHandle {
945 map_err(map(lit("digit_hex"), |_: String| digit_hex()), |_| {
946 "Expected HEX digit".into()
947 })
948}
949
950fn parser_digit() -> ParserHandle {
951 map_err(map(lit("digit"), |_: String| digit()), |_| {
952 "Expected digit".into()
953 })
954}
955
956fn parser_number_int_pos() -> ParserHandle {
957 map_err(
958 map(lit("number_int_pos"), |_: String| number_int_pos()),
959 |_| "Expected positive integer number".into(),
960 )
961}
962
963fn parser_number_int() -> ParserHandle {
964 map_err(map(lit("number_int"), |_: String| number_int()), |_| {
965 "Expected integer number".into()
966 })
967}
968
969fn parser_number_float() -> ParserHandle {
970 map_err(map(lit("number_float"), |_: String| number_float()), |_| {
971 "Expected float number".into()
972 })
973}
974
975fn parser_alphanum() -> ParserHandle {
976 map_err(map(lit("alphanum"), |_: String| alphanum()), |_| {
977 "Expected alphanumeric character".into()
978 })
979}
980
981fn parser_alpha_low() -> ParserHandle {
982 map_err(map(lit("alpha_low"), |_: String| alpha_low()), |_| {
983 "Expected lowercase alphabetic character".into()
984 })
985}
986
987fn parser_alpha_up() -> ParserHandle {
988 map_err(map(lit("alpha_up"), |_: String| alpha_up()), |_| {
989 "Expected uppercase alphabetic character".into()
990 })
991}
992
993fn parser_alpha() -> ParserHandle {
994 map_err(map(lit("alpha"), |_: String| alpha()), |_| {
995 "Expected alphabetic character".into()
996 })
997}
998
999fn parser_word() -> ParserHandle {
1000 map_err(map(lit("word"), |_: String| word()), |_| {
1001 "Expected word".into()
1002 })
1003}
1004
1005fn parser_id_start() -> ParserHandle {
1006 map_err(map(lit("id_start"), |_: String| id_start()), |_| {
1007 "Expected id start".into()
1008 })
1009}
1010
1011fn parser_id_continue() -> ParserHandle {
1012 map_err(map(lit("id_continue"), |_: String| id_continue()), |_| {
1013 "Expected id continue".into()
1014 })
1015}
1016
1017fn parser_id() -> ParserHandle {
1018 map_err(map(lit("id"), |_: String| id()), |_| "Expected id".into())
1019}
1020
1021fn parser_ows() -> ParserHandle {
1022 map_err(map(lit("ows"), |_: String| crate::shorthand::ows()), |_| {
1023 "Expected optional whitespaces".into()
1024 })
1025}
1026
1027fn parser_ws() -> ParserHandle {
1028 map_err(map(lit("ws"), |_: String| crate::shorthand::ws()), |_| {
1029 "Expected whitespaces".into()
1030 })
1031}
1032
1033fn parser_ignore() -> ParserHandle {
1034 map_err(map(lit("ignore"), |_: String| ignore()), |_| {
1035 "Expected ignored".into()
1036 })
1037}
1038
1039#[cfg(test)]
1040mod tests {
1041 use super::*;
1042 use crate::dynamic::DynamicExtensionBuilder;
1043 use intuicio_core::transformer::*;
1044 use intuicio_derive::intuicio_function;
1045
1046 #[test]
1047 fn test_parsers() {
1048 let registry = Generator::registry();
1049
1050 let (rest, result) = main()
1051 .parse(
1052 ®istry,
1053 "
1054 //foo => any
1055 list => {\"foo\" ws true}
1056 /*bar => any*/
1057 ",
1058 )
1059 .unwrap();
1060 assert_eq!(rest, "");
1061 let result = result
1062 .consume::<Vec<(String, ParserHandle, Option<String>)>>()
1063 .ok()
1064 .unwrap();
1065 assert_eq!(result.len(), 1);
1066 assert_eq!(result[0].0.as_str(), "list");
1067
1068 assert_eq!(comment().parse(®istry, "//foo\r\n").unwrap().0, "");
1069 assert_eq!(comment().parse(®istry, "/*bar*/").unwrap().0, "");
1070 assert_eq!(
1071 comment()
1072 .parse(®istry, "//macro => @main:(\r\n")
1073 .unwrap()
1074 .0,
1075 ""
1076 );
1077
1078 assert_eq!(
1079 parser_string()
1080 .parse(®istry, "string{\"(\" \")\"}")
1081 .unwrap()
1082 .0,
1083 ""
1084 );
1085
1086 let (rest, result) = parser_template()
1087 .parse(®istry, "template{\"foo\" ```@{}@```}")
1088 .unwrap();
1089 assert_eq!(rest, "");
1090 assert_eq!(
1091 result
1092 .consume::<ParserHandle>()
1093 .ok()
1094 .unwrap()
1095 .parse(®istry, "foo")
1096 .unwrap()
1097 .1
1098 .consume::<String>()
1099 .ok()
1100 .unwrap()
1101 .as_str(),
1102 "foo"
1103 );
1104
1105 let (rest, result) = parser_ext_wrap()
1106 .parse(®istry, "#wrapper{inner <inner>}")
1107 .unwrap();
1108 assert_eq!(rest, "");
1109 let parser = result.consume::<ParserHandle>().ok().unwrap();
1110 let registry = ParserRegistry::default();
1111 assert!(
1112 parser
1113 .parse(®istry, "foo")
1114 .unwrap()
1115 .1
1116 .is::<ParserNoValue>()
1117 );
1118 parser.extend(lit("foo"));
1119 assert!(parser.parse(®istry, "foo").unwrap().1.is::<String>());
1120 }
1121
1122 #[test]
1123 fn test_generator() {
1124 let grammar = std::fs::read_to_string("./resources/grammar.txt").unwrap();
1125 let generator = Generator::new(&grammar).unwrap();
1126 assert_eq!(
1127 generator
1128 .parsers
1129 .iter()
1130 .map(|(k, _, _)| k.as_str())
1131 .collect::<Vec<_>>(),
1132 vec![
1133 "debug",
1134 "source",
1135 "ext_exchange",
1136 "ext_depth",
1137 "ext_variants",
1138 "ext_wrap",
1139 "inspect",
1140 "map",
1141 "map_err",
1142 "pratt",
1143 "alt",
1144 "seq",
1145 "seq_del",
1146 "zom",
1147 "oom",
1148 "not",
1149 "opt",
1150 "pred",
1151 "slot",
1152 "rep",
1153 "inject",
1154 "lit",
1155 "regex",
1156 "template_value",
1157 "template_add",
1158 "template_mul",
1159 "template_output",
1160 "oc",
1161 "prefix",
1162 "suffix",
1163 "string",
1164 "list",
1165 "any",
1166 "nl",
1167 "digit",
1168 "digit_hex",
1169 "number_int_pos",
1170 "number_int",
1171 "number_float",
1172 "alphanum",
1173 "alpha_low",
1174 "alpha_up",
1175 "alpha",
1176 "word",
1177 "id_start",
1178 "id_continue",
1179 "id",
1180 "ows",
1181 "ws",
1182 "ignore",
1183 "bar",
1184 ]
1185 );
1186
1187 let registry = ParserRegistry::default()
1188 .with_parser(
1189 "value",
1190 map(prefix(number_int(), lit("value:")), |value: String| {
1191 value.parse::<i32>().unwrap()
1192 }),
1193 )
1194 .with_parser(
1195 "add",
1196 map(
1197 seq_del(lit("+"), [inject("value"), inject("value")]),
1198 |mut values: Vec<ParserOutput>| {
1199 let b = values.remove(1).consume::<i32>().ok().unwrap();
1200 let a = values.remove(0).consume::<i32>().ok().unwrap();
1201 a + b
1202 },
1203 ),
1204 )
1205 .with_parser(
1206 "mul",
1207 map(
1208 seq_del(lit("*"), [inject("value"), inject("value")]),
1209 |mut values: Vec<ParserOutput>| {
1210 let b = values.remove(1).consume::<i32>().ok().unwrap();
1211 let a = values.remove(0).consume::<i32>().ok().unwrap();
1212 a * b
1213 },
1214 ),
1215 );
1216 generator.install(®istry).unwrap();
1217
1218 let (rest, result) = registry.parse("template_value", "42").unwrap();
1219 assert_eq!(rest, "");
1220 assert_eq!(result.consume::<i32>().ok().unwrap(), 42);
1221
1222 let (rest, result) = registry.parse("template_add", "40 2").unwrap();
1223 assert_eq!(rest, "");
1224 assert_eq!(result.consume::<i32>().ok().unwrap(), 42);
1225
1226 let (rest, result) = registry.parse("template_mul", "6 4").unwrap();
1227 assert_eq!(rest, "");
1228 assert_eq!(result.consume::<i32>().ok().unwrap(), 24);
1229 }
1230
1231 #[intuicio_function(transformer = "DynamicManagedValueTransformer")]
1232 fn map_value(value: String) -> f32 {
1233 value.parse().unwrap()
1234 }
1235
1236 #[intuicio_function(transformer = "DynamicManagedValueTransformer")]
1237 fn map_value_error(_error: Box<dyn Error>) -> Box<dyn Error> {
1238 "Expected value".into()
1239 }
1240
1241 #[intuicio_function(transformer = "DynamicManagedValueTransformer")]
1242 fn map_op_add(mut value: Vec<ParserOutput>) -> f32 {
1243 let b = value.remove(2).consume::<f32>().ok().unwrap();
1244 let a = value.remove(1).consume::<f32>().ok().unwrap();
1245 a + b
1246 }
1247
1248 #[intuicio_function(transformer = "DynamicManagedValueTransformer")]
1249 fn map_op_sub(mut value: Vec<ParserOutput>) -> f32 {
1250 let b = value.remove(2).consume::<f32>().ok().unwrap();
1251 let a = value.remove(1).consume::<f32>().ok().unwrap();
1252 a - b
1253 }
1254
1255 #[intuicio_function(transformer = "DynamicManagedValueTransformer")]
1256 fn map_op_mul(mut value: Vec<ParserOutput>) -> f32 {
1257 let b = value.remove(2).consume::<f32>().ok().unwrap();
1258 let a = value.remove(1).consume::<f32>().ok().unwrap();
1259 a * b
1260 }
1261
1262 #[intuicio_function(transformer = "DynamicManagedValueTransformer")]
1263 fn map_op_div(mut value: Vec<ParserOutput>) -> f32 {
1264 let b = value.remove(2).consume::<f32>().ok().unwrap();
1265 let a = value.remove(1).consume::<f32>().ok().unwrap();
1266 a / b
1267 }
1268
1269 #[test]
1270 fn test_calculator() {
1271 let grammar = std::fs::read_to_string("./resources/calculator.txt").unwrap();
1272 let generator = Generator::new(&grammar).unwrap();
1273 assert_eq!(
1274 generator
1275 .parsers
1276 .iter()
1277 .map(|(k, _, _)| k.as_str())
1278 .collect::<Vec<_>>(),
1279 vec![
1280 "value", "op_add", "op_sub", "op_mul", "op_div", "op", "expr"
1281 ]
1282 );
1283
1284 let registry = ParserRegistry::default().with_extension(
1285 DynamicExtensionBuilder::default()
1286 .with(map_value::define_function)
1287 .with(map_value_error::define_function)
1288 .with(map_op_add::define_function)
1289 .with(map_op_sub::define_function)
1290 .with(map_op_mul::define_function)
1291 .with(map_op_div::define_function)
1292 .build(),
1293 );
1294 generator.install(®istry).unwrap();
1295
1296 let (rest, result) = registry.parse("value", "42").unwrap();
1297 assert_eq!(rest, "");
1298 assert_eq!(result.consume::<f32>().ok().unwrap(), 42.0);
1299
1300 let (rest, result) = registry.parse("op_add", "+ 40 2").unwrap();
1301 assert_eq!(rest, "");
1302 assert_eq!(result.consume::<f32>().ok().unwrap(), 42.0);
1303
1304 let (rest, result) = registry.parse("op_sub", "- 40 2").unwrap();
1305 assert_eq!(rest, "");
1306 assert_eq!(result.consume::<f32>().ok().unwrap(), 38.0);
1307
1308 let (rest, result) = registry.parse("op_mul", "* 40 2").unwrap();
1309 assert_eq!(rest, "");
1310 assert_eq!(result.consume::<f32>().ok().unwrap(), 80.0);
1311
1312 let (rest, result) = registry.parse("op_div", "/ 40 2").unwrap();
1313 assert_eq!(rest, "");
1314 assert_eq!(result.consume::<f32>().ok().unwrap(), 20.0);
1315
1316 let (rest, result) = registry.parse("op", "(+ 40 2)").unwrap();
1317 assert_eq!(rest, "");
1318 assert_eq!(result.consume::<f32>().ok().unwrap(), 42.0);
1319
1320 let (rest, result) = registry.parse("expr", "(+ 40 2)").unwrap();
1321 assert_eq!(rest, "");
1322 assert_eq!(result.consume::<f32>().ok().unwrap(), 42.0);
1323
1324 let (rest, result) = registry.parse("expr", "(+ (* 4 10) 2)").unwrap();
1325 assert_eq!(rest, "");
1326 assert_eq!(result.consume::<f32>().ok().unwrap(), 42.0);
1327
1328 let (rest, result) = registry.parse("expr", "(+ (* 4 10) (/ 4 2))").unwrap();
1329 assert_eq!(rest, "");
1330 assert_eq!(result.consume::<f32>().ok().unwrap(), 42.0);
1331
1332 let (rest, result) = registry
1333 .parse("expr", "(+ (* 4 10) (/ (- 5 1) 2))")
1334 .unwrap();
1335 assert_eq!(rest, "");
1336 assert_eq!(result.consume::<f32>().ok().unwrap(), 42.0);
1337 }
1338
1339 #[test]
1340 fn test_extending() {
1341 let grammar = std::fs::read_to_string("./resources/extending.txt").unwrap();
1342 let generator = Generator::new(&grammar).unwrap();
1343 assert_eq!(
1344 generator
1345 .parsers
1346 .iter()
1347 .map(|(k, _, _)| k.as_str())
1348 .collect::<Vec<_>>(),
1349 vec!["main", "main2", "main3"]
1350 );
1351
1352 let registry = ParserRegistry::default();
1353 generator.install(®istry).unwrap();
1354
1355 let (rest, result) = registry.parse("main", "bar").unwrap();
1356 assert_eq!(rest, "");
1357 assert!(result.is::<String>());
1358 }
1359}