intuicio_parser/
generator.rs

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    /// [parser id, parser handle, extender id?]
74    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(&registry, 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                &registry,
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(&registry, "//foo\r\n").unwrap().0, "");
1069        assert_eq!(comment().parse(&registry, "/*bar*/").unwrap().0, "");
1070        assert_eq!(
1071            comment()
1072                .parse(&registry, "//macro => @main:(\r\n")
1073                .unwrap()
1074                .0,
1075            ""
1076        );
1077
1078        assert_eq!(
1079            parser_string()
1080                .parse(&registry, "string{\"(\" \")\"}")
1081                .unwrap()
1082                .0,
1083            ""
1084        );
1085
1086        let (rest, result) = parser_template()
1087            .parse(&registry, "template{\"foo\" ```@{}@```}")
1088            .unwrap();
1089        assert_eq!(rest, "");
1090        assert_eq!(
1091            result
1092                .consume::<ParserHandle>()
1093                .ok()
1094                .unwrap()
1095                .parse(&registry, "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(&registry, "#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(&registry, "foo")
1114                .unwrap()
1115                .1
1116                .is::<ParserNoValue>()
1117        );
1118        parser.extend(lit("foo"));
1119        assert!(parser.parse(&registry, "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(&registry).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(&registry).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(&registry).unwrap();
1354
1355        let (rest, result) = registry.parse("main", "bar").unwrap();
1356        assert_eq!(rest, "");
1357        assert!(result.is::<String>());
1358    }
1359}