on 74efdad help sign in
470 lines 8.2 kB history raw
1+++
2title = "4e: Parsing (Combinators)"
3weight = 32
4template = "doc.html"
5+++
6### `++bend`
8Conditional composer
10Parsing composer: connects the `++edge` `vex` with the subsequent `++rule` `sab`
11as an optional suffix, using gate `raq` to compose or reject its
12result. If there is no suffix, or if the suffix fails to be composed
13with the current result, the current result is produced. Used to map a
14group of rules to a specified output.
16#### Accepts
18`raq` is a gate.
20`sab` is a rule.
22`vex` is an edge.
24#### Produces
26A `++rule`.
28#### Source
30```
31 ++ bend :: conditional comp
32 ~/ %bend
33 |* raq/_|*({a/* b/*} [~ u=[a b]])
34 ~/ %fun
35 |* {vex/edge sab/rule}
36 ?~ q.vex
37 vex
38 =+ yit=(sab q.u.q.vex)
39 =+ yur=(last p.vex p.yit)
40 ?~ q.yit
41 [p=yur q=q.vex]
42 =+ vux=(raq p.u.q.vex p.u.q.yit)
43 ?~ vux
44 [p=yur q=q.vex]
45 [p=yur q=[~ u=[p=u.vux q=q.u.q.yit]]]
46 ::
47```
49#### Examples
51```
52 > (;~((bend |=([a/char b/char] ?.(=(a b) ~ (some +(a))))) prn prn) [1 1] "qs")
53 [p=[p=1 q=3] q=[~ u=[p=~~q q=[p=[p=1 q=2] q="s"]]]]
55 > (;~((bend |=([a/char b/char] ?.(=(a b) ~ (some +(a))))) prn prn) [1 1] "qqq")
56 [p=[p=1 q=3] q=[~ u=[p=~~r q=[p=[p=1 q=3] q="q"]]]]
58 > (scan "aa" ;~((bend |=([a/char b/char] ?.(=(a b) ~ (some +(a))))) prn prn))
59 ~~b
61 > (scan "ba" ;~((bend |=([a/char b/char] ?.(=(a b) ~ (some +(a))))) prn prn))
62 ! {1 3}
63 ! exit
65 > `(unit @tas)`(scan "" ;~((bend) (easy ~) sym))
66 ~
68 > `(unit @tas)`(scan "sep" ;~((bend) (easy ~) sym))
69 [~ %sep]
70```
73---
74### `++comp`
76Arbitrary compose
78Parsing composer: connects the `++edge` `vex` with a following `++rule` `sab`,
79combining the contents of `vex` with the result of `sab` using a binary
80gate `raq`. Used to fold over the results of several `++rules`.
82#### Accepts
84`raq` is a gate that accepts a cell of two nouns, `a` and `b`, and
85produces a cell of two nouns.
87`sab` is a rule.
89`vex` is an edge.
91#### Produces
93A `++rule`.
95#### Source
97```
98 ++ comp
99 ~/ %comp
100 |* raq/_|*({a/* b/*} [a b]) :: arbitrary compose
101 ~/ %fun
102 |* {vex/edge sab/rule}
103 ~! +<
104 ?~ q.vex
105 vex
106 =+ yit=(sab q.u.q.vex)
107 =+ yur=(last p.vex p.yit)
108 ?~ q.yit
109 [p=yur q=q.yit]
110 [p=yur q=[~ u=[p=(raq p.u.q.vex p.u.q.yit) q=q.u.q.yit]]]
111 ::
112```
114#### Examples
116```
117 > (scan "123" ;~((comp |=([a/@u b/@u] (add a b))) dit dit dit))
118 6
119 > (scan "12" ;~((comp |=([a/@u b/@u] (add a b))) dit dit dit))
120 ! {1 3}
121 ! exit
122```
124---
125### `++fail`
127Never parse
129Produces an `++edge` at the same text position (`++hair`) with a failing
130result (`q=~`).
132#### Accepts
134`tub` is a `++nail`.
136#### Produces
138An `++edge`.
140#### Source
142```
143 ++ fail |=(tub/nail [p=p.tub q=~]) :: never parse
144```
146#### Examples
148```
149 > (fail [[1 1] "abc"])
150 [p=[p=1 q=1] q=~]
152 > (fail [[p=1.337 q=70] "Parse me, please?"])
153 [p=[p=1.337 q=70] q=~]
154```
157---
158### `++glue`
160Skip delimiter
162Parsing composer: connects an `++edge` `vex` with a following `++rule` `sab` by
163parsing the `++rule` `bus` (the delimiting symbol) and throwing out the
164result.
166#### Accepts
168`bus` is a `++rule`.
170`sab` is a `++rule`.
172`vex` is an `++edge`.
174#### Produces
178#### Source
180```
181 ++ glue :: add rule
182 ~/ %glue
183 |* bus/rule
184 ~/ %fun
185 |* {vex/edge sab/rule}
186 (plug vex ;~(pfix bus sab))
187 ::
188```
190#### Examples
192```
193 > (scan "200|mal|bon" ;~((glue bar) dem sym sym))
194 [q=200 7.102.829 7.237.474]
196 > `[@u @tas @tas]`(scan "200|mal|bon" ;~((glue bar) dem sym sym))
197 [200 %mal %bon]
199 > (scan "200|;|bon" ;~((glue bar) dem sem sym))
200 [q=200 ~~~3b. 7.237.474]
202 > (scan "200.;.bon" ;~((glue dot) dem sem sym))
203 [q=200 ~~~3b. 7.237.474]
204```
206---
207### `++less`
209Parse unless
211Parsing composer: if an `++edge` `vex` reflects a success, fail. Otherwise,
212connect `vex` with the following `++rule`.
214#### Accepts
216`sab` is a `++rule`.
218`vex` is an `++edge`.
220#### Produces
224#### Source
226```
227 ++ less :: no first and second
228 |* {vex/edge sab/rule}
229 ?~ q.vex
230 =+ roq=(sab)
231 [p=(last p.vex p.roq) q=q.roq]
232 (fail +<.sab)
233 ::
234```
236#### Examples
238```
239 > (scan "sas-/lo" (star ;~(less lus bar prn)))
240 "sas-/lo"
242 > (scan "sas-/l+o" (star ;~(less lus bar prn)))
243 ! {1 8}
244 ! exit
246 > (scan "sas|-/lo" (star ;~(less lus bar prn)))
247 ! {1 5}
248 ! exit
249```
252---
253### `++pfix`
255Discard first rule
257Parsing composer: connects an `++edge` `vex` with two subsequent `++rule`s,
258ignoring the result of the first and producing the result of the second.
260#### Accepts
262`vex` is an edge.
264#### Produces
268#### Source
270```
271 ++ pfix :: discard first rule
272 ~/ %pfix
273 (comp |*({a/* b/*} b))
274```
276#### Examples
278```
279 > `@t`(scan "%him" ;~(pfix cen sym))
280 'him'
282 > (scan "+++10" ;~(pfix (star lus) dem))
283 q=10
284```
287---
288### `++plug`
290Parse to tuple
292Parsing composer: connects an `++edge` `vex` with a following `++rule` `sab`, producing
293a cell of both the results. See also: the monad applicator ;\~ for a
294more detailed explanation.
296#### Accepts
298`sab` is a `++rule`.
300`vex` is an `++edge`.
302#### Produces
306#### Source
308```
309 ++ plug :: first then second
310 ~/ %plug
311 |* {vex/edge sab/rule}
312 ?~ q.vex
313 vex
314 =+ yit=(sab q.u.q.vex)
315 =+ yur=(last p.vex p.yit)
316 ?~ q.yit
317 [p=yur q=q.yit]
318 [p=yur q=[~ u=[p=[p.u.q.vex p.u.q.yit] q=q.u.q.yit]]]
319 ::
320```
322#### Examples
324```
325 > (scan "1..20" ;~(plug dem dot dot dem))
326 [q=1 ~~~. ~~~. q=20]
328 > (scan "moke/~2014.1.1" ;~(plug sym fas nuck:so))
329 [1.701.539.693 ~~~2f. [% p=[p=~.da q=170.141.184.500.766.106.671.844.917.172.921.958.400]]]
331 > ;;(,[@tas @t ~ %da @da] (scan "moke/~2014.1.1" ;~(plug sym fas nuck:so)))
332 [%moke '/' ~ %da ~2014.1.1]
333```
336---
337### `++pose`
339Parse options
341Parsing composer: if `vex` reflects a failure, connect it with the
342following rule `sab`. See also: the monad applicator ;\~
344#### Accepts
346`sab` is a `++rule`.
348`vex` is an `++edge`.
350#### Produces
354#### Source
356```
357 ++ pose :: first or second
358 ~/ %pose
359 |* {vex/edge sab/rule}
360 ?~ q.vex
361 =+ roq=(sab)
362 [p=(last p.vex p.roq) q=q.roq]
363 vex
364 ::
365```
367#### Examples
369```
370 > `@t`(scan "+" ;~(pose lus tar cen))
371 '+'
373 > `@t`(scan "*" ;~(pose lus tar cen))
374 '*'
376 > `@t`(scan "%" ;~(pose lus tar cen))
377 '%'
379 > `@t`(scan "-" ;~(pose lus tar cen))
380 ! {1 1}
381 ! exit
382```
385---
386### `++sfix`
388Discard second rule
390Parsing composer: connects `++edge`s `vex` with two subsequent `++rule`s returning the
391result of the first and discarding the result of the second.
393#### Accepts
395`a` is the result of parsing the first `++rule`.
397`b` is the result of of parsing the second `++rule`.
399#### Produces
403#### Source
405```
406 ++ sfix :: discard second rule
407 ~/ %sfix
408 (comp |*({a/* b/*} a))
409```
411#### Examples
413```
414 > `@t`(scan "him%" ;~(sfix sym cen))
415 'him'
417 > (scan "10+++" ;~(sfix dem (star lus)))
418 q=10
419```
422---
423### `++simu`
425First and second
427Parsing composer: if an `++edge` `vex` reflects a failure, fail. Otherwise,
428connect `vex` with the following `++rule`.
430#### Accepts
432`sab` is a `++rule`.
434`vex` is an `++edge`.
436#### Produces
440#### Source
442```
443 ++ simu :: first and second
444 |* {vex/edge sab/rule}
445 ?~ q.vex
446 vex
447 =+ roq=(sab)
448 roq
449 ::
450```
452#### Examples
454```
455 > (scan "~zod" scat:vast)
456 [%dtzy p=%p q=0]
458 > (scan "%zod" scat:vast)
459 [%dtzz p=%tas q=6.582.138]
461 > (scan "%zod" ;~(simu cen scat:vast))
462 [%dtzz p=%tas q=6.582.138]
464 > (scan "~zod" ;~(simu cen scat:vast))
465 ! {1 1}
466 ! exit
467```
470---