on c19bc7a help sign in
474 lines 8.3 kB history raw
1:- :~ navhome/'/docs/'
2 sort/'32'
3 title/'4e: Parsing (Combinators)'
4 ==
6;>
8# 4e: parsing (combinators)
10### `++bend`
12Conditional composer
14Parsing composer: connects the `++edge` `vex` with the subsequent `++rule` `sab`
15as an optional suffix, using gate `raq` to compose or reject its
16result. If there is no suffix, or if the suffix fails to be composed
17with the current result, the current result is produced. Used to map a
18group of rules to a specified output.
20#### Accepts
22`raq` is a gate.
24`sab` is a rule.
26`vex` is an edge.
28#### Produces
30A `++rule`.
32#### Source
34```
35 ++ bend :: conditional comp
36 ~/ %bend
37 |* raq/_|*({a/* b/*} [~ u=[a b]])
38 ~/ %fun
39 |* {vex/edge sab/rule}
40 ?~ q.vex
41 vex
42 =+ yit=(sab q.u.q.vex)
43 =+ yur=(last p.vex p.yit)
44 ?~ q.yit
45 [p=yur q=q.vex]
46 =+ vux=(raq p.u.q.vex p.u.q.yit)
47 ?~ vux
48 [p=yur q=q.vex]
49 [p=yur q=[~ u=[p=u.vux q=q.u.q.yit]]]
50 ::
51```
53#### Examples
55```
56 > (;~((bend |=([a/char b/char] ?.(=(a b) ~ (some +(a))))) prn prn) [1 1] "qs")
57 [p=[p=1 q=3] q=[~ u=[p=~~q q=[p=[p=1 q=2] q="s"]]]]
59 > (;~((bend |=([a/char b/char] ?.(=(a b) ~ (some +(a))))) prn prn) [1 1] "qqq")
60 [p=[p=1 q=3] q=[~ u=[p=~~r q=[p=[p=1 q=3] q="q"]]]]
62 > (scan "aa" ;~((bend |=([a/char b/char] ?.(=(a b) ~ (some +(a))))) prn prn))
63 ~~b
65 > (scan "ba" ;~((bend |=([a/char b/char] ?.(=(a b) ~ (some +(a))))) prn prn))
66 ! {1 3}
67 ! exit
69 > `(unit @tas)`(scan "" ;~((bend) (easy ~) sym))
70 ~
72 > `(unit @tas)`(scan "sep" ;~((bend) (easy ~) sym))
73 [~ %sep]
74```
77---
78### `++comp`
80Arbitrary compose
82Parsing composer: connects the `++edge` `vex` with a following `++rule` `sab`,
83combining the contents of `vex` with the result of `sab` using a binary
84gate `raq`. Used to fold over the results of several `++rules`.
86#### Accepts
88`raq` is a gate that accepts a cell of two nouns, `a` and `b`, and
89produces a cell of two nouns.
91`sab` is a rule.
93`vex` is an edge.
95#### Produces
97A `++rule`.
99#### Source
101```
102 ++ comp
103 ~/ %comp
104 |* raq/_|*({a/* b/*} [a b]) :: arbitrary compose
105 ~/ %fun
106 |* {vex/edge sab/rule}
107 ~! +<
108 ?~ q.vex
109 vex
110 =+ yit=(sab q.u.q.vex)
111 =+ yur=(last p.vex p.yit)
112 ?~ q.yit
113 [p=yur q=q.yit]
114 [p=yur q=[~ u=[p=(raq p.u.q.vex p.u.q.yit) q=q.u.q.yit]]]
115 ::
116```
118#### Examples
120```
121 > (scan "123" ;~((comp |=([a/@u b/@u] (add a b))) dit dit dit))
122 6
123 > (scan "12" ;~((comp |=([a/@u b/@u] (add a b))) dit dit dit))
124 ! {1 3}
125 ! exit
126```
128---
129### `++fail`
131Never parse
133Produces an `++edge` at the same text position (`++hair`) with a failing
134result (`q=~`).
136#### Accepts
138`tub` is a `++nail`.
140#### Produces
142An `++edge`.
144#### Source
146```
147 ++ fail |=(tub/nail [p=p.tub q=~]) :: never parse
148```
150#### Examples
152```
153 > (fail [[1 1] "abc"])
154 [p=[p=1 q=1] q=~]
156 > (fail [[p=1.337 q=70] "Parse me, please?"])
157 [p=[p=1.337 q=70] q=~]
158```
161---
162### `++glue`
164Skip delimiter
166Parsing composer: connects an `++edge` `vex` with a following `++rule` `sab` by
167parsing the `++rule` `bus` (the delimiting symbol) and throwing out the
168result.
170#### Accepts
172`bus` is a `++rule`.
174`sab` is a `++rule`.
176`vex` is an `++edge`.
178#### Produces
182#### Source
184```
185 ++ glue :: add rule
186 ~/ %glue
187 |* bus/rule
188 ~/ %fun
189 |* {vex/edge sab/rule}
190 (plug vex ;~(pfix bus sab))
191 ::
192```
194#### Examples
196```
197 > (scan "200|mal|bon" ;~((glue bar) dem sym sym))
198 [q=200 7.102.829 7.237.474]
200 > `[@u @tas @tas]`(scan "200|mal|bon" ;~((glue bar) dem sym sym))
201 [200 %mal %bon]
203 > (scan "200|;|bon" ;~((glue bar) dem sem sym))
204 [q=200 ~~~3b. 7.237.474]
206 > (scan "200.;.bon" ;~((glue dot) dem sem sym))
207 [q=200 ~~~3b. 7.237.474]
208```
210---
211### `++less`
213Parse unless
215Parsing composer: if an `++edge` `vex` reflects a success, fail. Otherwise,
216connect `vex` with the following `++rule`.
218#### Accepts
220`sab` is a `++rule`.
222`vex` is an `++edge`.
224#### Produces
228#### Source
230```
231 ++ less :: no first and second
232 |* {vex/edge sab/rule}
233 ?~ q.vex
234 =+ roq=(sab)
235 [p=(last p.vex p.roq) q=q.roq]
236 (fail +<.sab)
237 ::
238```
240#### Examples
242```
243 > (scan "sas-/lo" (star ;~(less lus bar prn)))
244 "sas-/lo"
246 > (scan "sas-/l+o" (star ;~(less lus bar prn)))
247 ! {1 8}
248 ! exit
250 > (scan "sas|-/lo" (star ;~(less lus bar prn)))
251 ! {1 5}
252 ! exit
253```
256---
257### `++pfix`
259Discard first rule
261Parsing composer: connects an `++edge` `vex` with two subsequent `++rule`s,
262ignoring the result of the first and producing the result of the second.
264#### Accepts
266`vex` is an edge.
268#### Produces
272#### Source
274```
275 ++ pfix :: discard first rule
276 ~/ %pfix
277 (comp |*({a/* b/*} b))
278```
280#### Examples
282```
283 > `@t`(scan "%him" ;~(pfix cen sym))
284 'him'
286 > (scan "+++10" ;~(pfix (star lus) dem))
287 q=10
288```
291---
292### `++plug`
294Parse to tuple
296Parsing composer: connects an `++edge` `vex` with a following `++rule` `sab`, producing
297a cell of both the results. See also: the monad applicator ;\~ for a
298more detailed explanation.
300#### Accepts
302`sab` is a `++rule`.
304`vex` is an `++edge`.
306#### Produces
310#### Source
312```
313 ++ plug :: first then second
314 ~/ %plug
315 |* {vex/edge sab/rule}
316 ?~ q.vex
317 vex
318 =+ yit=(sab q.u.q.vex)
319 =+ yur=(last p.vex p.yit)
320 ?~ q.yit
321 [p=yur q=q.yit]
322 [p=yur q=[~ u=[p=[p.u.q.vex p.u.q.yit] q=q.u.q.yit]]]
323 ::
324```
326#### Examples
328```
329 > (scan "1..20" ;~(plug dem dot dot dem))
330 [q=1 ~~~. ~~~. q=20]
332 > (scan "moke/~2014.1.1" ;~(plug sym fas nuck:so))
333 [1.701.539.693 ~~~2f. [% p=[p=~.da q=170.141.184.500.766.106.671.844.917.172.921.958.400]]]
335 > ;;(,[@tas @t ~ %da @da] (scan "moke/~2014.1.1" ;~(plug sym fas nuck:so)))
336 [%moke '/' ~ %da ~2014.1.1]
337```
340---
341### `++pose`
343Parse options
345Parsing composer: if `vex` reflects a failure, connect it with the
346following rule `sab`. See also: the monad applicator ;\~
348#### Accepts
350`sab` is a `++rule`.
352`vex` is an `++edge`.
354#### Produces
358#### Source
360```
361 ++ pose :: first or second
362 ~/ %pose
363 |* {vex/edge sab/rule}
364 ?~ q.vex
365 =+ roq=(sab)
366 [p=(last p.vex p.roq) q=q.roq]
367 vex
368 ::
369```
371#### Examples
373```
374 > `@t`(scan "+" ;~(pose lus tar cen))
375 '+'
377 > `@t`(scan "*" ;~(pose lus tar cen))
378 '*'
380 > `@t`(scan "%" ;~(pose lus tar cen))
381 '%'
383 > `@t`(scan "-" ;~(pose lus tar cen))
384 ! {1 1}
385 ! exit
386```
389---
390### `++sfix`
392Discard second rule
394Parsing composer: connects `++edge`s `vex` with two subsequent `++rule`s returning the
395result of the first and discarding the result of the second.
397#### Accepts
399`a` is the result of parsing the first `++rule`.
401`b` is the result of of parsing the second `++rule`.
403#### Produces
407#### Source
409```
410 ++ sfix :: discard second rule
411 ~/ %sfix
412 (comp |*({a/* b/*} a))
413```
415#### Examples
417```
418 > `@t`(scan "him%" ;~(sfix sym cen))
419 'him'
421 > (scan "10+++" ;~(sfix dem (star lus)))
422 q=10
423```
426---
427### `++simu`
429First and second
431Parsing composer: if an `++edge` `vex` reflects a failure, fail. Otherwise,
432connect `vex` with the following `++rule`.
434#### Accepts
436`sab` is a `++rule`.
438`vex` is an `++edge`.
440#### Produces
444#### Source
446```
447 ++ simu :: first and second
448 |* {vex/edge sab/rule}
449 ?~ q.vex
450 vex
451 =+ roq=(sab)
452 roq
453 ::
454```
456#### Examples
458```
459 > (scan "~zod" scat:vast)
460 [%dtzy p=%p q=0]
462 > (scan "%zod" scat:vast)
463 [%dtzz p=%tas q=6.582.138]
465 > (scan "%zod" ;~(simu cen scat:vast))
466 [%dtzz p=%tas q=6.582.138]
468 > (scan "~zod" ;~(simu cen scat:vast))
469 ! {1 1}
470 ! exit
471```
474---