on 4fdc19d help sign in
1380 lines 21 kB history raw
1+++
2title = "4f: Parsing (Rule-Builders)"
3weight = 33
4template = "doc.html"
5+++
7## `++bass`
9Parser modifier: LSB
10ordered `list` as atom of a `base`.
12#### Accepts
14`wuc` is an atom.
16`tyd` is a `rule`.
18#### Produces
20A `rule`.
22#### Source
24```hoon
25++ bass
26 |* [wuc=@ tyd=rule]
27 %+ cook
28 |= waq=(list @)
29 %+ roll
30 waq
31 =|([p=@ q=@] |.((add p (mul wuc q))))
32 tyd
33```
35#### Examples
37```
38> (scan "123" (bass 10 (star dit)))
39q=123
40> (scan "123" (bass 8 (star dit)))
41q=83
42> `@ub`(scan "123" (bass 8 (star dit)))
430b101.0011
44```
46---
48## `++boss`
50Parser modifier: LSB
52Ordered `list` as atom of a `base`.
54#### Accepts
56`wuc` is an atom.
58`tyd` is a `rule`.
60#### Produces
62A `rule`.
64#### Source
66```hoon
67++ boss
68 |* [wuc=@ tyd=rule]
69 %+ cook
70 |= waq=(list @)
71 %+ reel
72 waq
73 =|([p=@ q=@] |.((add p (mul wuc q))))
74 tyd
75```
77#### Examples
79```
80> (scan "123" (boss 10 (star dit)))
81321
83> `@t`(scan "bam" (boss 256 (star alp)))
84'bam'
86> `@ux`(scan "bam" (boss 256 (star alp)))
870x6d.6162
88```
90---
92## `++cold`
94Replace with constant
96Parser modifier. Accepts a `rule` `sef` and produces a parser that produces a
97constant `cus`, assuming `sef` is successful.
99#### Accepts
101`cus` is a constant noun.
103`sef` is a `rule`.
105#### Produces
107An `edge`.
109#### Source
111```hoon
112++ cold
113 ~/ %cold
114 |* [cus=* sef=rule]
115 ~/ %fun
116 |= tub=nail
117 =+ vex=(sef tub)
118 ?~ q.vex
119 vex
120 [p=p.vex q=[~ u=[p=cus q=q.u.q.vex]]]
121```
123#### Examples
125```
126> ((cold %foo (just 'a')) [[1 1] "abc"])
127[p=[p=1 q=2] q=[~ u=[p=%foo q=[p=[p=1 q=2] q="bc"]]]]
129> ((cold %foo (just 'a')) [[1 1] "bc"])
130[p=[p=1 q=1] q=~]
131```
133---
135## `++cook`
137Apply gate
139Parser modifier. Produces a parser that takes a (successful) result of a
140`rule` `sef` and slams it through `poq`.
142#### Accepts
144`poq` is a gate.
146`sef` is a `rule`.
148#### Produces
150An `rule`.
152#### Source
154```hoon
155++ cook
156 ~/ %cook
157 |* [poq=gate sef=rule]
158 ~/ %fun
159 |= tub=nail
160 =+ vex=(sef tub)
161 ?~ q.vex
162 vex
163 [p=p.vex q=[~ u=[p=(poq p.u.q.vex) q=q.u.q.vex]]]
164```
166#### Examples
168```
169> ((cook ,@ud (just 'a')) [[1 1] "abc"])
170[p=[p=1 q=2] q=[~ u=[p=97 q=[p=[p=1 q=2] q="bc"]]]]
172> ((cook ,@tas (just 'a')) [[1 1] "abc"])
173[p=[p=1 q=2] q=[~ u=[p=%a q=[p=[p=1 q=2] q="bc"]]]]
175> ((cook |=(a=@ +(a)) (just 'a')) [[1 1] "abc"])
176[p=[p=1 q=2] q=[~ u=[p=98 q=[p=[p=1 q=2] q="bc"]]]]
178> ((cook |=(a=@ `@t`+(a)) (just 'a')) [[1 1] "abc"])
179[p=[p=1 q=2] q=[~ u=[p='b' q=[p=[p=1 q=2] q="bc"]]]]
180```
182---
184## `++easy`
186Always parse
188Parser generator. Produces a parser that succeeds with given noun `huf`
189without consuming any text.
191#### Accepts
193`huf` is a noun.
195#### Produces
197A `rule`.
199#### Source
201```hoon
202++ easy
203 ~/ %easy
204 |* huf=*
205 ~/ %fun
206 |= tub=nail
207 ^- (like _huf)
208 [p=p.tub q=[~ u=[p=huf q=tub]]]
209```
211#### Examples
213```
214> ((easy %foo) [[1 1] "abc"])
215[p=[p=1 q=1] q=[~ [p=%foo q=[p=[p=1 q=1] q="abc"]]]]
217> ((easy %foo) [[1 1] "bc"])
218[p=[p=1 q=1] q=[~ [p=%foo q=[p=[p=1 q=1] q="bc"]]]]
220> ((easy 'a') [[1 1] "bc"])
221[p=[p=1 q=1] q=[~ [p='a' q=[p=[p=1 q=1] q="bc"]]]]
222```
224---
226## `++fuss`
228Has A or B?
230If string `sic` is parsed: `%.y`. If string `non` is parsed: `%.n`. Otherwise, fail.
232#### Accepts
234`sic` is a `@t`.
236`non` is a `@t`.
238#### Produces
240A `rule`.
242#### Source
244```hoon
245++ fuss
246 |= [sic=@t non=@t]
247 ;~(pose (cold %& (jest sic)) (cold %| (jest non)))
248```
250#### Examples
252```
253> (rash 'foo' (fuss 'foo' 'bar'))
254%.y
256> (rash 'bar' (fuss 'foo' 'bar'))
257%.n
259> (rash 'baz' (fuss 'foo' 'bar'))
260{1 3}
261syntax error
262```
264---
266## `++full`
268Parse to end
270Parser modifier. Accepts a `rule` `sef`, and produces a parser that succeeds
271only when the `tape` of `tub` is fully consumed using `sef`.
273#### Accepts
275`sef` is a `rule`.
277#### Produces
279A `rule`.
281#### Source
283```hoon
284++ full
285 |* sef=rule
286 |= tub=nail
287 =+ vex=(sef tub)
288 ?~(q.vex vex ?:(=(~ q.q.u.q.vex) vex [p=p.vex q=~]))
289```
291#### Examples
293```
294> ((full (just 'a')) [[1 1] "ab"])
295[p=[p=1 q=2] q=~]
297> ((full (jest 'ab')) [[1 1] "ab"])
298[p=[p=1 q=3] q=[~ u=[p='ab' q=[p=[p=1 q=3] q=""]]]]
300> ((full ;~(plug (just 'a') (just 'b'))) [[1 1] "ab"])
301[p=[p=1 q=3] q=[~ u=[p=['a' 'b'] q=[p=[p=1 q=3] q=""]]]]
302```
304---
306## `++funk`
308Add to tape
310Parser modifier: prepend text to `tape` before applying parser.
312#### Accepts
314`pre` is a `tape`
316`sef` is a `rule`
318#### Produces
320A `rule`.
322#### Source
324```hoon
325++ funk
326 |* [pre=tape sef=rule]
327 |= tub=nail
328 (sef p.tub (weld pre q.tub))
329```
331#### Examples
333```
334> ((funk "abc prefix-" (jest 'abc')) [[1 1] "to be parsed"])
335[p=[p=1 q=4] q=[~ [p='abc' q=[p=[p=1 q=4] q=" prefix-to be parsed"]]]]
337> ((funk "parse" (just 'a')) [[1 4] " me"])
338[p=[p=1 q=4] q=~]
339```
341---
343## `++here`
345Place-based apply
347Parser modifier. Similar to `++cook` in that it produces a parser that takes a
348(successful) result of `sef` and slams it through `hez`. `hez` accepts a
349`pint` `a` and a noun `b`, which is what the parser parsed.
351#### Accepts
353`hez` is a gate.
355`sef` is a `rule`
357#### Produces
359A `rule`.
361#### Source
363```hoon
364++ here
365 ~/ %here
366 =+ [hez=|=([a=pint b=*] [a b]) sef=*rule]
367 |@
368 ++ $
369 ~/ %fun
370 |= tub=nail
371 =+ vex=(sef tub)
372 ?~ q.vex
373 vex
374 [p=p.vex q=[~ u=[p=(hez [p.tub p.q.u.q.vex] p.u.q.vex) q=q.u.q.vex]]]
375 --
376```
378#### Examples
380```
381> (scan "abc" (star alf))
382"abc"
384> (scan "abc" (here |*(^ +<) (star alf)))
385[[[p=1 q=1] p=1 q=4] "abc"]
387> (scan "abc" (star (here |*(^ +<) alf)))
388~[[[[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]]
389```
391## `++inde`
393Indentation block
395Apply `rule` to indented block starting at current column number, omitting the
396leading whitespace.
398#### Accepts
400`sef` is a `rule`.
402#### Produces
404A `rule`.
406#### Source
408```hoon
409++ inde |* sef=rule
410 |= nail ^+ (sef)
411 =+ [har tap]=[p q]:+<
412 =+ lev=(fil 3 (dec q.har) ' ')
413 =+ eol=(just `@t`10)
414 =+ =- roq=((star ;~(pose prn ;~(sfix eol (jest lev)) -)) har tap)
415 ;~(simu ;~(plug eol eol) eol)
416 ?~ q.roq roq
417 =+ vex=(sef har(q 1) p.u.q.roq)
418 =+ fur=p.vex(q (add (dec q.har) q.p.vex))
419 ?~ q.vex vex(p fur)
420 =- vex(p fur, u.q -)
421 :+ &3.vex
422 &4.vex(q.p (add (dec q.har) q.p.&4.vex))
423 =+ res=|4.vex
424 |- ?~ res |4.roq
425 ?. =(10 -.res) [-.res $(res +.res)]
426 (welp [`@t`10 (trip lev)] $(res +.res))
427```
429#### Examples
431```
432> `tape`(scan " foo\0a bar" ;~(pfix ace ace ace (inde (star ;~(pose prn (just '\0a'))))))
433"foo\0abar"
434```
436#### Discussion
438Note the amount of indentation whitespace to be stripped from the beginning of
439each line is determined by the value of `q` (the column) in the `hair` when
440`++inde` is first called. This means something like the `pfix` expression in the
441example above is necessary to set the level of indentation. Additionally, the
442`rule` given to `++inde` must consume the whole line including the line ending.
444---
446## `++ifix`
448Infix
450Parser modifier: surround with pair of `rule`s, the output of which is
451discarded.
453#### Accepts
455`fel` is a pair of `rule`s.
457`hof` is a `rule`.
459#### Produces
461A `rule`.
463#### Source
465```hoon
466++ ifix
467 |* [fel=[rule rule] hof=rule]
468 ~! +<
469 ~! +<:-.fel
470 ~! +<:+.fel
471 ;~(pfix -.fel ;~(sfix hof +.fel))
472```
474#### Examples
476```
477> (scan "-40-" (ifix [hep hep] dem))
47840
480> (scan "4my4" (ifix [dit dit] (star alf)))
481"my"
482```
484---
486## `++jest`
488Match a cord
490Match and consume a cord.
492#### Accepts
494`daf` is a `@t`.
496#### Produces
498A `rule`.
500#### Source
502```hoon
503++ jest
504 |= daf=@t
505 |= tub=nail
506 =+ fad=daf
507 |- ^- (like @t)
508 ?: =(`@`0 daf)
509 [p=p.tub q=[~ u=[p=fad q=tub]]]
510 ?: |(?=(~ q.tub) !=((end 3 daf) i.q.tub))
511 (fail tub)
512 $(p.tub (lust i.q.tub p.tub), q.tub t.q.tub, daf (rsh 3 daf))
513```
515#### Examples
517```
518> ((jest 'abc') [[1 1] "abc"])
519[p=[p=1 q=4] q=[~ [p='abc' q=[p=[p=1 q=4] q=""]]]]
521> (scan "abc" (jest 'abc'))
522'abc'
524> (scan "abc" (jest 'acb'))
525! {1 2}
526! 'syntax-error'
527! exit
529> ((jest 'john doe') [[1 1] "john smith"])
530[p=[p=1 q=6] q=~]
532> ((jest 'john doe') [[1 1] "john doe"])
533[p=[p=1 q=9] q=[~ [p='john doe' q=[p=[p=1 q=9] q=""]]]]
534```
536---
538## `++just`
540Match a char
542Match and consume a single character.
544#### Accepts
546`daf` is a `char`
548#### Produces
550A `rule`.
552#### Source
554```hoon
555++ just
556 ~/ %just
557 |= daf=char
558 ~/ %fun
559 |= tub=nail
560 ^- (like char)
561 ?~ q.tub
562 (fail tub)
563 ?. =(daf i.q.tub)
564 (fail tub)
565 (next tub)
566```
568#### Examples
570```
571> ((just 'a') [[1 1] "abc"])
572[p=[p=1 q=2] q=[~ [p='a' q=[p=[p=1 q=2] q="bc"]]]]
574> (scan "abc" (just 'a'))
575! {1 2}
576! 'syntax-error'
577! exit
579> (scan "a" (just 'a'))
580'a'
582> (scan "%" (just '%'))
583'%'
584```
586---
588## `++knee`
590Recursive parsers
592Used for recursive parsers, which would otherwise be infinite when
593compiled.
595#### Accepts
597`gar` is a noun.
599`sef` is a gate that accepts a `rule`
601#### Produces
603A `rule`.
605#### Source
607```hoon
608++ knee
609 =| [gar=* sef=_|.(*rule)]
610 |@ ++ $
611 |= tub=nail
612 ^- (like _gar)
613 ((sef) tub)
614 --
615```
617#### Examples
619```
620> |-(;~(plug prn ;~(pose $ (easy ~))))
621! rest-loop
622! exit
624> |-(;~(plug prn ;~(pose (knee *tape |.(^$)) (easy ~))))
625< 1.obo
626 [ c=c=tub=[p=[p=@ud q=@ud] q=""]
627 b
628 < 1.bes
629 [ c=tub=[p=[p=@ud q=@ud] q=""]
630 b=<1.tnv [tub=[p=[p=@ud q=@ud] q=""] <1.ktu [daf=@tD <414.fvk 101.jzo 1.ypj %164>]>]>
631 a=<1.fvg [tub=[p=[p=@ud q=@ud] q=""] <1.khu [[les=@ mos=@] <414.fvk 101.jzo 1.ypj %164>]>]>
632 v=<414.fvk 101.jzo 1.ypj %164>
633 ]
634 >
635 a
636 ... 450 lines omitted ...
637 ]
640> (scan "abcd" |-(;~(plug prn ;~(pose (knee *tape |.(^$)) (easy ~)))))
641['a' "bcd"]
642```
644---
646## `++mask`
648Match char
650Parser generator. Matches the next character if it is in a list of characters.
652#### Accepts
654`bud` is a list of `char`
656#### Produces
658A `rule`.
660#### Source
662```hoon
663++ mask
664 ~/ %mask
665 |= bud=(list char)
666 ~/ %fun
667 |= tub=nail
668 ^- (like char)
669 ?~ q.tub
670 (fail tub)
671 ?. (lien bud |=(a=char =(i.q.tub a)))
672 (fail tub)
673 (next tub)
674```
676#### Examples
678```
679> (scan "a" (mask "cba"))
680'a'
682> ((mask "abc") [[1 1] "abc"])
683[p=[p=1 q=2] q=[~ [p='a' q=[p=[p=1 q=2] q="bc"]]]]
685> ((mask "abc") [[1 1] "bbc"])
686[p=[p=1 q=2] q=[~ [p='b' q=[p=[p=1 q=2] q="bc"]]]]
688> ((mask "abc") [[1 1] "dbc"])
689[p=[p=1 q=1] q=~]
690```
692---
694## `++more`
696Parse list with delimiter
698Parser modifier: Parse a list of matches using a delimiter `rule`.
700#### Accepts
702`bus` is a `rule`.
704`fel` is a `rule`.
706#### Produces
708A `rule`.
710#### Source
712```hoon
713++ more
714 |* [bus=rule fel=rule]
715 ;~(pose (most bus fel) (easy ~))
716```
718#### Examples
720```
721> (scan "" (more ace dem))
724> (scan "40 20" (more ace dem))
725[40 [i=20 t=~]]
727> (scan "40 20 60 1 5" (more ace dem))
728[40 [i=20 t=~[60 1 5]]]
729```
731---
733## `++most`
735Parse list of at least one match
737Parser modifier: parse a `list` of at least one match using a delimiter `rule`.
739#### Accepts
741`bus` is a `rule`.
743`fel` is a `rule`.
745#### Produces
747A `rule`.
749#### Source
751```hoon
752++ most
753 |* [bus=rule fel=rule]
754 ;~(plug fel (star ;~(pfix bus fel)))
755```
757#### Examples
759```
760> (scan "40 20" (most ace dem))
761[40 [i=20 t=~]]
763> (scan "40 20 60 1 5" (most ace dem))
764[40 [i=20 t=~[60 1 5]]]
766> (scan "" (most ace dem))
767! {1 1}
768! exit
769```
771---
773## `++next`
775Consume char
777Consume any character, producing it as a result.
779#### Accepts
781`tub` is a `nail`
783#### Produces
785An `edge`.
787#### Source
789```hoon
790++ next
791 |= tub=nail
792 ^- (like char)
793 ?~ q.tub
794 (fail tub)
795 =+ zac=(lust i.q.tub p.tub)
796 [zac [~ i.q.tub [zac t.q.tub]]]
797```
799#### Examples
801```
802> (next [[1 1] "ebc"])
803[p=[p=1 q=2] q=[~ [p='e' q=[p=[p=1 q=2] q="bc"]]]]
805> (next [[1 1] "john jumps jones"])
806[p=[p=1 q=2] q=[~ [p='j' q=[p=[p=1 q=2] q="ohn jumps jones"]]]]
807```
809---
811## `++perk`
813Parse cube fork
815Given `a`, a list of `@tas`, match any one in the list and produce it. Note the
816list should not be a `list` type, but just a null-terminated cell like `~[%foo %bar %baz]`. The type produced will be a union of the items in the given list,
817so you can use a `?-` expression on the output.
819#### Accepts
821`a` is a `(pole @tas)`.
823#### Produces
825A `rule`.
827#### Source
829```hoon
830++ perk
831 |* a=(pole @tas)
832 ?~ a fail
833 ;~ pose
834 (cold -.a (jest -.a))
835 $(a +.a)
836 ==
837```
839#### Examples
841```
842> (scan "foo" (perk ~[%foo %bar]))
843%foo
845> (scan "bar" (perk ~[%foo %bar]))
846%bar
848> (scan "baz" (perk ~[%foo %bar]))
849{1 3}
850syntax error
851```
853---
855## `++plus`
857List of at least one match.
859Parser modifier: parse `list` of at least one match.
861#### Accepts
863`fel` is a `rule`.
865#### Produces
867A `rule`.
869#### Source
871```hoon
872++ plus |*(fel=rule ;~(plug fel (star fel))) ::
873```
875#### Examples
877```
878> (scan ">>>>" (cook lent (plus gar)))
881> (scan "- - " (plus ;~(pose ace hep)))
882['-' [i=' ' t=~[' ' '-' ' ']]]
884> `tape`(scan "- - " (plus ;~(pose ace hep)))
885"- - "
887> `(pole ,@t)`(scan "- - " (plus ;~(pose ace hep)))
888['-' [' ' [' ' ['-' [' ' ~]]]]]
889```
891---
893## `++punt`
895Unitized parse
897Either successfully apply `rule` `a` and produce a `unit` of the result, or produce `~`.
899#### Accepts
901`a` is a `rule`.
903#### Produces
905A `rule`.
907#### Source
909```hoon
910++ punt |*([a=rule] ;~(pose (stag ~ a) (easy ~)))
911```
913#### Example
915```
916> ((punt (jest 'foo')) 1^1 "foo")
917[p=[p=1 q=4] q=[~ u=[p=[~ 'foo'] q=[p=[p=1 q=4] q=~]]]]
919> ((punt (jest 'foo')) 1^1 "bar")
920[p=[p=1 q=1] q=[~ [p=~ q=[p=[p=1 q=1] q="bar"]]]]
921```
923---
925## `++sear`
927Conditional `cook`
929Conditional `cook`. Slams the result through a gate that produces
930a unit; if that unit is empty, fail.
932#### Accepts
934`pyq` is a gate that produces a `unit`.
936`sef` is a `rule`.
938#### Produces
940A `rule`.
942#### Source
944```hoon
945++ sear
946 |* [pyq=$-(* (unit)) sef=rule]
947 |= tub=nail
948 =+ vex=(sef tub)
949 ?~ q.vex
950 vex
951 =+ gey=(pyq p.u.q.vex)
952 ?~ gey
953 [p=p.vex q=~]
954 [p=p.vex q=[~ u=[p=u.gey q=q.u.q.vex]]]
955```
957#### Examples
959```
960> ((sear |=(a=* ?@(a (some a) ~)) (just 'a')) [[1 1] "abc"])
961[p=[p=1 q=2] q=[~ u=[p=97 q=[p=[p=1 q=2] q="bc"]]]]
963> ((sear |=(* ~) (just 'a')) [[1 1] "abc"])
964[p=[p=1 q=2] q=~]
965```
967---
969## `++shim`
971Char in range
973Match characters (`char`) within a range.
975#### Accepts
977`les` is an atom.
979`mos` is an atom.
981#### Produces
983A `rule`.
985#### Source
987```hoon
988++ shim
989 ~/ %shim
990 |= [les=@ mos=@]
991 ~/ %fun
992 |= tub=nail
993 ^- (like char)
994 ?~ q.tub
995 (fail tub)
996 ?. ?&((gte i.q.tub les) (lte i.q.tub mos))
997 (fail tub)
998 (next tub)
999```
1001#### Examples
1003```
1004> `tape`(rash 'abc' (plus (shim 'a' 'z')))
1005"abc"
1007> `tape`(rash 'ABC' (plus (shim 'a' 'z')))
1008{1 1}
1009syntax error
1010```
1012---
1014## `++slug`
1016Use gate to parse delimited list
1018Parser modifier: By composing with a gate, parse a delimited `list` of
1019matches.
1021#### Accepts
1023`raq` is a binary gate.
1025`bus` is a `rule`.
1027`fel` is a `rule`.
1029#### Produces
1031A `rule`.
1033#### Source
1035```hoon
1036++ slug
1037 |* raq=_=>(~ |*([a=* b=*] [a b]))
1038 |* [bus=rule fel=rule]
1039 ;~((comp raq) fel (stir +<+.raq raq ;~(pfix bus fel)))
1040```
1042#### Examples
1044```
1045> (scan "20+5+110" ((slug add) lus dem))
1046135
1048> `@t`(scan "a b c" ((slug |=(a=[@t @t] (cat 3 a))) ace alp))
1049'abc'
1050```
1052---
1054## `++stag`
1056Add label
1058Add a label to an `edge` parsed by a `rule`.
1060#### Accepts
1062`gob` is a noun.
1064`sef` is a rule.
1066#### Produces
1068A `rule`.
1070#### Source
1072```hoon
1073++ stag
1074 ~/ %stag
1075 |* [gob=* sef=rule]
1076 ~/ %fun
1077 |= tub=nail
1078 =+ vex=(sef tub)
1079 ?~ q.vex
1080 vex
1081 [p=p.vex q=[~ u=[p=[gob p.u.q.vex] q=q.u.q.vex]]]
1082```
1084#### Examples
1086```
1087> (rash 'abc' (stag %foo (jest 'abc')))
1088[%foo 'abc']
1089```
1091---
1093## `++star`
1095List of matches
1097Parser modifier: parse `list` of matches.
1099#### Accepts
1101`fel` is a `rule`.
1103#### Produces
1105A `rule`.
1107#### Source
1109```hoon
1110++ star
1111 |* fel=rule
1112 (stir `(list _(wonk *fel))`~ |*([a=* b=*] [a b]) fel)
1113```
1115#### Examples
1117```
1118> (scan "aaaaa" (just 'a'))
1119! {1 2}
1120! 'syntax-error'
1121! exit
1123> (scan "aaaaa" (star (just 'a')))
1124"aaaaa"
1126> (scan "abcdef" (star (just 'a')))
1127! {1 2}
1128! 'syntax-error'
1129! exit
1131> (scan "abcabc" (star (jest 'abc')))
1132<|abc abc|>
1134> (scan "john smith" (star (shim 0 200)))
1135"john smith"
1136```
1138---
1140## `++stet`
1142Add faces
1144Add faces `[p q]` to range-parser pairs in a list. Typically used in combination
1145with [`++stew`](#stew).
1147#### Accepts
1149`leh` is a list of range-parsers.
1151#### Produces
1153A `(list [p=?(@ [@ @]) q=rule])`.
1155#### Source
1157```hoon
1158++ stet
1159 |* leh=(list [?(@ [@ @]) rule])
1160 |-
1161 ?~ leh
1163 [i=[p=-.i.leh q=+.i.leh] t=$(leh t.leh)]
1164```
1166#### Examples
1168```
1169> =rule %- stew
1170 %- stet
1171 %- limo
1172 :~
1173 [['a' 'z'] (cook |=(a=@ (sub a 32)) alp)]
1174 [['A' 'Z'] (cook |=(a=@ (add a 32)) alp)]
1175 ==
1177> `tape`(rash 'fooBARbaz' (star rule))
1178"FOObarBAZ"
1179```
1181---
1183## `++stew`
1185Switch by first char
1187Parser generator. From an associative `list` of characters or character
1188ranges to `rule`s, construct a `map`, and parse `tape`s only
1189with `rule`s associated with a range that the `tape`'s first character falls in.
1191#### Accepts
1193`leh` is a `(list [p=?(@ [@ @]) q=rule])`, where `p` is a `char` or `char` range.
1195#### Produces
1197A `rule`.
1199#### Source
1201```hoon
1202++ stew :: switch by first char
1203 ~/ %stew
1204 |* leh=(list [p=?(@ [@ @]) q=rule]) :: char+range keys
1205 =+ ^= wor :: range complete lth
1206 |= [ort=?(@ [@ @]) wan=?(@ [@ @])]
1207 ?@ ort
1208 ?@(wan (lth ort wan) (lth ort -.wan))
1209 ?@(wan (lth +.ort wan) (lth +.ort -.wan))
1210 =+ ^= hel :: build parser map
1211 =+ hel=`(tree _?>(?=(^ leh) i.leh))`~
1212 |- ^+ hel
1213 ?~ leh
1215 =+ yal=$(leh t.leh)
1216 |- ^+ hel
1217 ?~ yal
1218 [i.leh ~ ~]
1219 ?: (wor p.i.leh p.n.yal)
1220 =+ nuc=$(yal l.yal)
1221 ?> ?=(^ nuc)
1222 ?: (mor p.n.yal p.n.nuc)
1223 [n.yal nuc r.yal]
1224 [n.nuc l.nuc [n.yal r.nuc r.yal]]
1225 =+ nuc=$(yal r.yal)
1226 ?> ?=(^ nuc)
1227 ?: (mor p.n.yal p.n.nuc)
1228 [n.yal l.yal nuc]
1229 [n.nuc [n.yal l.yal l.nuc] r.nuc]
1230 ~% %fun ..^$ ~
1231 |= tub=nail
1232 ?~ q.tub
1233 (fail tub)
1234 |-
1235 ?~ hel
1236 (fail tub)
1237 ?: ?@ p.n.hel
1238 =(p.n.hel i.q.tub)
1239 ?&((gte i.q.tub -.p.n.hel) (lte i.q.tub +.p.n.hel))
1240 :: (q.n.hel [(lust i.q.tub p.tub) t.q.tub])
1241 (q.n.hel tub)
1242 ?: (wor i.q.tub p.n.hel)
1243 $(hel l.hel)
1244 $(hel r.hel)
1245```
1247#### Examples
1249```
1250> =rule %- stew
1251 %- stet
1252 %- limo
1253 :~
1254 [['a' 'z'] (cook |=(a=@ (sub a 32)) alp)]
1255 [['A' 'Z'] (cook |=(a=@ (add a 32)) alp)]
1256 ==
1258> `tape`(rash 'fooBARbaz' (star rule))
1259"FOObarBAZ"
1260```
1262---
1264## `++stir`
1266Parse repeatedly
1268Parse with `rule` as many times as possible, and fold over results with a
1269binary gate.
1271#### Accepts
1273`rud` is a noun.
1275`raq` is a gate that takes two nouns and produces a cell.
1277`fel` is a `rule`.
1279#### Produces
1281A `rule`.
1283#### Source
1285```hoon
1286++ stir
1287 ~/ %stir
1288 |* [rud=* raq=_=>(~ |*([a=* b=*] [a b])) fel=rule]
1289 ~/ %fun
1290 |= tub=nail
1291 ^- (like _rud)
1292 ::
1293 :: lef: successful interim parse results (per .fel)
1294 :: wag: initial accumulator (.rud in .tub at farthest success)
1295 ::
1296 =+ ^= [lef wag]
1297 =| lef=(list _(fel tub))
1298 |- ^- [_lef (pair hair [~ u=(pair _rud nail)])]
1299 =+ vex=(fel tub)
1300 ?~ q.vex
1301 :- lef
1302 [p.vex [~ rud tub]]
1303 $(lef [vex lef], tub q.u.q.vex)
1304 ::
1305 :: fold .lef into .wag, combining results with .raq
1306 ::
1307 %+ roll lef
1308 |= _[vex=(fel tub) wag=wag] :: q.vex is always (some)
1309 ^+ wag
1310 :- (last p.vex p.wag)
1311 [~ (raq p.u.+.q.vex p.u.q.wag) q.u.q.wag]
1312```
1314#### Examples
1316```
1317> (scan "abc" (stir *@ add prn))
1318294
1320> (roll "abc" add)
1321294
1322```
1324---
1326## `++stun`
1328Parse several times
1330Parse bounded number of times.
1332#### Accepts
1334`lig` is a cell of atoms (`[@ @]`) indicating the bounds.
1336`fel` is a `rule`.
1338#### Produces
1340A `rule`.
1342#### Source
1344```hoon
1345++ stun
1346 ~/ %stun
1347 |* [lig=[@ @] fel=rule]
1348 |= tub=nail
1349 ^- (like (list _(wonk (fel))))
1350 ?: =(0 +.lig)
1351 [p.tub [~ ~ tub]]
1352 =+ vex=(fel tub)
1353 ?~ q.vex
1354 ?: =(0 -.lig)
1355 [p.vex [~ ~ tub]]
1356 vex
1357 =+ ^= wag %= $
1358 -.lig ?:(=(0 -.lig) 0 (dec -.lig))
1359 +.lig ?:(=(0 +.lig) 0 (dec +.lig))
1360 tub q.u.q.vex
1361 ==
1362 ?~ q.wag
1363 wag
1364 [p.wag [~ [p.u.q.vex p.u.q.wag] q.u.q.wag]]
1365```
1367#### Examples
1369```
1370> ((stun [5 10] prn) [1 1] "aquickbrownfoxran")
1371[p=[p=1 q=11] q=[~ [p="aquickbrow" q=[p=[p=1 q=11] q="nfoxran"]]]]
1373> ((stun [5 10] prn) [1 1] "aquickbro")
1374[p=[p=1 q=10] q=[~ [p="aquickbro" q=[p=[p=1 q=10] q=""]]]]
1376> ((stun [5 10] prn) [1 1] "aqui")
1377[p=[p=1 q=5] q=~]
1378```
1380---