4f: Parsing (Rule-Builders)
++bass
Parser modifier: LSB
ordered ++list
as atom of a ++base
.
Accepts
wuc
is an atom.
tyd
is a ++rule
.
Produces
A ++rule
.
Source
++ bass |* {wuc/@ tyd/rule} %+ cook |= waq/(list @) %+ roll waq =|({p/@ q/@} |.((add p (mul wuc q)))) tyd ::
Examples
> (scan "123" (bass 10 (star dit)))
q=123
> (scan "123" (bass 8 (star dit)))
q=83
> `@ub`(scan "123" (bass 8 (star dit)))
0b101.0011
++boss
Parser modifier: LSB
Ordered ++list
as atom of a ++base
.
Accepts
wuc
is an atom.
tyd
is a ++rule
.
Produces
A ++rule
.
Source
++ boss |* {wuc/@ tyd/rule} %+ cook |= waq/(list @) %+ reel waq =|({p/@ q/@} |.((add p (mul wuc q)))) tyd ::
Examples
> (scan "123" (boss 10 (star dit)))
q=321
> `@t`(scan "bam" (boss 256 (star alp)))
'bam'
> `@ux`(scan "bam" (boss 256 (star alp)))
0x6d.6162
++cold
Replace with constant
Parser modifier. Accepts a ++rule
sef
and produces a parser that
produces a constant cus
, assuming sef
is successful.
Accepts
cus
is a constant noun.
sef
is a ++rule
.
Produces
An ++edge
.
Source
++ cold :: replace w+ constant ~/ %cold |* {cus/* sef/rule} ~/ %fun |= tub/nail =+ vex=(sef tub) ?~ q.vex vex [p=p.vex q=[~ u=[p=cus q=q.u.q.vex]]]
Examples
> ((cold %foo (just 'a')) [[1 1] "abc"])
[p=[p=1 q=2] q=[~ u=[p=%foo q=[p=[p=1 q=2] q="bc"]]]]
> ((cold %foo (just 'a')) [[1 1] "bc"])
[p=[p=1 q=1] q=~]
++cook
Apply gate
Parser modifier. Produces a parser that takes a (successful) result of a
++rule
sef
and slams it through poq
.
Accepts
poq
is a gate.
sef
is a ++rule
.
Produces
An ++rule
.
Source
++ cook :: apply gate ~/ %cook |* {poq/gate sef/rule} ~/ %fun |= tub/nail =+ vex=(sef tub) ?~ q.vex vex [p=p.vex q=[~ u=[p=(poq p.u.q.vex) q=q.u.q.vex]]] ::
Examples
> ((cook ,@ud (just 'a')) [[1 1] "abc"])
[p=[p=1 q=2] q=[~ u=[p=97 q=[p=[p=1 q=2] q="bc"]]]]
> ((cook ,@tas (just 'a')) [[1 1] "abc"])
[p=[p=1 q=2] q=[~ u=[p=%a q=[p=[p=1 q=2] q="bc"]]]]
> ((cook |=(a=@ +(a)) (just 'a')) [[1 1] "abc"])
[p=[p=1 q=2] q=[~ u=[p=98 q=[p=[p=1 q=2] q="bc"]]]]
> ((cook |=(a=@ `@t`+(a)) (just 'a')) [[1 1] "abc"])
[p=[p=1 q=2] q=[~ u=[p='b' q=[p=[p=1 q=2] q="bc"]]]]
++easy
Always parse
Parser generator. Produces a parser that succeeds with given noun huf
without consuming any text.
Accepts
huf
is a noun.
Produces
A ++rule
.
Source
++ easy :: always parse ~/ %easy |* huf=* ~/ %fun |= tub=nail ^- (like ,_huf) [p=p.tub q=[~ u=[p=huf q=tub]]] ::
Examples
> ((easy %foo) [[1 1] "abc"])
[p=[p=1 q=1] q=[~ [p=%foo q=[p=[p=1 q=1] q="abc"]]]]
> ((easy %foo) [[1 1] "bc"])
[p=[p=1 q=1] q=[~ [p=%foo q=[p=[p=1 q=1] q="bc"]]]]
> ((easy 'a') [[1 1] "bc"])
[p=[p=1 q=1] q=[~ [p='a' q=[p=[p=1 q=1] q="bc"]]]]
++full
Parse to end
Parser modifier. Accepts a ++rule
sef
, and produces a parser that succeeds only
when the of tub
is fully consumed using sef
.
Accepts
sef
is a ++rule
.
Produces
A ++rule
.
Source
++ full :: parse to end |* sef=_rule |= tub=nail =+ vex=(sef tub) ?~(q.vex vex ?:(=(~ q.q.u.q.vex) vex [p=p.vex q=~])) ::
Examples
> ((full (just 'a')) [[1 1] "ab"])
[p=[p=1 q=2] q=~]
> ((full (jest 'ab')) [[1 1] "ab"])
[p=[p=1 q=3] q=[~ u=[p='ab' q=[p=[p=1 q=3] q=""]]]]
> ((full ;~(plug (just 'a') (just 'b'))) [[1 1] "ab"])
[p=[p=1 q=3] q=[~ u=[p=[~~a ~~b] q=[p=[p=1 q=3] q=""]]]]
++funk
Add to tape
Parser modifier: prepend text to ++tape
before applying parser.
Accepts
pre
is a ++tape
sef
is a ++rule
Produces
A ++rule
.
Source
++ funk :: add to tape first |* {pre/tape sef/rule} |= tub/nail (sef p.tub (weld pre q.tub))
Examples
> ((funk "abc prefix-" (jest 'abc')) [[1 1] "to be parsed"])
[p=[p=1 q=4] q=[~ [p='abc' q=[p=[p=1 q=4] q=" prefix-to be parsed"]]]]
> ((funk "parse" (just 'a')) [[1 4] " me"])
[p=[p=1 q=4] q=~]
++here
Place-based apply
Parser modifier. Similar to ++cook
in that it produces a parser that takes a
(successful) result of sef
and slams it through hez
. hez
accepts a
++pint
a
and a noun b
, which is what the parser parsed.
Accepts
hez
is a gate.
sef
is a ++rule
Produces
A ++rule
.
Source
++ here :: place-based apply ~/ %here |* {hez/_|=({a/pint b/*} [a b]) sef/rule} ~/ %fun |= tub/nail =+ vex=(sef tub) ?~ q.vex vex [p=p.vex q=[~ u=[p=(hez [p.tub p.q.u.q.vex] p.u.q.vex) q=q.u.q.vex]]] ::
Examples
> (scan "abc" (star alf))
"abc"
> (scan "abc" (here |*(^ +<) (star alf)))
[[[p=1 q=1] p=1 q=4] "abc"]
> (scan "abc" (star (here |*(^ +<) alf)))
~[[[[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]]
++ifix
Infix
Parser modifier: surround with pair of ++rule
s, the output of which is
discarded.
Accepts
fel
is a pair of ++rule
s.
hof
is a ++rule
.
Produces
A ++rule
.
Source
++ ifix |* {fel/{rule rule} hof/rule} ~! +< ~! +<:-.fel ~! +<:+.fel ;~(pfix -.fel ;~(sfix hof +.fel)) ::
Examples
> (scan "-40-" (ifix [hep hep] dem))
q=40
> (scan "4my4" (ifix [dit dit] (star alf)))
"my"
++jest
Match a cord
Match and consume a cord.
Accepts
daf
is a @t
.
Produces
An ++edge
.
Source
++ jest :: match a cord |= daf/@t |= tub/nail =+ fad=daf |- ^- (like @t) ?: =(`@`0 daf) [p=p.tub q=[~ u=[p=fad q=tub]]] ?: |(?=($~ q.tub) !=((end 3 1 daf) i.q.tub)) (fail tub) $(p.tub (lust i.q.tub p.tub), q.tub t.q.tub, daf (rsh 3 1 daf)) ::
Examples
> ((jest 'abc') [[1 1] "abc"])
[p=[p=1 q=4] q=[~ [p='abc' q=[p=[p=1 q=4] q=""]]]]
> (scan "abc" (jest 'abc'))
'abc'
> (scan "abc" (jest 'acb'))
! {1 2}
! 'syntax-error'
! exit
> ((jest 'john doe') [[1 1] "john smith"])
[p=[p=1 q=6] q=~]
> ((jest 'john doe') [[1 1] "john doe"])
[p=[p=1 q=9] q=[~ [p='john doe' q=[p=[p=1 q=9] q=""]]]]
++just
Match a char
Match and consume a single character.
Accepts
daf
is a ++char
Produces
A ++rule
.
Source
++ just :: XX redundant, jest ~/ %just :: match a char |= daf/char ~/ %fun |= tub/nail ^- (like char) ?~ q.tub (fail tub) ?. =(daf i.q.tub) (fail tub) (next tub) ::
Examples
> ((just 'a') [[1 1] "abc"])
[p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
> (scan "abc" (just 'a'))
! {1 2}
! 'syntax-error'
! exit
> (scan "a" (just 'a'))
~~a
> (scan "%" (just '%'))
~~~25.
++knee
Recursive parsers
Used for recursive parsers, which would otherwise be infinite when compiled.
Accepts
gar
is a noun.
sef
is a gate that accepts a ++rule
Produces
A ++rule
.
Source
++ knee :: callbacks |* {gar/* sef/_|.(*rule)} |= tub/nail ^- (like _gar) ((sef) tub) ::
Examples
> |-(;~(plug prn ;~(pose $ (easy ~))))
! rest-loop
! exit
> |-(;~(plug prn ;~(pose (knee *tape |.(^$)) (easy ~))))
< 1.obo
[ c=c=tub=[p=[p=@ud q=@ud] q=""]
b
< 1.bes
[ c=tub=[p=[p=@ud q=@ud] q=""]
b=<1.tnv [tub=[p=[p=@ud q=@ud] q=""] <1.ktu [daf=@tD <414.fvk 101.jzo 1.ypj %164>]>]>
a=<1.fvg [tub=[p=[p=@ud q=@ud] q=""] <1.khu [[les=@ mos=@] <414.fvk 101.jzo 1.ypj %164>]>]>
v=<414.fvk 101.jzo 1.ypj %164>
]
>
a
... 450 lines omitted ...
]
>
> (scan "abcd" |-(;~(plug prn ;~(pose (knee *tape |.(^$)) (easy ~)))))
[~~a "bcd"]
++mask
Match char
Parser generator. Matches the next character if it is in a list of characters.
Accepts
bud
is a list of ++char
Produces
A ++rule
.
Source
++ mask :: match char in set ~/ %mask |= bud/(list char) ~/ %fun |= tub/nail ^- (like char) ?~ q.tub (fail tub) ?. (lien bud |=(a/char =(i.q.tub a))) (fail tub) (next tub) ::
Examples
> (scan "a" (mask "cba"))
~~a
> ((mask "abc") [[1 1] "abc"])
[p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
> ((mask "abc") [[1 1] "bbc"])
[p=[p=1 q=2] q=[~ [p=~~b q=[p=[p=1 q=2] q="bc"]]]]
> ((mask "abc") [[1 1] "dbc"])
[p=[p=1 q=1] q=~]
++more
Parse list with delimiter
Parser modifier: Parse a list of matches using a delimiter ++rule
.
Accepts
bus
is a ++rule
.
fel
is a ++rule
.
Produces
A ++rule
.
Source
++ more |* {bus/rule fel/rule} ;~(pose (most bus fel) (easy ~)) ::
Examples
> (scan "" (more ace dem))
~
> (scan "40 20" (more ace dem))
[q=40 ~[q=20]]
> (scan "40 20 60 1 5" (more ace dem))
[q=40 ~[q=20 q=60 q=1 q=5]]
++most
Parse list of at least one match
Parser modifier: parse a ++list
of at least one match using a delimiter ++rule
.
Accepts
bus
is a ++rule
.
fel
is a ++rule
.
Produces
A ++rule
.
Source
++ most |* {bus/rule fel/rule} ;~(plug fel (star ;~(pfix bus fel))) ::
Examples
> (scan "40 20" (most ace dem))
[q=40 ~[q=20]]
> (scan "40 20 60 1 5" (most ace dem))
[q=40 ~[q=20 q=60 q=1 q=5]]
> (scan "" (most ace dem))
! {1 1}
! exit
++next
Consume char
Consume any character, producing it as a result.
Accepts
tub
is a ++nail
Produces
An ++edge
.
Source
++ next :: consume a char |= tub/nail ^- (like char) ?~ q.tub (fail tub) =+ zac=(lust i.q.tub p.tub) [zac [~ i.q.tub [zac t.q.tub]]] ::
Examples
> (next [[1 1] "ebc"])
[p=[p=1 q=2] q=[~ [p=~~e q=[p=[p=1 q=2] q="bc"]]]]
> (next [[1 1] "john jumps jones"])
[p=[p=1 q=2] q=[~ [p=~~j q=[p=[p=1 q=2] q="ohn jumps jones"]]]]
++plus
List of at least one match.
Parser modifier: parse ++list
of at least one match.
Accepts
fel
is a ++rule
.
Produces
A ++rule
.
Source
++ plus |*(fel/rule ;~(plug fel (star fel)))
Examples
> (scan ">>>>" (cook lent (plus gar)))
4
> (scan "- - " (plus ;~(pose ace hep)))
[~~- " - "]
> `tape`(scan "- - " (plus ;~(pose ace hep)))
"- - "
> `(pole ,@t)`(scan "- - " (plus ;~(pose ace hep)))
['-' [' ' [' ' ['-' [' ' ~]]]]]
++sear
Conditional ++cook
Conditional ++cook
. Slams the result through a gate that produces
a unit; if that unit is empty, fail.
Accepts
tub
is a ++nail
.
Produces
A ++rule
.
Source
++ sear :: conditional cook |* {pyq/$-(* (unit)) sef/rule} |= tub/nail =+ vex=(sef tub) ?~ q.vex vex =+ gey=(pyq p.u.q.vex) ?~ gey [p=p.vex q=~] [p=p.vex q=[~ u=[p=u.gey q=q.u.q.vex]]] ::
Examples
> ((sear |=(a/* ?@(a (some a) ~)) (just `a`)) [[1 1] "abc"])
[p=[p=1 q=2] q=[~ u=[p=97 q=[p=[p=1 q=2] q="bc"]]]]
> ((sear |=(* ~) (just 'a')) [[1 1] "abc"])
[p=[p=1 q=2] q=~]
++shim
Char in range
Match characters (++char
) within a range.
Accepts
les
is an atom.
mos
is an atom.
Produces
A ++rule
.
Source
++ shim :: match char in range ~/ %shim |= {les/@ mos/@} ~/ %fun |= tub/nail ^- (like char) ?~ q.tub (fail tub) ?. ?&((gte i.q.tub les) (lte i.q.tub mos)) (fail tub) (next tub) ::
Examples
> ((shim 'a' 'z') [[1 1] "abc"])
[p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
> ((shim 'a' 'Z') [[1 1] "abc"])
[p=[p=1 q=1] q=~]
> ((shim 'a' 'Z') [[1 1] "Abc"])
[p=[p=1 q=2] q=[~ [p=~~~41. q=[p=[p=1 q=2] q="bc"]]]]
++slug
Use gate to parse delimited list
Parser modifier: By composing with a gate, parse a delimited ++list
of
matches.
Accepts
bus
is a ++rule
.
fel
is a ++rule
.
Produces
A ++rule
.
Source
++ slug |* raq/_|*({a/* b/*} [a b]) |* {bus/rule fel/rule} ;~((comp raq) fel (stir +<+.raq raq ;~(pfix bus fel))) ::
Examples
> (scan "20+5+110" ((slug add) lus dem))
135
> `@t`(scan "a b c" ((slug |=(a/[@ @t] (cat 3 a))) ace alp))
'abc'
++stag
Add label
Add a label to an edge parsed by a rule.
Accepts
gob
is a noun.
sef
is a rule.
Produces
A ++rule
.
Source
++ stag :: add a label ~/ %stag |* {gob/* sef/rule} ~/ %fun |= tub/nail =+ vex=(sef tub) ?~ q.vex vex [p=p.vex q=[~ u=[p=[gob p.u.q.vex] q=q.u.q.vex]]] ::
Examples
> ((stag %foo (just 'a')) [[1 1] "abc"])
[p=[p=1 q=2] q=[~ u=[p=[%foo ~~a] q=[p=[p=1 q=2] q="bc"]]]]
> ((stag "xyz" (jest 'abc')) [[1 1] "abc"])
[p=[p=1 q=4] q=[~ u=[p=["xyz" 'abc'] q=[p=[p=1 q=4] q=""]]]]
> ((stag 10.000 (shim 0 100)) [[1 1] "abc"])
[p=[p=1 q=2] q=[~ u=[p=[10.000 ~~a] q=[p=[p=1 q=2] q="bc"]]]]
++star
List of matches
Parser modifier: parse ++list
of matches.
Accepts
fel
is a ++rule
.
Produces
++ star :: 0 or more times |* fel/rule (stir `(list _(wonk *fel))`~ |*({a/* b/*} [a b]) fel)
Examples
> (scan "aaaaa" (just 'a'))
! {1 2}
! 'syntax-error'
! exit
> (scan "aaaaa" (star (just 'a')))
"aaaaa"
> (scan "abcdef" (star (just 'a')))
! {1 2}
! 'syntax-error'
! exit
> (scan "abcabc" (star (jest 'abc')))
<|abc abc|>
> (scan "john smith" (star (shim 0 200)))
"john smith"
++stet
Add faces
Add faces [p q]
to range-parser pairs in a list.
Accepts
leh
is a list of range-parsers.
Produces
Source
++ stet |* leh/(list {?(@ {@ @}) rule}) |- ?~ leh ~ [i=[p=-.i.leh q=+.i.leh] t=$(leh t.leh)] ::
Examples
> (stet (limo [[5 (just 'a')] [1 (jest 'abc')] [[1 1] (shim 0 200)]
[[1 10] (cold %foo (just 'a'))]~]))
~[
[p=5 q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
[p=1 q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
[p=[1 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
[p=[1 10] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
]
> [[[1 1] (just 'a')] [[2 1] (shim 0 200)] ~]
[ [[1 1] <1.tnv [tub=[p=[p=@ud q=@ud] q=""] <1.ktu [daf=@tD <414.fvk 101.jzo 1.ypj %164>]>]>]
[[2 1] <1.fvg [tub=[p=[p=@ud q=@ud] q=""] <1.khu [[les=@ mos=@] <414.fvk 101.jzo 1.ypj %164>]>]>]
~
]
> (stet (limo [[[1 1] (just 'a')] [[2 1] (shim 0 200)] ~]))
~[
[p=[1 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
[p=[2 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
]
++stew
Switch by first
++ stew :: switch by first char ~/ %stew |* leh/(list {p/?(@ {@ @}) q/rule}) :: char+range keys =+ ^= wor :: range complete lth |= {ort/?(@ {@ @}) wan/?(@ {@ @})} ?@ ort ?@(wan (lth ort wan) (lth ort -.wan)) ?@(wan (lth +.ort wan) (lth +.ort -.wan)) =+ ^= hel :: build parser map =+ hel=`(tree _?>(?=(^ leh) i.leh))`~ |- ^+ hel ?~ leh ~ =+ yal=$(leh t.leh) |- ^+ hel ?~ yal [i.leh ~ ~] ?: (wor p.i.leh p.n.yal) =+ nuc=$(yal l.yal) ?> ?=(^ nuc) ?: (vor p.n.yal p.n.nuc) [n.yal nuc r.yal] [n.nuc l.nuc [n.yal r.nuc r.yal]] =+ nuc=$(yal r.yal) ?> ?=(^ nuc) ?: (vor p.n.yal p.n.nuc) [n.yal l.yal nuc] [n.nuc [n.yal l.yal l.nuc] r.nuc] ~% %fun ..^$ ~ |= tub/nail ?~ q.tub (fail tub) |- ?~ hel (fail tub) ?: ?@ p.n.hel =(p.n.hel i.q.tub) ?&((gte i.q.tub -.p.n.hel) (lte i.q.tub +.p.n.hel)) :: (q.n.hel [(lust i.q.tub p.tub) t.q.tub]) (q.n.hel tub) ?: (wor i.q.tub p.n.hel) $(hel l.hel) $(hel r.hel) ::
Parser generator. From an associative ++list
of characters or character
ranges to ++rule
s, construct a ++map
, and parse ++tape
s only
with ++rules
associated with a range that the ++tape
's first character falls in.
++stir
Parse repeatedly
Parse with ++rule
as many times as possible, and fold over results with a
binary gate.
Accepts
rud
is a noun.
raq
is a gate that takes two nouns and produces a cell.
fel
is a rule.
Produces
A rule.
Source
++ stir ~/ %stir |* {rud/* raq/_=>(~ |*({a/* b/*} [a b])) fel/rule} ~/ %fun |= tub/nail ^- (like _rud) =+ vex=(fel tub) ?~ q.vex [p.vex [~ rud tub]] =+ wag=$(tub q.u.q.vex) ?> ?=(^ q.wag) [(last p.vex p.wag) [~ (raq p.u.q.vex p.u.q.wag) q.u.q.wag]]
Examples
> (scan "abc" (stir *@ add prn))
294
> (roll "abc" add)
b=294
++stun
Parse several times
Parse bounded number of times.
Accepts
[les=@ mos=@]
is a cell of atoms indicating the bounds.
fel
is a ++rule
.
Produces
A ++rule
.
Source
++ stun :: parse several times |* {lig/{@ @} fel/rule} |= tub/nail ^- (like (list _(wonk (fel)))) ?: =(0 +.lig) [p.tub [~ ~ tub]] =+ vex=(fel tub) ?~ q.vex ?: =(0 -.lig) [p.vex [~ ~ tub]] vex =+ ^= wag %= $ -.lig ?:(=(0 -.lig) 0 (dec -.lig)) +.lig ?:(=(0 +.lig) 0 (dec +.lig)) tub q.u.q.vex == ?~ q.wag wag [p.wag [~ [p.u.q.vex p.u.q.wag] q.u.q.wag]]
Examples
> ((stun [5 10] prn) [1 1] "aquickbrownfoxran")
[p=[p=1 q=11] q=[~ [p="aquickbrow" q=[p=[p=1 q=11] q="nfoxran"]]]]
> ((stun [5 10] prn) [1 1] "aquickbro")
[p=[p=1 q=10] q=[~ [p="aquickbro" q=[p=[p=1 q=10] q=""]]]]
> ((stun [5 10] prn) [1 1] "aqui")
[p=[p=1 q=5] q=~]