on c19bc7a help sign in
1206 lines 21 kB history raw
1:- :~ navhome/'/docs/'
2 sort/'33'
3 title/'4f: Parsing (Rule-Builders)'
4 ==
6;>
9# 4f: parsing (rule builders)
11### `++bass`
13Parser modifier: LSB
14ordered `++list` as atom of a `++base`.
16#### Accepts
18`wuc` is an atom.
20`tyd` is a `++rule`.
22#### Produces
24A `++rule`.
26#### Source
28```
29 ++ bass
30 |* {wuc/@ tyd/rule}
31 %+ cook
32 |= waq/(list @)
33 %+ roll
34 waq
35 =|({p/@ q/@} |.((add p (mul wuc q))))
36 tyd
37 ::
38```
40#### Examples
42```
43 > (scan "123" (bass 10 (star dit)))
44 q=123
45 > (scan "123" (bass 8 (star dit)))
46 q=83
47 > `@ub`(scan "123" (bass 8 (star dit)))
48 0b101.0011
49```
52---
54### `++boss`
56Parser modifier: LSB
58Ordered `++list` as atom of a `++base`.
60#### Accepts
62`wuc` is an atom.
64`tyd` is a `++rule`.
66#### Produces
68A `++rule`.
70#### Source
72```
73 ++ boss
74 |* {wuc/@ tyd/rule}
75 %+ cook
76 |= waq/(list @)
77 %+ reel
78 waq
79 =|({p/@ q/@} |.((add p (mul wuc q))))
80 tyd
81 ::
82```
84#### Examples
86```
87 > (scan "123" (boss 10 (star dit)))
88 q=321
90 > `@t`(scan "bam" (boss 256 (star alp)))
91 'bam'
93 > `@ux`(scan "bam" (boss 256 (star alp)))
94 0x6d.6162
95```
97---
98### `++cold`
100Replace with constant
102Parser modifier. Accepts a `++rule` `sef` and produces a parser that
103produces a constant `cus`, assuming `sef` is successful.
105#### Accepts
107`cus` is a constant noun.
109`sef` is a `++rule`.
111#### Produces
113An `++edge`.
115#### Source
117```
118 ++ cold :: replace w+ constant
119 ~/ %cold
120 |* {cus/* sef/rule}
121 ~/ %fun
122 |= tub/nail
123 =+ vex=(sef tub)
124 ?~ q.vex
125 vex
126 [p=p.vex q=[~ u=[p=cus q=q.u.q.vex]]]
127```
129#### Examples
131```
132 > ((cold %foo (just 'a')) [[1 1] "abc"])
133 [p=[p=1 q=2] q=[~ u=[p=%foo q=[p=[p=1 q=2] q="bc"]]]]
135 > ((cold %foo (just 'a')) [[1 1] "bc"])
136 [p=[p=1 q=1] q=~]
137```
140---
141### `++cook`
143Apply gate
145Parser modifier. Produces a parser that takes a (successful) result of a
146`++rule` `sef` and slams it through `poq`.
148#### Accepts
150`poq` is a gate.
152`sef` is a `++rule`.
154#### Produces
156An `++rule`.
158#### Source
160```
161 ++ cook :: apply gate
162 ~/ %cook
163 |* {poq/gate sef/rule}
164 ~/ %fun
165 |= tub/nail
166 =+ vex=(sef tub)
167 ?~ q.vex
168 vex
169 [p=p.vex q=[~ u=[p=(poq p.u.q.vex) q=q.u.q.vex]]]
170 ::
171```
173#### Examples
175```
176 > ((cook ,@ud (just 'a')) [[1 1] "abc"])
177 [p=[p=1 q=2] q=[~ u=[p=97 q=[p=[p=1 q=2] q="bc"]]]]
179 > ((cook ,@tas (just 'a')) [[1 1] "abc"])
180 [p=[p=1 q=2] q=[~ u=[p=%a q=[p=[p=1 q=2] q="bc"]]]]
182 > ((cook |=(a=@ +(a)) (just 'a')) [[1 1] "abc"])
183 [p=[p=1 q=2] q=[~ u=[p=98 q=[p=[p=1 q=2] q="bc"]]]]
185 > ((cook |=(a=@ `@t`+(a)) (just 'a')) [[1 1] "abc"])
186 [p=[p=1 q=2] q=[~ u=[p='b' q=[p=[p=1 q=2] q="bc"]]]]
187```
190---
191### `++easy`
193Always parse
195Parser generator. Produces a parser that succeeds with given noun `huf`
196without consuming any text.
198#### Accepts
200`huf` is a noun.
202#### Produces
204A `++rule`.
206#### Source
208```
209 ++ easy :: always parse
210 ~/ %easy
211 |* huf=*
212 ~/ %fun
213 |= tub=nail
214 ^- (like ,_huf)
215 [p=p.tub q=[~ u=[p=huf q=tub]]]
216 ::
217```
219#### Examples
221```
222 > ((easy %foo) [[1 1] "abc"])
223 [p=[p=1 q=1] q=[~ [p=%foo q=[p=[p=1 q=1] q="abc"]]]]
225 > ((easy %foo) [[1 1] "bc"])
226 [p=[p=1 q=1] q=[~ [p=%foo q=[p=[p=1 q=1] q="bc"]]]]
228 > ((easy 'a') [[1 1] "bc"])
229 [p=[p=1 q=1] q=[~ [p='a' q=[p=[p=1 q=1] q="bc"]]]]
230```
233---
234### `++full`
236Parse to end
238Parser modifier. Accepts a `++rule` `sef`, and produces a parser that succeeds only
239when the of `tub` is fully consumed using `sef`.
241#### Accepts
243`sef` is a `++rule`.
245#### Produces
247A `++rule`.
249#### Source
251```
252 ++ full :: parse to end
253 |* sef=_rule
254 |= tub=nail
255 =+ vex=(sef tub)
256 ?~(q.vex vex ?:(=(~ q.q.u.q.vex) vex [p=p.vex q=~]))
257 ::
258```
260#### Examples
262```
263 > ((full (just 'a')) [[1 1] "ab"])
264 [p=[p=1 q=2] q=~]
266 > ((full (jest 'ab')) [[1 1] "ab"])
267 [p=[p=1 q=3] q=[~ u=[p='ab' q=[p=[p=1 q=3] q=""]]]]
269 > ((full ;~(plug (just 'a') (just 'b'))) [[1 1] "ab"])
270 [p=[p=1 q=3] q=[~ u=[p=[~~a ~~b] q=[p=[p=1 q=3] q=""]]]]
271```
274---
275### `++funk`
277Add to tape
279Parser modifier: prepend text to `++tape` before applying parser.
281#### Accepts
283`pre` is a `++tape`
285`sef` is a `++rule`
287#### Produces
289A `++rule`.
291#### Source
293```
294 ++ funk :: add to tape first
295 |* {pre/tape sef/rule}
296 |= tub/nail
297 (sef p.tub (weld pre q.tub))
298```
300#### Examples
302```
303 > ((funk "abc prefix-" (jest 'abc')) [[1 1] "to be parsed"])
304 [p=[p=1 q=4] q=[~ [p='abc' q=[p=[p=1 q=4] q=" prefix-to be parsed"]]]]
306 > ((funk "parse" (just 'a')) [[1 4] " me"])
307 [p=[p=1 q=4] q=~]
308```
311---
312### `++here`
314Place-based apply
316Parser modifier. Similar to `++cook` in that it produces a parser that takes a
317(successful) result of `sef` and slams it through `hez`. `hez` accepts a
318`++pint` `a` and a noun `b`, which is what the parser parsed.
320#### Accepts
322`hez` is a gate.
324`sef` is a `++rule`
326#### Produces
328A `++rule`.
330#### Source
332```
333 ++ here :: place-based apply
334 ~/ %here
335 |* {hez/_|=({a/pint b/*} [a b]) sef/rule}
336 ~/ %fun
337 |= tub/nail
338 =+ vex=(sef tub)
339 ?~ q.vex
340 vex
341 [p=p.vex q=[~ u=[p=(hez [p.tub p.q.u.q.vex] p.u.q.vex) q=q.u.q.vex]]]
342 ::
343```
345#### Examples
347```
348 > (scan "abc" (star alf))
349 "abc"
351 > (scan "abc" (here |*(^ +<) (star alf)))
352 [[[p=1 q=1] p=1 q=4] "abc"]
354 > (scan "abc" (star (here |*(^ +<) alf)))
355 ~[[[[p=1 q=1] p=1 q=2] ~~a] [[[p=1 q=2] p=1 q=3] ~~b] [[[p=1 q=3] p=1 q=4] ~~c]]
356```
359---
360### `++ifix`
362Infix
364Parser modifier: surround with pair of `++rule`s, the output of which is
365discarded.
367#### Accepts
369`fel` is a pair of `++rule`s.
371`hof` is a `++rule`.
373#### Produces
375A `++rule`.
377#### Source
379```
380 ++ ifix
381 |* {fel/{rule rule} hof/rule}
382 ~! +<
383 ~! +<:-.fel
384 ~! +<:+.fel
385 ;~(pfix -.fel ;~(sfix hof +.fel))
386 ::
387```
389#### Examples
391```
392 > (scan "-40-" (ifix [hep hep] dem))
393 q=40
395 > (scan "4my4" (ifix [dit dit] (star alf)))
396 "my"
397```
400---
401### `++jest`
403Match a cord
405Match and consume a cord.
407#### Accepts
409`daf` is a `@t`.
411#### Produces
413An `++edge`.
415#### Source
417```
418 ++ jest :: match a cord
419 |= daf/@t
420 |= tub/nail
421 =+ fad=daf
422 |- ^- (like @t)
423 ?: =(`@`0 daf)
424 [p=p.tub q=[~ u=[p=fad q=tub]]]
425 ?: |(?=($~ q.tub) !=((end 3 1 daf) i.q.tub))
426 (fail tub)
427 $(p.tub (lust i.q.tub p.tub), q.tub t.q.tub, daf (rsh 3 1 daf))
428 ::
429```
431#### Examples
433```
434 > ((jest 'abc') [[1 1] "abc"])
435 [p=[p=1 q=4] q=[~ [p='abc' q=[p=[p=1 q=4] q=""]]]]
437 > (scan "abc" (jest 'abc'))
438 'abc'
440 > (scan "abc" (jest 'acb'))
441 ! {1 2}
442 ! 'syntax-error'
443 ! exit
445 > ((jest 'john doe') [[1 1] "john smith"])
446 [p=[p=1 q=6] q=~]
448 > ((jest 'john doe') [[1 1] "john doe"])
449 [p=[p=1 q=9] q=[~ [p='john doe' q=[p=[p=1 q=9] q=""]]]]
450```
453---
454### `++just`
456Match a char
458Match and consume a single character.
460#### Accepts
462`daf` is a `++char`
464#### Produces
466A `++rule`.
468#### Source
470```
471 ++ just :: XX redundant, jest
472 ~/ %just :: match a char
473 |= daf/char
474 ~/ %fun
475 |= tub/nail
476 ^- (like char)
477 ?~ q.tub
478 (fail tub)
479 ?. =(daf i.q.tub)
480 (fail tub)
481 (next tub)
482 ::
483```
485#### Examples
487```
488 > ((just 'a') [[1 1] "abc"])
489 [p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
491 > (scan "abc" (just 'a'))
492 ! {1 2}
493 ! 'syntax-error'
494 ! exit
496 > (scan "a" (just 'a'))
498 ~~a
499 > (scan "%" (just '%'))
500 ~~~25.
501```
504---
505### `++knee`
507Recursive parsers
509Used for recursive parsers, which would otherwise be infinite when
510compiled.
512#### Accepts
514`gar` is a noun.
516`sef` is a gate that accepts a `++rule`
518#### Produces
520A `++rule`.
522#### Source
524```
525 ++ knee :: callbacks
526 |* {gar/* sef/_|.(*rule)}
527 |= tub/nail
528 ^- (like _gar)
529 ((sef) tub)
530 ::
531```
533#### Examples
535```
536 > |-(;~(plug prn ;~(pose $ (easy ~))))
537 ! rest-loop
538 ! exit
540 > |-(;~(plug prn ;~(pose (knee *tape |.(^$)) (easy ~))))
541 < 1.obo
542 [ c=c=tub=[p=[p=@ud q=@ud] q=""]
543 b
544 < 1.bes
545 [ c=tub=[p=[p=@ud q=@ud] q=""]
546 b=<1.tnv [tub=[p=[p=@ud q=@ud] q=""] <1.ktu [daf=@tD <414.fvk 101.jzo 1.ypj %164>]>]>
547 a=<1.fvg [tub=[p=[p=@ud q=@ud] q=""] <1.khu [[les=@ mos=@] <414.fvk 101.jzo 1.ypj %164>]>]>
548 v=<414.fvk 101.jzo 1.ypj %164>
549 ]
550 >
551 a
552 ... 450 lines omitted ...
553 ]
554 >
555 > (scan "abcd" |-(;~(plug prn ;~(pose (knee *tape |.(^$)) (easy ~)))))
556 [~~a "bcd"]
557```
560---
561### `++mask`
563Match char
565Parser generator. Matches the next character if it is in a list of
566characters.
568#### Accepts
570`bud` is a list of `++char`
572#### Produces
574A `++rule`.
576#### Source
578```
579 ++ mask :: match char in set
580 ~/ %mask
581 |= bud/(list char)
582 ~/ %fun
583 |= tub/nail
584 ^- (like char)
585 ?~ q.tub
586 (fail tub)
587 ?. (lien bud |=(a/char =(i.q.tub a)))
588 (fail tub)
589 (next tub)
590 ::
591```
593#### Examples
595```
596 > (scan "a" (mask "cba"))
597 ~~a
599 > ((mask "abc") [[1 1] "abc"])
600 [p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
602 > ((mask "abc") [[1 1] "bbc"])
603 [p=[p=1 q=2] q=[~ [p=~~b q=[p=[p=1 q=2] q="bc"]]]]
605 > ((mask "abc") [[1 1] "dbc"])
606 [p=[p=1 q=1] q=~]
607```
609---
610### `++more`
612Parse list with delimiter
614Parser modifier: Parse a list of matches using a delimiter `++rule`.
616#### Accepts
618`bus` is a `++rule`.
620`fel` is a `++rule`.
622#### Produces
624A `++rule`.
626#### Source
628```
629 ++ more
630 |* {bus/rule fel/rule}
631 ;~(pose (most bus fel) (easy ~))
632 ::
633```
635#### Examples
637```
638 > (scan "" (more ace dem))
639 ~
641 > (scan "40 20" (more ace dem))
642 [q=40 ~[q=20]]
644 > (scan "40 20 60 1 5" (more ace dem))
645 [q=40 ~[q=20 q=60 q=1 q=5]]
646```
649---
650### `++most`
652Parse list of at least one match
654Parser modifier: parse a `++list` of at least one match using a delimiter `++rule`.
656#### Accepts
658`bus` is a `++rule`.
660`fel` is a `++rule`.
662#### Produces
664A `++rule`.
666#### Source
668```
669 ++ most
670 |* {bus/rule fel/rule}
671 ;~(plug fel (star ;~(pfix bus fel)))
672 ::
673```
675#### Examples
677```
678 > (scan "40 20" (most ace dem))
679 [q=40 ~[q=20]]
681 > (scan "40 20 60 1 5" (most ace dem))
682 [q=40 ~[q=20 q=60 q=1 q=5]]
684 > (scan "" (most ace dem))
685 ! {1 1}
686 ! exit
687```
690---
691### `++next`
693Consume char
695Consume any character, producing it as a result.
697#### Accepts
699`tub` is a `++nail`
701#### Produces
703An `++edge`.
705#### Source
707```
708 ++ next :: consume a char
709 |= tub/nail
710 ^- (like char)
711 ?~ q.tub
712 (fail tub)
713 =+ zac=(lust i.q.tub p.tub)
714 [zac [~ i.q.tub [zac t.q.tub]]]
715 ::
716```
718#### Examples
720```
721 > (next [[1 1] "ebc"])
722 [p=[p=1 q=2] q=[~ [p=~~e q=[p=[p=1 q=2] q="bc"]]]]
724 > (next [[1 1] "john jumps jones"])
725 [p=[p=1 q=2] q=[~ [p=~~j q=[p=[p=1 q=2] q="ohn jumps jones"]]]]
726```
729---
731### `++plus`
733List of at least one match.
735Parser modifier: parse `++list` of at least one match.
737#### Accepts
739`fel` is a `++rule`.
741#### Produces
743A `++rule`.
745#### Source
747```
748 ++ plus |*(fel/rule ;~(plug fel (star fel)))
749```
751#### Examples
753```
754 > (scan ">>>>" (cook lent (plus gar)))
755 4
757 > (scan "- - " (plus ;~(pose ace hep)))
758 [~~- " - "]
760 > `tape`(scan "- - " (plus ;~(pose ace hep)))
761 "- - "
763 > `(pole ,@t)`(scan "- - " (plus ;~(pose ace hep)))
764 ['-' [' ' [' ' ['-' [' ' ~]]]]]
765```
768---
769### `++sear`
771Conditional `++cook`
773Conditional `++cook`. Slams the result through a gate that produces
774a unit; if that unit is empty, fail.
776#### Accepts
778`tub` is a `++nail`.
780#### Produces
782A `++rule`.
784#### Source
786```
787 ++ sear :: conditional cook
788 |* {pyq/$-(* (unit)) sef/rule}
789 |= tub/nail
790 =+ vex=(sef tub)
791 ?~ q.vex
792 vex
793 =+ gey=(pyq p.u.q.vex)
794 ?~ gey
795 [p=p.vex q=~]
796 [p=p.vex q=[~ u=[p=u.gey q=q.u.q.vex]]]
797 ::
798```
800#### Examples
802```
803 > ((sear |=(a/* ?@(a (some a) ~)) (just `a`)) [[1 1] "abc"])
804 [p=[p=1 q=2] q=[~ u=[p=97 q=[p=[p=1 q=2] q="bc"]]]]
806 > ((sear |=(* ~) (just 'a')) [[1 1] "abc"])
807 [p=[p=1 q=2] q=~]
808```
811---
812### `++shim`
814Char in range
816Match characters (`++char`) within a range.
818#### Accepts
820`les` is an atom.
822`mos` is an atom.
824#### Produces
826A `++rule`.
828#### Source
830```
831 ++ shim :: match char in range
832 ~/ %shim
833 |= {les/@ mos/@}
834 ~/ %fun
835 |= tub/nail
836 ^- (like char)
837 ?~ q.tub
838 (fail tub)
839 ?. ?&((gte i.q.tub les) (lte i.q.tub mos))
840 (fail tub)
841 (next tub)
842 ::
843```
845#### Examples
847```
848 > ((shim 'a' 'z') [[1 1] "abc"])
849 [p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
851 > ((shim 'a' 'Z') [[1 1] "abc"])
852 [p=[p=1 q=1] q=~]
854 > ((shim 'a' 'Z') [[1 1] "Abc"])
855 [p=[p=1 q=2] q=[~ [p=~~~41. q=[p=[p=1 q=2] q="bc"]]]]
856```
859---
860### `++slug`
862Use gate to parse delimited list
864Parser modifier: By composing with a gate, parse a delimited `++list` of
865matches.
867#### Accepts
869`bus` is a `++rule`.
871`fel` is a `++rule`.
873#### Produces
875A `++rule`.
877#### Source
879```
880 ++ slug
881 |* raq/_|*({a/* b/*} [a b])
882 |* {bus/rule fel/rule}
883 ;~((comp raq) fel (stir +<+.raq raq ;~(pfix bus fel)))
884 ::
885```
887#### Examples
889```
890 > (scan "20+5+110" ((slug add) lus dem))
891 135
893 > `@t`(scan "a b c" ((slug |=(a/[@ @t] (cat 3 a))) ace alp))
894 'abc'
895```
898---
899### `++stag`
901Add label
903Add a label to an edge parsed by a rule.
905#### Accepts
907`gob` is a noun.
909`sef` is a rule.
911#### Produces
913A `++rule`.
915#### Source
917```
918 ++ stag :: add a label
919 ~/ %stag
920 |* {gob/* sef/rule}
921 ~/ %fun
922 |= tub/nail
923 =+ vex=(sef tub)
924 ?~ q.vex
925 vex
926 [p=p.vex q=[~ u=[p=[gob p.u.q.vex] q=q.u.q.vex]]]
927 ::
928```
930#### Examples
932```
933 > ((stag %foo (just 'a')) [[1 1] "abc"])
934 [p=[p=1 q=2] q=[~ u=[p=[%foo ~~a] q=[p=[p=1 q=2] q="bc"]]]]
936 > ((stag "xyz" (jest 'abc')) [[1 1] "abc"])
937 [p=[p=1 q=4] q=[~ u=[p=["xyz" 'abc'] q=[p=[p=1 q=4] q=""]]]]
939 > ((stag 10.000 (shim 0 100)) [[1 1] "abc"])
940 [p=[p=1 q=2] q=[~ u=[p=[10.000 ~~a] q=[p=[p=1 q=2] q="bc"]]]]
941```
944---
945### `++star`
947List of matches
949Parser modifier: parse `++list` of matches.
951#### Accepts
953`fel` is a `++rule`.
955#### Produces
957```
958 ++ star :: 0 or more times
959 |* fel/rule
960 (stir `(list _(wonk *fel))`~ |*({a/* b/*} [a b]) fel)
961```
963#### Examples
965```
966 > (scan "aaaaa" (just 'a'))
967 ! {1 2}
968 ! 'syntax-error'
969 ! exit
971 > (scan "aaaaa" (star (just 'a')))
972 "aaaaa"
974 > (scan "abcdef" (star (just 'a')))
975 ! {1 2}
976 ! 'syntax-error'
977 ! exit
979 > (scan "abcabc" (star (jest 'abc')))
980 <|abc abc|>
982 > (scan "john smith" (star (shim 0 200)))
983 "john smith"
984```
987---
988### `++stet`
990Add faces
992Add faces `[p q]` to range-parser pairs in a list.
994#### Accepts
996`leh` is a list of range-parsers.
998#### Produces
1002#### Source
1004```
1005 ++ stet
1006 |* leh/(list {?(@ {@ @}) rule})
1007 |-
1008 ?~ leh
1010 [i=[p=-.i.leh q=+.i.leh] t=$(leh t.leh)]
1011 ::
1012```
1014#### Examples
1016```
1017 > (stet (limo [[5 (just 'a')] [1 (jest 'abc')] [[1 1] (shim 0 200)]
1018 [[1 10] (cold %foo (just 'a'))]~]))
1019 ~[
1020 [p=5 q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
1021 [p=1 q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
1022 [p=[1 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
1023 [p=[1 10] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
1025 > [[[1 1] (just 'a')] [[2 1] (shim 0 200)] ~]
1026 [ [[1 1] <1.tnv [tub=[p=[p=@ud q=@ud] q=""] <1.ktu [daf=@tD <414.fvk 101.jzo 1.ypj %164>]>]>]
1027 [[2 1] <1.fvg [tub=[p=[p=@ud q=@ud] q=""] <1.khu [[les=@ mos=@] <414.fvk 101.jzo 1.ypj %164>]>]>]
1030 > (stet (limo [[[1 1] (just 'a')] [[2 1] (shim 0 200)] ~]))
1031 ~[
1032 [p=[1 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
1033 [p=[2 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
1035```
1038---
1039### `++stew`
1041Switch by first
1043```
1044 ++ stew :: switch by first char
1045 ~/ %stew
1046 |* leh/(list {p/?(@ {@ @}) q/rule}) :: char+range keys
1047 =+ ^= wor :: range complete lth
1048 |= {ort/?(@ {@ @}) wan/?(@ {@ @})}
1049 ?@ ort
1050 ?@(wan (lth ort wan) (lth ort -.wan))
1051 ?@(wan (lth +.ort wan) (lth +.ort -.wan))
1052 =+ ^= hel :: build parser map
1053 =+ hel=`(tree _?>(?=(^ leh) i.leh))`~
1054 |- ^+ hel
1055 ?~ leh
1057 =+ yal=$(leh t.leh)
1058 |- ^+ hel
1059 ?~ yal
1060 [i.leh ~ ~]
1061 ?: (wor p.i.leh p.n.yal)
1062 =+ nuc=$(yal l.yal)
1063 ?> ?=(^ nuc)
1064 ?: (vor p.n.yal p.n.nuc)
1065 [n.yal nuc r.yal]
1066 [n.nuc l.nuc [n.yal r.nuc r.yal]]
1067 =+ nuc=$(yal r.yal)
1068 ?> ?=(^ nuc)
1069 ?: (vor p.n.yal p.n.nuc)
1070 [n.yal l.yal nuc]
1071 [n.nuc [n.yal l.yal l.nuc] r.nuc]
1072 ~% %fun ..^$ ~
1073 |= tub/nail
1074 ?~ q.tub
1075 (fail tub)
1076 |-
1077 ?~ hel
1078 (fail tub)
1079 ?: ?@ p.n.hel
1080 =(p.n.hel i.q.tub)
1081 ?&((gte i.q.tub -.p.n.hel) (lte i.q.tub +.p.n.hel))
1082 :: (q.n.hel [(lust i.q.tub p.tub) t.q.tub])
1083 (q.n.hel tub)
1084 ?: (wor i.q.tub p.n.hel)
1085 $(hel l.hel)
1086 $(hel r.hel)
1087 ::
1088```
1091Parser generator. From an associative `++list` of characters or character
1092ranges to `++rule`s, construct a `++map`, and parse `++tape`s only
1093with `++rules` associated with a range that the `++tape`'s first character falls in.
1097---
1098### `++stir`
1100Parse repeatedly
1102Parse with `++rule` as many times as possible, and fold over results with a
1103binary gate.
1105#### Accepts
1107`rud` is a noun.
1109`raq` is a gate that takes two nouns and produces a cell.
1111`fel` is a rule.
1113#### Produces
1115A rule.
1117#### Source
1119```
1120 ++ stun :: parse several times
1121 |* {lig/{@ @} fel/rule}
1122 |= tub/nail
1123 ^- (like (list _(wonk (fel))))
1124 ?: =(0 +.lig)
1125 [p.tub [~ ~ tub]]
1126 =+ vex=(fel tub)
1127 ?~ q.vex
1128 ?: =(0 -.lig)
1129 [p.vex [~ ~ tub]]
1130 vex
1131 =+ ^= wag %= $
1132 -.lig ?:(=(0 -.lig) 0 (dec -.lig))
1133 +.lig ?:(=(0 +.lig) 0 (dec +.lig))
1134 tub q.u.q.vex
1135 ==
1136 ?~ q.wag
1137 wag
1138 [p.wag [~ [p.u.q.vex p.u.q.wag] q.u.q.wag]]
1139```
1141#### Examples
1143```
1144 > (scan "abc" (stir *@ add prn))
1145 294
1147 > (roll "abc" add)
1148 b=294
1149```
1152---
1153### `++stun`
1155Parse several times
1157Parse bounded number of times.
1159#### Accepts
1161`[les=@ mos=@]` is a cell of atoms indicating the bounds.
1163`fel` is a `++rule`.
1165#### Produces
1167A `++rule`.
1169#### Source
1171```
1172 ++ stun :: parse several times
1173 |* {lig/{@ @} fel/rule}
1174 |= tub/nail
1175 ^- (like (list _(wonk (fel))))
1176 ?: =(0 +.lig)
1177 [p.tub [~ ~ tub]]
1178 =+ vex=(fel tub)
1179 ?~ q.vex
1180 ?: =(0 -.lig)
1181 [p.vex [~ ~ tub]]
1182 vex
1183 =+ ^= wag %= $
1184 -.lig ?:(=(0 -.lig) 0 (dec -.lig))
1185 +.lig ?:(=(0 +.lig) 0 (dec +.lig))
1186 tub q.u.q.vex
1187 ==
1188 ?~ q.wag
1189 wag
1190 [p.wag [~ [p.u.q.vex p.u.q.wag] q.u.q.wag]]
1191```
1193#### Examples
1195```
1196 > ((stun [5 10] prn) [1 1] "aquickbrownfoxran")
1197 [p=[p=1 q=11] q=[~ [p="aquickbrow" q=[p=[p=1 q=11] q="nfoxran"]]]]
1199 > ((stun [5 10] prn) [1 1] "aquickbro")
1200 [p=[p=1 q=10] q=[~ [p="aquickbro" q=[p=[p=1 q=10] q=""]]]]
1202 > ((stun [5 10] prn) [1 1] "aqui")
1203 [p=[p=1 q=5] q=~]
1204```
1206---