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