on 140ac0e help sign in
457 lines 8.1 kB history raw
1# 4e: parsing (combinators)
2### `++bend`
4Conditional composer
6Parsing composer: connects the `++edge` `vex` with the subsequent `++rule` `sab`
7as an optional suffix, using gate `raq` to compose or reject its
8result. If there is no suffix, or if the suffix fails to be composed
9with the current result, the current result is produced. Used to map a
10group of rules to a specified output.
12Accepts
13-------
15`raq` is a gate.
17`sab` is a rule.
19`vex` is an edge.
21Produces
22--------
24A `++rule`.
26Source
27------
29 ++ bend :: conditional comp
30 ~/ %bend
31 |* raq/_|*({a/* b/*} [~ u=[a b]])
32 ~/ %fun
33 |* {vex/edge sab/rule}
34 ?~ q.vex
35 vex
36 =+ yit=(sab q.u.q.vex)
37 =+ yur=(last p.vex p.yit)
38 ?~ q.yit
39 [p=yur q=q.vex]
40 =+ vux=(raq p.u.q.vex p.u.q.yit)
41 ?~ vux
42 [p=yur q=q.vex]
43 [p=yur q=[~ u=[p=u.vux q=q.u.q.yit]]]
44 ::
46Examples
47--------
49 > (;~((bend |=([a/char b/char] ?.(=(a b) ~ (some +(a))))) prn prn) [1 1] "qs")
50 [p=[p=1 q=3] q=[~ u=[p=~~q q=[p=[p=1 q=2] q="s"]]]]
51 > (;~((bend |=([a/char b/char] ?.(=(a b) ~ (some +(a))))) prn prn) [1 1] "qqq")
52 [p=[p=1 q=3] q=[~ u=[p=~~r q=[p=[p=1 q=3] q="q"]]]]
53 > (scan "aa" ;~((bend |=([a/char b/char] ?.(=(a b) ~ (some +(a))))) prn prn))
54 ~~b
55 > (scan "ba" ;~((bend |=([a/char b/char] ?.(=(a b) ~ (some +(a))))) prn prn))
56 ! {1 3}
57 ! exit
58 > `(unit @tas)`(scan "" ;~((bend) (easy ~) sym))
59 ~
60 > `(unit @tas)`(scan "sep" ;~((bend) (easy ~) sym))
61 [~ %sep]
65***
66### `++comp`
68Arbitrary compose
70Parsing composer: connects the `++edge` `vex` with a following `++rule` `sab`,
71combining the contents of `vex` with the result of `sab` using a binary
72gate `raq`. Used to fold over the results of several `++rules`.
74Accepts
75-------
77`raq` is a gate that accepts a cell of two nouns, `a` and `b`, and
78produces a cell of two nouns.
80`sab` is a rule.
82`vex` is an edge.
84Produces
85--------
87A `++rule`.
89Source
90------
92 ++ comp
93 ~/ %comp
94 |* raq/_|*({a/* b/*} [a b]) :: arbitrary compose
95 ~/ %fun
96 |* {vex/edge sab/rule}
97 ~! +<
98 ?~ q.vex
99 vex
100 =+ yit=(sab q.u.q.vex)
101 =+ yur=(last p.vex p.yit)
102 ?~ q.yit
103 [p=yur q=q.yit]
104 [p=yur q=[~ u=[p=(raq p.u.q.vex p.u.q.yit) q=q.u.q.yit]]]
105 ::
107Examples
108--------
110 > (scan "123" ;~((comp |=([a/@u b/@u] (add a b))) dit dit dit))
111 6
112 > (scan "12" ;~((comp |=([a/@u b/@u] (add a b))) dit dit dit))
113 ! {1 3}
114 ! exit
116***
117### `++fail`
119Never parse
121Produces an `++edge` at the same text position (`++hair`) with a failing
122result (`q=~`).
124Accepts
125-------
127`tub` is a `++nail`.
129Produces
130--------
132An `++edge`.
134Source
135------
137 ++ fail |=(tub/nail [p=p.tub q=~]) :: never parse
139Examples
140--------
142 > (fail [[1 1] "abc"])
143 [p=[p=1 q=1] q=~]
144 > (fail [[p=1.337 q=70] "Parse me, please?"])
145 [p=[p=1.337 q=70] q=~]
149***
150### `++glue`
152Skip delimiter
154Parsing composer: connects an `++edge` `vex` with a following `++rule` `sab` by
155parsing the `++rule` `bus` (the delimiting symbol) and throwing out the
156result.
158Accepts
159-------
161`bus` is a `++rule`.
163`sab` is a `++rule`.
165`vex` is an `++edge`.
167Produces
168--------
172Source
173------
175 ++ glue :: add rule
176 ~/ %glue
177 |* bus/rule
178 ~/ %fun
179 |* {vex/edge sab/rule}
180 (plug vex ;~(pfix bus sab))
181 ::
183Examples
184--------
186 > (scan "200|mal|bon" ;~((glue bar) dem sym sym))
187 [q=200 7.102.829 7.237.474]
188 > `[@u @tas @tas]`(scan "200|mal|bon" ;~((glue bar) dem sym sym))
189 [200 %mal %bon]
190 > (scan "200|;|bon" ;~((glue bar) dem sem sym))
191 [q=200 ~~~3b. 7.237.474]
192 > (scan "200.;.bon" ;~((glue dot) dem sem sym))
193 [q=200 ~~~3b. 7.237.474]
197***
198### `++less`
200Parse unless
202Parsing composer: if an `++edge` `vex` reflects a success, fail. Otherwise,
203connect `vex` with the following `++rule`.
205Accepts
206-------
208`sab` is a `++rule`.
210`vex` is an `++edge`.
212Produces
213--------
217Source
218------
220 ++ less :: no first and second
221 |* {vex/edge sab/rule}
222 ?~ q.vex
223 =+ roq=(sab)
224 [p=(last p.vex p.roq) q=q.roq]
225 (fail +<.sab)
226 ::
228Examples
229--------
231 > (scan "sas-/lo" (star ;~(less lus bar prn)))
232 "sas-/lo"
233 > (scan "sas-/l+o" (star ;~(less lus bar prn)))
234 ! {1 8}
235 ! exit
236 > (scan "sas|-/lo" (star ;~(less lus bar prn)))
237 ! {1 5}
238 ! exit
242***
243### `++pfix`
245Discard first rule
247Parsing composer: connects an `++edge` `vex` with two subsequent `++rule`s,
248ignoring the result of the first and producing the result of the second.
250Accepts
251-------
253`vex` is an edge.
255Produces
256--------
260Source
261------
263 ++ pfix :: discard first rule
264 ~/ %pfix
265 (comp |*({a/* b/*} b))
267Examples
268--------
270 > `@t`(scan "%him" ;~(pfix cen sym))
271 'him'
272 > (scan "+++10" ;~(pfix (star lus) dem))
273 q=10
277***
278### `++plug`
280Parse to tuple
282Parsing composer: connects an `++edge` `vex` with a following `++rule` `sab`, producing
283a cell of both the results. See also: the monad applicator ;\~ for a
284more detailed explanation.
286Accepts
287-------
289`sab` is a `++rule`.
291`vex` is an `++edge`.
293Produces
294--------
298Source
299------
301 ++ plug :: first then second
302 ~/ %plug
303 |* {vex/edge sab/rule}
304 ?~ q.vex
305 vex
306 =+ yit=(sab q.u.q.vex)
307 =+ yur=(last p.vex p.yit)
308 ?~ q.yit
309 [p=yur q=q.yit]
310 [p=yur q=[~ u=[p=[p.u.q.vex p.u.q.yit] q=q.u.q.yit]]]
311 ::
313Examples
314--------
316 > (scan "1..20" ;~(plug dem dot dot dem))
317 [q=1 ~~~. ~~~. q=20]
318 > (scan "moke/~2014.1.1" ;~(plug sym fas nuck:so))
319 [1.701.539.693 ~~~2f. [% p=[p=~.da q=170.141.184.500.766.106.671.844.917.172.921.958.400]]]
320 > ;;(,[@tas @t ~ %da @da] (scan "moke/~2014.1.1" ;~(plug sym fas nuck:so)))
321 [%moke '/' ~ %da ~2014.1.1]
325***
326### `++pose`
328Parse options
330Parsing composer: if `vex` reflects a failure, connect it with the
331following rule `sab`. See also: the monad applicator ;\~
333Accepts
334-------
336`sab` is a `++rule`.
338`vex` is an `++edge`.
340Produces
341--------
345Source
346------
348 ++ pose :: first or second
349 ~/ %pose
350 |* {vex/edge sab/rule}
351 ?~ q.vex
352 =+ roq=(sab)
353 [p=(last p.vex p.roq) q=q.roq]
354 vex
355 ::
358Examples
359--------
361 > `@t`(scan "+" ;~(pose lus tar cen))
362 '+'
363 > `@t`(scan "*" ;~(pose lus tar cen))
364 '*'
365 > `@t`(scan "%" ;~(pose lus tar cen))
366 '%'
367 > `@t`(scan "-" ;~(pose lus tar cen))
368 ! {1 1}
369 ! exit
373***
374### `++sfix`
376Discard second rule
378Parsing composer: connects `++edge`s `vex` with two subsequent `++rule`s returning the
379result of the first and discarding the result of the second.
381Accepts
382-------
384`a` is the result of parsing the first `++rule`.
386`b` is the result of of parsing the second `++rule`.
388Produces
389--------
393Source
394------
396 ++ sfix :: discard second rule
397 ~/ %sfix
398 (comp |*({a/* b/*} a))
401Examples
402--------
404 > `@t`(scan "him%" ;~(sfix sym cen))
405 'him'
406 > (scan "10+++" ;~(sfix dem (star lus)))
407 q=10
411***
412### `++simu`
414First and second
416Parsing composer: if an `++edge` `vex` reflects a failure, fail. Otherwise,
417connect `vex` with the following `++rule`.
419Accepts
420-------
422`sab` is a `++rule`.
424`vex` is an `++edge`.
426Produces
427--------
431Source
432------
434 ++ simu :: first and second
435 |* {vex/edge sab/rule}
436 ?~ q.vex
437 vex
438 =+ roq=(sab)
439 roq
440 ::
442Examples
443--------
445 > (scan "~zod" scat:vast)
446 [%dtzy p=%p q=0]
447 > (scan "%zod" scat:vast)
448 [%dtzz p=%tas q=6.582.138]
449 > (scan "%zod" ;~(simu cen scat:vast))
450 [%dtzz p=%tas q=6.582.138]
451 > (scan "~zod" ;~(simu cen scat:vast))
452 ! {1 1}
453 ! exit
457***