on 159efe7 help sign in
1194 lines 21 kB history raw
1+++
2title = "4f: Parsing (Rule-Builders)"
3weight = 33
4template = "doc.html"
5+++
6### `++bass`
8Parser modifier: LSB
9ordered `++list` as atom of a `++base`.
11#### Accepts
13`wuc` is an atom.
15`tyd` is a `++rule`.
17#### Produces
19A `++rule`.
21#### Source
23```
24 ++ bass
25 |* {wuc/@ tyd/rule}
26 %+ cook
27 |= waq/(list @)
28 %+ roll
29 waq
30 =|({p/@ q/@} |.((add p (mul wuc q))))
31 tyd
32 ::
33```
35#### Examples
37```
38 > (scan "123" (bass 10 (star dit)))
39 q=123
40 > (scan "123" (bass 8 (star dit)))
41 q=83
42 > `@ub`(scan "123" (bass 8 (star dit)))
43 0b101.0011
44```
47---
49### `++boss`
51Parser modifier: LSB
53Ordered `++list` as atom of a `++base`.
55#### Accepts
57`wuc` is an atom.
59`tyd` is a `++rule`.
61#### Produces
63A `++rule`.
65#### Source
67```
68 ++ boss
69 |* {wuc/@ tyd/rule}
70 %+ cook
71 |= waq/(list @)
72 %+ reel
73 waq
74 =|({p/@ q/@} |.((add p (mul wuc q))))
75 tyd
76 ::
77```
79#### Examples
81```
82 > (scan "123" (boss 10 (star dit)))
83 q=321
85 > `@t`(scan "bam" (boss 256 (star alp)))
86 'bam'
88 > `@ux`(scan "bam" (boss 256 (star alp)))
89 0x6d.6162
90```
92---
93### `++cold`
95Replace with constant
97Parser modifier. Accepts a `++rule` `sef` and produces a parser that
98produces a constant `cus`, assuming `sef` is successful.
100#### Accepts
102`cus` is a constant noun.
104`sef` is a `++rule`.
106#### Produces
108An `++edge`.
110#### Source
112```
113 ++ cold :: replace w+ constant
114 ~/ %cold
115 |* {cus/* sef/rule}
116 ~/ %fun
117 |= tub/nail
118 =+ vex=(sef tub)
119 ?~ q.vex
120 vex
121 [p=p.vex q=[~ u=[p=cus q=q.u.q.vex]]]
122```
124#### Examples
126```
127 > ((cold %foo (just 'a')) [[1 1] "abc"])
128 [p=[p=1 q=2] q=[~ u=[p=%foo q=[p=[p=1 q=2] q="bc"]]]]
130 > ((cold %foo (just 'a')) [[1 1] "bc"])
131 [p=[p=1 q=1] q=~]
132```
135---
136### `++cook`
138Apply gate
140Parser modifier. Produces a parser that takes a (successful) result of a
141`++rule` `sef` and slams it through `poq`.
143#### Accepts
145`poq` is a gate.
147`sef` is a `++rule`.
149#### Produces
151An `++rule`.
153#### Source
155```
156 ++ cook :: apply gate
157 ~/ %cook
158 |* {poq/gate sef/rule}
159 ~/ %fun
160 |= tub/nail
161 =+ vex=(sef tub)
162 ?~ q.vex
163 vex
164 [p=p.vex q=[~ u=[p=(poq p.u.q.vex) q=q.u.q.vex]]]
165 ::
166```
168#### Examples
170```
171 > ((cook ,@ud (just 'a')) [[1 1] "abc"])
172 [p=[p=1 q=2] q=[~ u=[p=97 q=[p=[p=1 q=2] q="bc"]]]]
174 > ((cook ,@tas (just 'a')) [[1 1] "abc"])
175 [p=[p=1 q=2] q=[~ u=[p=%a q=[p=[p=1 q=2] q="bc"]]]]
177 > ((cook |=(a=@ +(a)) (just 'a')) [[1 1] "abc"])
178 [p=[p=1 q=2] q=[~ u=[p=98 q=[p=[p=1 q=2] q="bc"]]]]
180 > ((cook |=(a=@ `@t`+(a)) (just 'a')) [[1 1] "abc"])
181 [p=[p=1 q=2] q=[~ u=[p='b' q=[p=[p=1 q=2] q="bc"]]]]
182```
185---
186### `++easy`
188Always parse
190Parser generator. Produces a parser that succeeds with given noun `huf`
191without consuming any text.
193#### Accepts
195`huf` is a noun.
197#### Produces
199A `++rule`.
201#### Source
203```
204 ++ easy :: always parse
205 ~/ %easy
206 |* huf=*
207 ~/ %fun
208 |= tub=nail
209 ^- (like ,_huf)
210 [p=p.tub q=[~ u=[p=huf q=tub]]]
211 ::
212```
214#### Examples
216```
217 > ((easy %foo) [[1 1] "abc"])
218 [p=[p=1 q=1] q=[~ [p=%foo q=[p=[p=1 q=1] q="abc"]]]]
220 > ((easy %foo) [[1 1] "bc"])
221 [p=[p=1 q=1] q=[~ [p=%foo q=[p=[p=1 q=1] q="bc"]]]]
223 > ((easy 'a') [[1 1] "bc"])
224 [p=[p=1 q=1] q=[~ [p='a' q=[p=[p=1 q=1] q="bc"]]]]
225```
228---
229### `++full`
231Parse to end
233Parser modifier. Accepts a `++rule` `sef`, and produces a parser that succeeds only
234when the of `tub` is fully consumed using `sef`.
236#### Accepts
238`sef` is a `++rule`.
240#### Produces
242A `++rule`.
244#### Source
246```
247 ++ full :: parse to end
248 |* sef=_rule
249 |= tub=nail
250 =+ vex=(sef tub)
251 ?~(q.vex vex ?:(=(~ q.q.u.q.vex) vex [p=p.vex q=~]))
252 ::
253```
255#### Examples
257```
258 > ((full (just 'a')) [[1 1] "ab"])
259 [p=[p=1 q=2] q=~]
261 > ((full (jest 'ab')) [[1 1] "ab"])
262 [p=[p=1 q=3] q=[~ u=[p='ab' q=[p=[p=1 q=3] q=""]]]]
264 > ((full ;~(plug (just 'a') (just 'b'))) [[1 1] "ab"])
265 [p=[p=1 q=3] q=[~ u=[p=[~~a ~~b] q=[p=[p=1 q=3] q=""]]]]
266```
269---
270### `++funk`
272Add to tape
274Parser modifier: prepend text to `++tape` before applying parser.
276#### Accepts
278`pre` is a `++tape`
280`sef` is a `++rule`
282#### Produces
284A `++rule`.
286#### Source
288```
289 ++ funk :: add to tape first
290 |* {pre/tape sef/rule}
291 |= tub/nail
292 (sef p.tub (weld pre q.tub))
293```
295#### Examples
297```
298 > ((funk "abc prefix-" (jest 'abc')) [[1 1] "to be parsed"])
299 [p=[p=1 q=4] q=[~ [p='abc' q=[p=[p=1 q=4] q=" prefix-to be parsed"]]]]
301 > ((funk "parse" (just 'a')) [[1 4] " me"])
302 [p=[p=1 q=4] q=~]
303```
306---
307### `++here`
309Place-based apply
311Parser modifier. Similar to `++cook` in that it produces a parser that takes a
312(successful) result of `sef` and slams it through `hez`. `hez` accepts a
313`++pint` `a` and a noun `b`, which is what the parser parsed.
315#### Accepts
317`hez` is a gate.
319`sef` is a `++rule`
321#### Produces
323A `++rule`.
325#### Source
327```
328 ++ here :: place-based apply
329 ~/ %here
330 |* {hez/_|=({a/pint b/*} [a b]) sef/rule}
331 ~/ %fun
332 |= tub/nail
333 =+ vex=(sef tub)
334 ?~ q.vex
335 vex
336 [p=p.vex q=[~ u=[p=(hez [p.tub p.q.u.q.vex] p.u.q.vex) q=q.u.q.vex]]]
337 ::
338```
340#### Examples
342```
343 > (scan "abc" (star alf))
344 "abc"
346 > (scan "abc" (here |*(^ +<) (star alf)))
347 [[[p=1 q=1] p=1 q=4] "abc"]
349 > (scan "abc" (star (here |*(^ +<) alf)))
350 ~[[[[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]]
351```
354---
355### `++ifix`
357Infix
359Parser modifier: surround with pair of `++rule`s, the output of which is
360discarded.
362#### Accepts
364`fel` is a pair of `++rule`s.
366`hof` is a `++rule`.
368#### Produces
370A `++rule`.
372#### Source
374```
375 ++ ifix
376 |* {fel/{rule rule} hof/rule}
377 ~! +<
378 ~! +<:-.fel
379 ~! +<:+.fel
380 ;~(pfix -.fel ;~(sfix hof +.fel))
381 ::
382```
384#### Examples
386```
387 > (scan "-40-" (ifix [hep hep] dem))
388 q=40
390 > (scan "4my4" (ifix [dit dit] (star alf)))
391 "my"
392```
395---
396### `++jest`
398Match a cord
400Match and consume a cord.
402#### Accepts
404`daf` is a `@t`.
406#### Produces
408An `++edge`.
410#### Source
412```
413 ++ jest :: match a cord
414 |= daf/@t
415 |= tub/nail
416 =+ fad=daf
417 |- ^- (like @t)
418 ?: =(`@`0 daf)
419 [p=p.tub q=[~ u=[p=fad q=tub]]]
420 ?: |(?=($~ q.tub) !=((end 3 1 daf) i.q.tub))
421 (fail tub)
422 $(p.tub (lust i.q.tub p.tub), q.tub t.q.tub, daf (rsh 3 1 daf))
423 ::
424```
426#### Examples
428```
429 > ((jest 'abc') [[1 1] "abc"])
430 [p=[p=1 q=4] q=[~ [p='abc' q=[p=[p=1 q=4] q=""]]]]
432 > (scan "abc" (jest 'abc'))
433 'abc'
435 > (scan "abc" (jest 'acb'))
436 ! {1 2}
437 ! 'syntax-error'
438 ! exit
440 > ((jest 'john doe') [[1 1] "john smith"])
441 [p=[p=1 q=6] q=~]
443 > ((jest 'john doe') [[1 1] "john doe"])
444 [p=[p=1 q=9] q=[~ [p='john doe' q=[p=[p=1 q=9] q=""]]]]
445```
448---
449### `++just`
451Match a char
453Match and consume a single character.
455#### Accepts
457`daf` is a `++char`
459#### Produces
461A `++rule`.
463#### Source
465```
466 ++ just :: XX redundant, jest
467 ~/ %just :: match a char
468 |= daf/char
469 ~/ %fun
470 |= tub/nail
471 ^- (like char)
472 ?~ q.tub
473 (fail tub)
474 ?. =(daf i.q.tub)
475 (fail tub)
476 (next tub)
477 ::
478```
480#### Examples
482```
483 > ((just 'a') [[1 1] "abc"])
484 [p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
486 > (scan "abc" (just 'a'))
487 ! {1 2}
488 ! 'syntax-error'
489 ! exit
491 > (scan "a" (just 'a'))
493 ~~a
494 > (scan "%" (just '%'))
495 ~~~25.
496```
499---
500### `++knee`
502Recursive parsers
504Used for recursive parsers, which would otherwise be infinite when
505compiled.
507#### Accepts
509`gar` is a noun.
511`sef` is a gate that accepts a `++rule`
513#### Produces
515A `++rule`.
517#### Source
519```
520 ++ knee :: callbacks
521 |* {gar/* sef/_|.(*rule)}
522 |= tub/nail
523 ^- (like _gar)
524 ((sef) tub)
525 ::
526```
528#### Examples
530```
531 > |-(;~(plug prn ;~(pose $ (easy ~))))
532 ! rest-loop
533 ! exit
535 > |-(;~(plug prn ;~(pose (knee *tape |.(^$)) (easy ~))))
536 < 1.obo
537 [ c=c=tub=[p=[p=@ud q=@ud] q=""]
538 b
539 < 1.bes
540 [ c=tub=[p=[p=@ud q=@ud] q=""]
541 b=<1.tnv [tub=[p=[p=@ud q=@ud] q=""] <1.ktu [daf=@tD <414.fvk 101.jzo 1.ypj %164>]>]>
542 a=<1.fvg [tub=[p=[p=@ud q=@ud] q=""] <1.khu [[les=@ mos=@] <414.fvk 101.jzo 1.ypj %164>]>]>
543 v=<414.fvk 101.jzo 1.ypj %164>
544 ]
545 >
546 a
547 ... 450 lines omitted ...
548 ]
549 >
550 > (scan "abcd" |-(;~(plug prn ;~(pose (knee *tape |.(^$)) (easy ~)))))
551 [~~a "bcd"]
552```
555---
556### `++mask`
558Match char
560Parser generator. Matches the next character if it is in a list of
561characters.
563#### Accepts
565`bud` is a list of `++char`
567#### Produces
569A `++rule`.
571#### Source
573```
574 ++ mask :: match char in set
575 ~/ %mask
576 |= bud/(list char)
577 ~/ %fun
578 |= tub/nail
579 ^- (like char)
580 ?~ q.tub
581 (fail tub)
582 ?. (lien bud |=(a/char =(i.q.tub a)))
583 (fail tub)
584 (next tub)
585 ::
586```
588#### Examples
590```
591 > (scan "a" (mask "cba"))
592 ~~a
594 > ((mask "abc") [[1 1] "abc"])
595 [p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
597 > ((mask "abc") [[1 1] "bbc"])
598 [p=[p=1 q=2] q=[~ [p=~~b q=[p=[p=1 q=2] q="bc"]]]]
600 > ((mask "abc") [[1 1] "dbc"])
601 [p=[p=1 q=1] q=~]
602```
604---
605### `++more`
607Parse list with delimiter
609Parser modifier: Parse a list of matches using a delimiter `++rule`.
611#### Accepts
613`bus` is a `++rule`.
615`fel` is a `++rule`.
617#### Produces
619A `++rule`.
621#### Source
623```
624 ++ more
625 |* {bus/rule fel/rule}
626 ;~(pose (most bus fel) (easy ~))
627 ::
628```
630#### Examples
632```
633 > (scan "" (more ace dem))
634 ~
636 > (scan "40 20" (more ace dem))
637 [q=40 ~[q=20]]
639 > (scan "40 20 60 1 5" (more ace dem))
640 [q=40 ~[q=20 q=60 q=1 q=5]]
641```
644---
645### `++most`
647Parse list of at least one match
649Parser modifier: parse a `++list` of at least one match using a delimiter `++rule`.
651#### Accepts
653`bus` is a `++rule`.
655`fel` is a `++rule`.
657#### Produces
659A `++rule`.
661#### Source
663```
664 ++ most
665 |* {bus/rule fel/rule}
666 ;~(plug fel (star ;~(pfix bus fel)))
667 ::
668```
670#### Examples
672```
673 > (scan "40 20" (most ace dem))
674 [q=40 ~[q=20]]
676 > (scan "40 20 60 1 5" (most ace dem))
677 [q=40 ~[q=20 q=60 q=1 q=5]]
679 > (scan "" (most ace dem))
680 ! {1 1}
681 ! exit
682```
685---
686### `++next`
688Consume char
690Consume any character, producing it as a result.
692#### Accepts
694`tub` is a `++nail`
696#### Produces
698An `++edge`.
700#### Source
702```
703 ++ next :: consume a char
704 |= tub/nail
705 ^- (like char)
706 ?~ q.tub
707 (fail tub)
708 =+ zac=(lust i.q.tub p.tub)
709 [zac [~ i.q.tub [zac t.q.tub]]]
710 ::
711```
713#### Examples
715```
716 > (next [[1 1] "ebc"])
717 [p=[p=1 q=2] q=[~ [p=~~e q=[p=[p=1 q=2] q="bc"]]]]
719 > (next [[1 1] "john jumps jones"])
720 [p=[p=1 q=2] q=[~ [p=~~j q=[p=[p=1 q=2] q="ohn jumps jones"]]]]
721```
724---
726### `++plus`
728List of at least one match.
730Parser modifier: parse `++list` of at least one match.
732#### Accepts
734`fel` is a `++rule`.
736#### Produces
738A `++rule`.
740#### Source
742```
743 ++ plus |*(fel/rule ;~(plug fel (star fel)))
744```
746#### Examples
748```
749 > (scan ">>>>" (cook lent (plus gar)))
750 4
752 > (scan "- - " (plus ;~(pose ace hep)))
753 [~~- " - "]
755 > `tape`(scan "- - " (plus ;~(pose ace hep)))
756 "- - "
758 > `(pole ,@t)`(scan "- - " (plus ;~(pose ace hep)))
759 ['-' [' ' [' ' ['-' [' ' ~]]]]]
760```
763---
764### `++sear`
766Conditional `++cook`
768Conditional `++cook`. Slams the result through a gate that produces
769a unit; if that unit is empty, fail.
771#### Accepts
773`tub` is a `++nail`.
775#### Produces
777A `++rule`.
779#### Source
781```
782 ++ sear :: conditional cook
783 |* {pyq/$-(* (unit)) sef/rule}
784 |= tub/nail
785 =+ vex=(sef tub)
786 ?~ q.vex
787 vex
788 =+ gey=(pyq p.u.q.vex)
789 ?~ gey
790 [p=p.vex q=~]
791 [p=p.vex q=[~ u=[p=u.gey q=q.u.q.vex]]]
792 ::
793```
795#### Examples
797```
798 > ((sear |=(a/* ?@(a (some a) ~)) (just `a`)) [[1 1] "abc"])
799 [p=[p=1 q=2] q=[~ u=[p=97 q=[p=[p=1 q=2] q="bc"]]]]
801 > ((sear |=(* ~) (just 'a')) [[1 1] "abc"])
802 [p=[p=1 q=2] q=~]
803```
806---
807### `++shim`
809Char in range
811Match characters (`++char`) within a range.
813#### Accepts
815`les` is an atom.
817`mos` is an atom.
819#### Produces
821A `++rule`.
823#### Source
825```
826 ++ shim :: match char in range
827 ~/ %shim
828 |= {les/@ mos/@}
829 ~/ %fun
830 |= tub/nail
831 ^- (like char)
832 ?~ q.tub
833 (fail tub)
834 ?. ?&((gte i.q.tub les) (lte i.q.tub mos))
835 (fail tub)
836 (next tub)
837 ::
838```
840#### Examples
842```
843 > ((shim 'a' 'z') [[1 1] "abc"])
844 [p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
846 > ((shim 'a' 'Z') [[1 1] "abc"])
847 [p=[p=1 q=1] q=~]
849 > ((shim 'a' 'Z') [[1 1] "Abc"])
850 [p=[p=1 q=2] q=[~ [p=~~~41. q=[p=[p=1 q=2] q="bc"]]]]
851```
854---
855### `++slug`
857Use gate to parse delimited list
859Parser modifier: By composing with a gate, parse a delimited `++list` of
860matches.
862#### Accepts
864`bus` is a `++rule`.
866`fel` is a `++rule`.
868#### Produces
870A `++rule`.
872#### Source
874```
875 ++ slug
876 |* raq/_|*({a/* b/*} [a b])
877 |* {bus/rule fel/rule}
878 ;~((comp raq) fel (stir +<+.raq raq ;~(pfix bus fel)))
879 ::
880```
882#### Examples
884```
885 > (scan "20+5+110" ((slug add) lus dem))
886 135
888 > `@t`(scan "a b c" ((slug |=(a/[@ @t] (cat 3 a))) ace alp))
889 'abc'
890```
893---
894### `++stag`
896Add label
898Add a label to an edge parsed by a rule.
900#### Accepts
902`gob` is a noun.
904`sef` is a rule.
906#### Produces
908A `++rule`.
910#### Source
912```
913 ++ stag :: add a label
914 ~/ %stag
915 |* {gob/* sef/rule}
916 ~/ %fun
917 |= tub/nail
918 =+ vex=(sef tub)
919 ?~ q.vex
920 vex
921 [p=p.vex q=[~ u=[p=[gob p.u.q.vex] q=q.u.q.vex]]]
922 ::
923```
925#### Examples
927```
928 > ((stag %foo (just 'a')) [[1 1] "abc"])
929 [p=[p=1 q=2] q=[~ u=[p=[%foo ~~a] q=[p=[p=1 q=2] q="bc"]]]]
931 > ((stag "xyz" (jest 'abc')) [[1 1] "abc"])
932 [p=[p=1 q=4] q=[~ u=[p=["xyz" 'abc'] q=[p=[p=1 q=4] q=""]]]]
934 > ((stag 10.000 (shim 0 100)) [[1 1] "abc"])
935 [p=[p=1 q=2] q=[~ u=[p=[10.000 ~~a] q=[p=[p=1 q=2] q="bc"]]]]
936```
939---
940### `++star`
942List of matches
944Parser modifier: parse `++list` of matches.
946#### Accepts
948`fel` is a `++rule`.
950#### Produces
952```
953 ++ star :: 0 or more times
954 |* fel/rule
955 (stir `(list _(wonk *fel))`~ |*({a/* b/*} [a b]) fel)
956```
958#### Examples
960```
961 > (scan "aaaaa" (just 'a'))
962 ! {1 2}
963 ! 'syntax-error'
964 ! exit
966 > (scan "aaaaa" (star (just 'a')))
967 "aaaaa"
969 > (scan "abcdef" (star (just 'a')))
970 ! {1 2}
971 ! 'syntax-error'
972 ! exit
974 > (scan "abcabc" (star (jest 'abc')))
975 <|abc abc|>
977 > (scan "john smith" (star (shim 0 200)))
978 "john smith"
979```
982---
983### `++stet`
985Add faces
987Add faces `[p q]` to range-parser pairs in a list.
989#### Accepts
991`leh` is a list of range-parsers.
993#### Produces
997#### Source
999```
1000 ++ stet
1001 |* leh/(list {?(@ {@ @}) rule})
1002 |-
1003 ?~ leh
1005 [i=[p=-.i.leh q=+.i.leh] t=$(leh t.leh)]
1006 ::
1007```
1009#### Examples
1011```
1012 > (stet (limo [[5 (just 'a')] [1 (jest 'abc')] [[1 1] (shim 0 200)]
1013 [[1 10] (cold %foo (just 'a'))]~]))
1014 ~[
1015 [p=5 q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
1016 [p=1 q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
1017 [p=[1 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
1018 [p=[1 10] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
1020 > [[[1 1] (just 'a')] [[2 1] (shim 0 200)] ~]
1021 [ [[1 1] <1.tnv [tub=[p=[p=@ud q=@ud] q=""] <1.ktu [daf=@tD <414.fvk 101.jzo 1.ypj %164>]>]>]
1022 [[2 1] <1.fvg [tub=[p=[p=@ud q=@ud] q=""] <1.khu [[les=@ mos=@] <414.fvk 101.jzo 1.ypj %164>]>]>]
1025 > (stet (limo [[[1 1] (just 'a')] [[2 1] (shim 0 200)] ~]))
1026 ~[
1027 [p=[1 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
1028 [p=[2 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
1030```
1033---
1034### `++stew`
1036Switch by first
1038```
1039 ++ stew :: switch by first char
1040 ~/ %stew
1041 |* leh/(list {p/?(@ {@ @}) q/rule}) :: char+range keys
1042 =+ ^= wor :: range complete lth
1043 |= {ort/?(@ {@ @}) wan/?(@ {@ @})}
1044 ?@ ort
1045 ?@(wan (lth ort wan) (lth ort -.wan))
1046 ?@(wan (lth +.ort wan) (lth +.ort -.wan))
1047 =+ ^= hel :: build parser map
1048 =+ hel=`(tree _?>(?=(^ leh) i.leh))`~
1049 |- ^+ hel
1050 ?~ leh
1052 =+ yal=$(leh t.leh)
1053 |- ^+ hel
1054 ?~ yal
1055 [i.leh ~ ~]
1056 ?: (wor p.i.leh p.n.yal)
1057 =+ nuc=$(yal l.yal)
1058 ?> ?=(^ nuc)
1059 ?: (vor p.n.yal p.n.nuc)
1060 [n.yal nuc r.yal]
1061 [n.nuc l.nuc [n.yal r.nuc r.yal]]
1062 =+ nuc=$(yal r.yal)
1063 ?> ?=(^ nuc)
1064 ?: (vor p.n.yal p.n.nuc)
1065 [n.yal l.yal nuc]
1066 [n.nuc [n.yal l.yal l.nuc] r.nuc]
1067 ~% %fun ..^$ ~
1068 |= tub/nail
1069 ?~ q.tub
1070 (fail tub)
1071 |-
1072 ?~ hel
1073 (fail tub)
1074 ?: ?@ p.n.hel
1075 =(p.n.hel i.q.tub)
1076 ?&((gte i.q.tub -.p.n.hel) (lte i.q.tub +.p.n.hel))
1077 :: (q.n.hel [(lust i.q.tub p.tub) t.q.tub])
1078 (q.n.hel tub)
1079 ?: (wor i.q.tub p.n.hel)
1080 $(hel l.hel)
1081 $(hel r.hel)
1082 ::
1083```
1086Parser generator. From an associative `++list` of characters or character
1087ranges to `++rule`s, construct a `++map`, and parse `++tape`s only
1088with `++rules` associated with a range that the `++tape`'s first character falls in.
1092---
1093### `++stir`
1095Parse repeatedly
1097Parse with `++rule` as many times as possible, and fold over results with a
1098binary gate.
1100#### Accepts
1102`rud` is a noun.
1104`raq` is a gate that takes two nouns and produces a cell.
1106`fel` is a rule.
1108#### Produces
1110A rule.
1112#### Source
1114```
1115 ++ stir
1116 ~/ %stir
1117 |* {rud/* raq/_=>(~ |*({a/* b/*} [a b])) fel/rule}
1118 ~/ %fun
1119 |= tub/nail
1120 ^- (like _rud)
1121 =+ vex=(fel tub)
1122 ?~ q.vex
1123 [p.vex [~ rud tub]]
1124 =+ wag=$(tub q.u.q.vex)
1125 ?> ?=(^ q.wag)
1126 [(last p.vex p.wag) [~ (raq p.u.q.vex p.u.q.wag) q.u.q.wag]]
1127```
1129#### Examples
1131```
1132 > (scan "abc" (stir *@ add prn))
1133 294
1135 > (roll "abc" add)
1136 b=294
1137```
1140---
1141### `++stun`
1143Parse several times
1145Parse bounded number of times.
1147#### Accepts
1149`[les=@ mos=@]` is a cell of atoms indicating the bounds.
1151`fel` is a `++rule`.
1153#### Produces
1155A `++rule`.
1157#### Source
1159```
1160 ++ stun :: parse several times
1161 |* {lig/{@ @} fel/rule}
1162 |= tub/nail
1163 ^- (like (list _(wonk (fel))))
1164 ?: =(0 +.lig)
1165 [p.tub [~ ~ tub]]
1166 =+ vex=(fel tub)
1167 ?~ q.vex
1168 ?: =(0 -.lig)
1169 [p.vex [~ ~ tub]]
1170 vex
1171 =+ ^= wag %= $
1172 -.lig ?:(=(0 -.lig) 0 (dec -.lig))
1173 +.lig ?:(=(0 +.lig) 0 (dec +.lig))
1174 tub q.u.q.vex
1175 ==
1176 ?~ q.wag
1177 wag
1178 [p.wag [~ [p.u.q.vex p.u.q.wag] q.u.q.wag]]
1179```
1181#### Examples
1183```
1184 > ((stun [5 10] prn) [1 1] "aquickbrownfoxran")
1185 [p=[p=1 q=11] q=[~ [p="aquickbrow" q=[p=[p=1 q=11] q="nfoxran"]]]]
1187 > ((stun [5 10] prn) [1 1] "aquickbro")
1188 [p=[p=1 q=10] q=[~ [p="aquickbro" q=[p=[p=1 q=10] q=""]]]]
1190 > ((stun [5 10] prn) [1 1] "aqui")
1191 [p=[p=1 q=5] q=~]
1192```
1194---