on 6d45ede help sign in
462 lines 8.2 kB history raw
1---
2navhome: /docs
3---
6# 4e: parsing (combinators)
7### `++bend`
9Conditional composer
11Parsing composer: connects the `++edge` `vex` with the subsequent `++rule` `sab`
12as an optional suffix, using gate `raq` to compose or reject its
13result. If there is no suffix, or if the suffix fails to be composed
14with the current result, the current result is produced. Used to map a
15group of rules to a specified output.
17Accepts
18-------
20`raq` is a gate.
22`sab` is a rule.
24`vex` is an edge.
26Produces
27--------
29A `++rule`.
31Source
32------
34 ++ bend :: conditional comp
35 ~/ %bend
36 |* raq/_|*({a/* b/*} [~ u=[a b]])
37 ~/ %fun
38 |* {vex/edge sab/rule}
39 ?~ q.vex
40 vex
41 =+ yit=(sab q.u.q.vex)
42 =+ yur=(last p.vex p.yit)
43 ?~ q.yit
44 [p=yur q=q.vex]
45 =+ vux=(raq p.u.q.vex p.u.q.yit)
46 ?~ vux
47 [p=yur q=q.vex]
48 [p=yur q=[~ u=[p=u.vux q=q.u.q.yit]]]
49 ::
51Examples
52--------
54 > (;~((bend |=([a/char b/char] ?.(=(a b) ~ (some +(a))))) prn prn) [1 1] "qs")
55 [p=[p=1 q=3] q=[~ u=[p=~~q q=[p=[p=1 q=2] q="s"]]]]
56 > (;~((bend |=([a/char b/char] ?.(=(a b) ~ (some +(a))))) prn prn) [1 1] "qqq")
57 [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
60 > (scan "ba" ;~((bend |=([a/char b/char] ?.(=(a b) ~ (some +(a))))) prn prn))
61 ! {1 3}
62 ! exit
63 > `(unit @tas)`(scan "" ;~((bend) (easy ~) sym))
64 ~
65 > `(unit @tas)`(scan "sep" ;~((bend) (easy ~) sym))
66 [~ %sep]
70***
71### `++comp`
73Arbitrary compose
75Parsing composer: connects the `++edge` `vex` with a following `++rule` `sab`,
76combining the contents of `vex` with the result of `sab` using a binary
77gate `raq`. Used to fold over the results of several `++rules`.
79Accepts
80-------
82`raq` is a gate that accepts a cell of two nouns, `a` and `b`, and
83produces a cell of two nouns.
85`sab` is a rule.
87`vex` is an edge.
89Produces
90--------
92A `++rule`.
94Source
95------
97 ++ comp
98 ~/ %comp
99 |* raq/_|*({a/* b/*} [a b]) :: arbitrary compose
100 ~/ %fun
101 |* {vex/edge sab/rule}
102 ~! +<
103 ?~ q.vex
104 vex
105 =+ yit=(sab q.u.q.vex)
106 =+ yur=(last p.vex p.yit)
107 ?~ q.yit
108 [p=yur q=q.yit]
109 [p=yur q=[~ u=[p=(raq p.u.q.vex p.u.q.yit) q=q.u.q.yit]]]
110 ::
112Examples
113--------
115 > (scan "123" ;~((comp |=([a/@u b/@u] (add a b))) dit dit dit))
116 6
117 > (scan "12" ;~((comp |=([a/@u b/@u] (add a b))) dit dit dit))
118 ! {1 3}
119 ! exit
121***
122### `++fail`
124Never parse
126Produces an `++edge` at the same text position (`++hair`) with a failing
127result (`q=~`).
129Accepts
130-------
132`tub` is a `++nail`.
134Produces
135--------
137An `++edge`.
139Source
140------
142 ++ fail |=(tub/nail [p=p.tub q=~]) :: never parse
144Examples
145--------
147 > (fail [[1 1] "abc"])
148 [p=[p=1 q=1] q=~]
149 > (fail [[p=1.337 q=70] "Parse me, please?"])
150 [p=[p=1.337 q=70] q=~]
154***
155### `++glue`
157Skip delimiter
159Parsing composer: connects an `++edge` `vex` with a following `++rule` `sab` by
160parsing the `++rule` `bus` (the delimiting symbol) and throwing out the
161result.
163Accepts
164-------
166`bus` is a `++rule`.
168`sab` is a `++rule`.
170`vex` is an `++edge`.
172Produces
173--------
177Source
178------
180 ++ glue :: add rule
181 ~/ %glue
182 |* bus/rule
183 ~/ %fun
184 |* {vex/edge sab/rule}
185 (plug vex ;~(pfix bus sab))
186 ::
188Examples
189--------
191 > (scan "200|mal|bon" ;~((glue bar) dem sym sym))
192 [q=200 7.102.829 7.237.474]
193 > `[@u @tas @tas]`(scan "200|mal|bon" ;~((glue bar) dem sym sym))
194 [200 %mal %bon]
195 > (scan "200|;|bon" ;~((glue bar) dem sem sym))
196 [q=200 ~~~3b. 7.237.474]
197 > (scan "200.;.bon" ;~((glue dot) dem sem sym))
198 [q=200 ~~~3b. 7.237.474]
202***
203### `++less`
205Parse unless
207Parsing composer: if an `++edge` `vex` reflects a success, fail. Otherwise,
208connect `vex` with the following `++rule`.
210Accepts
211-------
213`sab` is a `++rule`.
215`vex` is an `++edge`.
217Produces
218--------
222Source
223------
225 ++ less :: no first and second
226 |* {vex/edge sab/rule}
227 ?~ q.vex
228 =+ roq=(sab)
229 [p=(last p.vex p.roq) q=q.roq]
230 (fail +<.sab)
231 ::
233Examples
234--------
236 > (scan "sas-/lo" (star ;~(less lus bar prn)))
237 "sas-/lo"
238 > (scan "sas-/l+o" (star ;~(less lus bar prn)))
239 ! {1 8}
240 ! exit
241 > (scan "sas|-/lo" (star ;~(less lus bar prn)))
242 ! {1 5}
243 ! exit
247***
248### `++pfix`
250Discard first rule
252Parsing composer: connects an `++edge` `vex` with two subsequent `++rule`s,
253ignoring the result of the first and producing the result of the second.
255Accepts
256-------
258`vex` is an edge.
260Produces
261--------
265Source
266------
268 ++ pfix :: discard first rule
269 ~/ %pfix
270 (comp |*({a/* b/*} b))
272Examples
273--------
275 > `@t`(scan "%him" ;~(pfix cen sym))
276 'him'
277 > (scan "+++10" ;~(pfix (star lus) dem))
278 q=10
282***
283### `++plug`
285Parse to tuple
287Parsing composer: connects an `++edge` `vex` with a following `++rule` `sab`, producing
288a cell of both the results. See also: the monad applicator ;\~ for a
289more detailed explanation.
291Accepts
292-------
294`sab` is a `++rule`.
296`vex` is an `++edge`.
298Produces
299--------
303Source
304------
306 ++ plug :: first then second
307 ~/ %plug
308 |* {vex/edge sab/rule}
309 ?~ q.vex
310 vex
311 =+ yit=(sab q.u.q.vex)
312 =+ yur=(last p.vex p.yit)
313 ?~ q.yit
314 [p=yur q=q.yit]
315 [p=yur q=[~ u=[p=[p.u.q.vex p.u.q.yit] q=q.u.q.yit]]]
316 ::
318Examples
319--------
321 > (scan "1..20" ;~(plug dem dot dot dem))
322 [q=1 ~~~. ~~~. q=20]
323 > (scan "moke/~2014.1.1" ;~(plug sym fas nuck:so))
324 [1.701.539.693 ~~~2f. [% p=[p=~.da q=170.141.184.500.766.106.671.844.917.172.921.958.400]]]
325 > ;;(,[@tas @t ~ %da @da] (scan "moke/~2014.1.1" ;~(plug sym fas nuck:so)))
326 [%moke '/' ~ %da ~2014.1.1]
330***
331### `++pose`
333Parse options
335Parsing composer: if `vex` reflects a failure, connect it with the
336following rule `sab`. See also: the monad applicator ;\~
338Accepts
339-------
341`sab` is a `++rule`.
343`vex` is an `++edge`.
345Produces
346--------
350Source
351------
353 ++ pose :: first or second
354 ~/ %pose
355 |* {vex/edge sab/rule}
356 ?~ q.vex
357 =+ roq=(sab)
358 [p=(last p.vex p.roq) q=q.roq]
359 vex
360 ::
363Examples
364--------
366 > `@t`(scan "+" ;~(pose lus tar cen))
367 '+'
368 > `@t`(scan "*" ;~(pose lus tar cen))
369 '*'
370 > `@t`(scan "%" ;~(pose lus tar cen))
371 '%'
372 > `@t`(scan "-" ;~(pose lus tar cen))
373 ! {1 1}
374 ! exit
378***
379### `++sfix`
381Discard second rule
383Parsing composer: connects `++edge`s `vex` with two subsequent `++rule`s returning the
384result of the first and discarding the result of the second.
386Accepts
387-------
389`a` is the result of parsing the first `++rule`.
391`b` is the result of of parsing the second `++rule`.
393Produces
394--------
398Source
399------
401 ++ sfix :: discard second rule
402 ~/ %sfix
403 (comp |*({a/* b/*} a))
406Examples
407--------
409 > `@t`(scan "him%" ;~(sfix sym cen))
410 'him'
411 > (scan "10+++" ;~(sfix dem (star lus)))
412 q=10
416***
417### `++simu`
419First and second
421Parsing composer: if an `++edge` `vex` reflects a failure, fail. Otherwise,
422connect `vex` with the following `++rule`.
424Accepts
425-------
427`sab` is a `++rule`.
429`vex` is an `++edge`.
431Produces
432--------
436Source
437------
439 ++ simu :: first and second
440 |* {vex/edge sab/rule}
441 ?~ q.vex
442 vex
443 =+ roq=(sab)
444 roq
445 ::
447Examples
448--------
450 > (scan "~zod" scat:vast)
451 [%dtzy p=%p q=0]
452 > (scan "%zod" scat:vast)
453 [%dtzz p=%tas q=6.582.138]
454 > (scan "%zod" ;~(simu cen scat:vast))
455 [%dtzz p=%tas q=6.582.138]
456 > (scan "~zod" ;~(simu cen scat:vast))
457 ! {1 1}
458 ! exit
462***