1# 4f: parsing (rule builders)
5ordered `++list` as atom of a `++base`.
28 =|({p/@ q/@} |.((add p (mul wuc q))))
36 > (scan "123" (bass 10 (star dit)))
38 > (scan "123" (bass 8 (star dit)))
40 > `@ub`(scan "123" (bass 8 (star dit)))
51Ordered `++list` as atom of a `++base`.
74 =|({p/@ q/@} |.((add p (mul wuc q))))
81 > (scan "123" (boss 10 (star dit)))
83 > `@t`(scan "bam" (boss 256 (star alp)))
85 > `@ux`(scan "bam" (boss 256 (star alp)))
94Parser modifier. Accepts a `++rule` `sef` and produces a parser that
95produces a constant `cus`, assuming `sef` is successful.
100`cus` is a constant noun.
112 ++ cold :: replace w+ constant
120 [p=p.vex q=[~ u=[p=cus q=q.u.q.vex]]]
125 > ((cold %foo (just 'a')) [[1 1] "abc"])
126 [p=[p=1 q=2] q=[~ u=[p=%foo q=[p=[p=1 q=2] q="bc"]]]]
127 > ((cold %foo (just 'a')) [[1 1] "bc"])
137Parser modifier. Produces a parser that takes a (successful) result of a
138`++rule` `sef` and slams it through `poq`.
155 ++ cook :: apply gate
157 |* {poq/$-(* *) sef/rule}
163 [p=p.vex q=[~ u=[p=(poq p.u.q.vex) q=q.u.q.vex]]]
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"]]]]
171 > ((cook ,@tas (just 'a')) [[1 1] "abc"])
172 [p=[p=1 q=2] q=[~ u=[p=%a q=[p=[p=1 q=2] q="bc"]]]]
173 > ((cook |=(a=@ +(a)) (just 'a')) [[1 1] "abc"])
174 [p=[p=1 q=2] q=[~ u=[p=98 q=[p=[p=1 q=2] q="bc"]]]]
175 > ((cook |=(a=@ `@t`+(a)) (just 'a')) [[1 1] "abc"])
176 [p=[p=1 q=2] q=[~ u=[p='b' q=[p=[p=1 q=2] q="bc"]]]]
185Parser generator. Produces a parser that succeeds with given noun `huf`
186without consuming any text.
201 ++ easy :: always parse
207 [p=p.tub q=[~ u=[p=huf q=tub]]]
213 > ((easy %foo) [[1 1] "abc"])
214 [p=[p=1 q=1] q=[~ [p=%foo q=[p=[p=1 q=1] q="abc"]]]]
215 > ((easy %foo) [[1 1] "bc"])
216 [p=[p=1 q=1] q=[~ [p=%foo q=[p=[p=1 q=1] q="bc"]]]]
217 > ((easy 'a') [[1 1] "bc"])
218 [p=[p=1 q=1] q=[~ [p='a' q=[p=[p=1 q=1] q="bc"]]]]
227Parser modifier. Accepts a `++rule` `sef`, and produces a parser that succeeds only
228when the of `tub` is fully consumed using `sef`.
243 ++ full :: parse to end
247 ?~(q.vex vex ?:(=(~ q.q.u.q.vex) vex [p=p.vex q=~]))
253 > ((full (just 'a')) [[1 1] "ab"])
255 > ((full (jest 'ab')) [[1 1] "ab"])
256 [p=[p=1 q=3] q=[~ u=[p='ab' q=[p=[p=1 q=3] q=""]]]]
257 > ((full ;~(plug (just 'a') (just 'b'))) [[1 1] "ab"])
258 [p=[p=1 q=3] q=[~ u=[p=[~~a ~~b] q=[p=[p=1 q=3] q=""]]]]
267Parser modifier: prepend text to `++tape` before applying parser.
284 ++ funk :: add to tape first
285 |* {pre/tape sef/rule}
287 (sef p.tub (weld pre q.tub))
292 > ((funk "abc prefix-" (jest 'abc')) [[1 1] "to be parsed"])
293 [p=[p=1 q=4] q=[~ [p='abc' q=[p=[p=1 q=4] q=" prefix-to be parsed"]]]]
294 > ((funk "parse" (just 'a')) [[1 4] " me"])
304Parser modifier. Similar to `++cook` in that it produces a parser that takes a
305(successful) result of `sef` and slams it through `hez`. `hez` accepts a
306`++pint` `a` and a noun `b`, which is what the parser parsed.
323 ++ here :: place-based apply
325 |* {hez/_|=({a/pint b/*} [a b]) sef/rule}
331 [p=p.vex q=[~ u=[p=(hez [p.tub p.q.u.q.vex] p.u.q.vex) q=q.u.q.vex]]]
337 > (scan "abc" (star alf))
339 > (scan "abc" (here |*(^ +<) (star alf)))
340 [[[p=1 q=1] p=1 q=4] "abc"]
341 > (scan "abc" (star (here |*(^ +<) alf)))
342 ~[[[[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]]
351Parser modifier: surround with pair of `++rule`s, the output of which is
357`fel` is a pair of `++rule`s.
370 |* {fel/{rule rule} hof/rule}
374 ;~(pfix -.fel ;~(sfix hof +.fel))
380 > (scan "-40-" (ifix [hep hep] dem))
382 > (scan "4my4" (ifix [dit dit] (star alf)))
392Match and consume a cord.
407 ++ jest :: match a cord
413 [p=p.tub q=[~ u=[p=fad q=tub]]]
414 ?: |(?=($~ q.tub) !=((end 3 1 daf) i.q.tub))
416 $(p.tub (lust i.q.tub p.tub), q.tub t.q.tub, daf (rsh 3 1 daf))
422 > ((jest 'abc') [[1 1] "abc"])
423 [p=[p=1 q=4] q=[~ [p='abc' q=[p=[p=1 q=4] q=""]]]]
424 > (scan "abc" (jest 'abc'))
426 > (scan "abc" (jest 'acb'))
430 > ((jest 'john doe') [[1 1] "john smith"])
432 > ((jest 'john doe') [[1 1] "john doe"])
433 [p=[p=1 q=9] q=[~ [p='john doe' q=[p=[p=1 q=9] q=""]]]]
442Match and consume a single character.
457 ++ just :: XX redundant, jest
458 ~/ %just :: match a char
474 > ((just 'a') [[1 1] "abc"])
475 [p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
476 > (scan "abc" (just 'a'))
480 > (scan "a" (just 'a'))
482 > (scan "%" (just '%'))
492Used for recursive parsers, which would otherwise be infinite when
500`sef` is a gate that accepts a `++rule`
511 |* {gar/* sef/_|.(*rule)}
520 > |-(;~(plug prn ;~(pose $ (easy ~))))
523 > |-(;~(plug prn ;~(pose (knee *tape |.(^$)) (easy ~))))
525 [ c=c=tub=[p=[p=@ud q=@ud] q=""]
528 [ c=tub=[p=[p=@ud q=@ud] q=""]
529 b=<1.tnv [tub=[p=[p=@ud q=@ud] q=""] <1.ktu [daf=@tD <414.fvk 101.jzo 1.ypj %164>]>]>
530 a=<1.fvg [tub=[p=[p=@ud q=@ud] q=""] <1.khu [[les=@ mos=@] <414.fvk 101.jzo 1.ypj %164>]>]>
531 v=<414.fvk 101.jzo 1.ypj %164>
535 ... 450 lines omitted ...
538 > (scan "abcd" |-(;~(plug prn ;~(pose (knee *tape |.(^$)) (easy ~)))))
548Parser generator. Matches the next character if it is in a list of
554`bud` is a list of `++char`
564 ++ mask :: match char in set
572 ?. (lien bud |=(a/char =(i.q.tub a)))
580 > (scan "a" (mask "cba"))
582 > ((mask "abc") [[1 1] "abc"])
583 [p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
584 > ((mask "abc") [[1 1] "bbc"])
585 [p=[p=1 q=2] q=[~ [p=~~b q=[p=[p=1 q=2] q="bc"]]]]
586 > ((mask "abc") [[1 1] "dbc"])
594Parse list with delimiter
596Parser modifier: Parse a list of matches using a delimiter `++rule`.
614 |* {bus/rule fel/rule}
615 ;~(pose (most bus fel) (easy ~))
621 > (scan "" (more ace dem))
623 > (scan "40 20" (more ace dem))
625 > (scan "40 20 60 1 5" (more ace dem))
626 [q=40 ~[q=20 q=60 q=1 q=5]]
633Parse list of at least one match
635Parser modifier: parse a `++list` of at least one match using a delimiter `++rule`.
653 |* {bus/rule fel/rule}
654 ;~(plug fel (star ;~(pfix bus fel)))
660 > (scan "40 20" (most ace dem))
662 > (scan "40 20 60 1 5" (most ace dem))
663 [q=40 ~[q=20 q=60 q=1 q=5]]
664 > (scan "" (most ace dem))
675Consume any character, producing it as a result.
690 ++ next :: consume a char
695 =+ zac=(lust i.q.tub p.tub)
696 [zac [~ i.q.tub [zac t.q.tub]]]
702 > (next [[1 1] "ebc"])
703 [p=[p=1 q=2] q=[~ [p=~~e q=[p=[p=1 q=2] q="bc"]]]]
704 > (next [[1 1] "john jumps jones"])
705 [p=[p=1 q=2] q=[~ [p=~~j q=[p=[p=1 q=2] q="ohn jumps jones"]]]]
713List of at least one match.
715Parser modifier: parse `++list` of at least one match.
730 ++ plus |*(fel/rule ;~(plug fel (star fel)))
736 > (scan ">>>>" (cook lent (plus gar)))
738 > (scan "- - " (plus ;~(pose ace hep)))
740 > `tape`(scan "- - " (plus ;~(pose ace hep)))
742 > `(pole ,@t)`(scan "- - " (plus ;~(pose ace hep)))
743 ['-' [' ' [' ' ['-' [' ' ~]]]]]
752Conditional `++cook`. Slams the result through a gate that produces
753a unit; if that unit is empty, fail.
767 ++ sear :: conditional cook
768 |* {pyq/$-(* (unit)) sef/rule}
773 =+ gey=(pyq p.u.q.vex)
776 [p=p.vex q=[~ u=[p=u.gey q=q.u.q.vex]]]
783 > ((sear |=(a/* ?@(a (some a) ~)) (just `a`)) [[1 1] "abc"])
784 [p=[p=1 q=2] q=[~ u=[p=97 q=[p=[p=1 q=2] q="bc"]]]]
785 > ((sear |=(* ~) (just 'a')) [[1 1] "abc"])
795Match characters (`++char`) within a range.
812 ++ shim :: match char in range
820 ?. ?&((gte i.q.tub les) (lte i.q.tub mos))
828 > ((shim 'a' 'z') [[1 1] "abc"])
829 [p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
830 > ((shim 'a' 'Z') [[1 1] "abc"])
832 > ((shim 'a' 'Z') [[1 1] "Abc"])
833 [p=[p=1 q=2] q=[~ [p=~~~41. q=[p=[p=1 q=2] q="bc"]]]]
840Use gate to parse delimited list
842Parser modifier: By composing with a gate, parse a delimited `++list` of
861 |* raq/_|*({a/* b/*} [a b])
862 |* {bus/rule fel/rule}
863 ;~((comp raq) fel (stir +<+.raq raq ;~(pfix bus fel)))
870 > (scan "20+5+110" ((slug add) lus dem))
872 > `@t`(scan "a b c" ((slug |=(a/[@ @t] (cat 3 a))) ace alp))
882Add a label to an edge parsed by a rule.
899 ++ stag :: add a label
907 [p=p.vex q=[~ u=[p=[gob p.u.q.vex] q=q.u.q.vex]]]
913 > ((stag %foo (just 'a')) [[1 1] "abc"])
914 [p=[p=1 q=2] q=[~ u=[p=[%foo ~~a] q=[p=[p=1 q=2] q="bc"]]]]
915 > ((stag "xyz" (jest 'abc')) [[1 1] "abc"])
916 [p=[p=1 q=4] q=[~ u=[p=["xyz" 'abc'] q=[p=[p=1 q=4] q=""]]]]
917 > ((stag 10.000 (shim 0 100)) [[1 1] "abc"])
918 [p=[p=1 q=2] q=[~ u=[p=[10.000 ~~a] q=[p=[p=1 q=2] q="bc"]]]]
927Parser modifier: parse `++list` of matches.
937 ++ star :: 0 or more times
939 (stir `(list _(wonk *fel))`~ |*({a/* b/*} [a b]) fel)
944 > (scan "aaaaa" (just 'a'))
948 > (scan "aaaaa" (star (just 'a')))
950 > (scan "abcdef" (star (just 'a')))
954 > (scan "abcabc" (star (jest 'abc')))
956 > (scan "john smith" (star (shim 0 200)))
966Add faces `[p q]` to range-parser pairs in a list.
971`leh` is a list of range-parsers.
982 |* leh/(list {?(@ {@ @}) rule})
986 [i=[p=-.i.leh q=+.i.leh] t=$(leh t.leh)]
992 > (stet (limo [[5 (just 'a')] [1 (jest 'abc')] [[1 1] (shim 0 200)]
993 [[1 10] (cold %foo (just 'a'))]~]))
995 [p=5 q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
996 [p=1 q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
997 [p=[1 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
998 [p=[1 10] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
1000 > [[[1 1] (just 'a')] [[2 1] (shim 0 200)] ~]
1001 [ [[1 1] <1.tnv [tub=[p=[p=@ud q=@ud] q=""] <1.ktu [daf=@tD <414.fvk 101.jzo 1.ypj %164>]>]>]
1002 [[2 1] <1.fvg [tub=[p=[p=@ud q=@ud] q=""] <1.khu [[les=@ mos=@] <414.fvk 101.jzo 1.ypj %164>]>]>]
1005 > (stet (limo [[[1 1] (just 'a')] [[2 1] (shim 0 200)] ~]))
1007 [p=[1 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
1008 [p=[2 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
1018 ++ stew :: switch by first char
1020 |* leh/(list {p/?(@ {@ @}) q/rule}) :: char+range keys
1021 =+ ^= wor :: range complete lth
1022 |= {ort/?(@ {@ @}) wan/?(@ {@ @})}
1024 ?@(wan (lth ort wan) (lth ort -.wan))
1025 ?@(wan (lth +.ort wan) (lth +.ort -.wan))
1026 =+ ^= hel :: build parser map
1027 =+ hel=`(tree _?>(?=(^ leh) i.leh))`~
1035 ?: (wor p.i.leh p.n.yal)
1038 ?: (vor p.n.yal p.n.nuc)
1040 [n.nuc l.nuc [n.yal r.nuc r.yal]]
1043 ?: (vor p.n.yal p.n.nuc)
1045 [n.nuc [n.yal l.yal l.nuc] r.nuc]
1055 ?&((gte i.q.tub -.p.n.hel) (lte i.q.tub +.p.n.hel))
1056 :: (q.n.hel [(lust i.q.tub p.tub) t.q.tub])
1058 ?: (wor i.q.tub p.n.hel)
1065Parser generator. From an associative `++list` of characters or character
1066ranges to `++rule`s, construct a `++map`, and parse `++tape`s only
1067with `++rules` associated with a range that the `++tape`'s first character falls in.
1076Parse with `++rule` as many times as possible, and fold over results with a
1084`raq` is a gate that takes two nouns and produces a cell.
1096 ++ stun :: parse several times
1097 |* {lig/{@ @} fel/rule}
1099 ^- (like (list _(wonk (fel))))
1108 -.lig ?:(=(0 -.lig) 0 (dec -.lig))
1109 +.lig ?:(=(0 +.lig) 0 (dec +.lig))
1114 [p.wag [~ [p.u.q.vex p.u.q.wag] q.u.q.wag]]
1120 > (scan "abc" (stir *@ add prn))
1132Parse bounded number of times.
1137`[les=@ mos=@]` is a cell of atoms indicating the bounds.
1149 ++ stun :: parse several times
1150 |* {lig/{@ @} fel/rule}
1152 ^- (like (list _(wonk (fel))))
1161 -.lig ?:(=(0 -.lig) 0 (dec -.lig))
1162 +.lig ?:(=(0 +.lig) 0 (dec +.lig))
1167 [p.wag [~ [p.u.q.vex p.u.q.wag] q.u.q.wag]]
1172 > ((stun [5 10] prn) [1 1] "aquickbrownfoxran")
1173 [p=[p=1 q=11] q=[~ [p="aquickbrow" q=[p=[p=1 q=11] q="nfoxran"]]]]
1174 > ((stun [5 10] prn) [1 1] "aquickbro")
1175 [p=[p=1 q=10] q=[~ [p="aquickbro" q=[p=[p=1 q=10] q=""]]]]
1176 > ((stun [5 10] prn) [1 1] "aqui")
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list