intuicio_parser/
generator.rs

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