on 883cb21 help sign in
458 lines 8.2 kB history raw
1+++
2title = "4e: Parsing (Combinators)"
3weight = 32
4template = "doc.html"
5+++
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.
17#### Accepts
19`raq` is a gate.
21`sab` is a rule.
23`vex` is an edge.
25#### Produces
27A `++rule`.
29#### Source
31```hoon
32 ++ bend :: conditional comp
33 ~/ %bend
34 |* raq/_|*({a/* b/*} [~ u=[a b]])
35 ~/ %fun
36 |* {vex/edge sab/rule}
37 ?~ q.vex
38 vex
39 =+ yit=(sab q.u.q.vex)
40 =+ yur=(last p.vex p.yit)
41 ?~ q.yit
42 [p=yur q=q.vex]
43 =+ vux=(raq p.u.q.vex p.u.q.yit)
44 ?~ vux
45 [p=yur q=q.vex]
46 [p=yur q=[~ u=[p=u.vux q=q.u.q.yit]]]
47 ::
48```
50#### Examples
52```
53 > (;~((bend |=([a/char b/char] ?.(=(a b) ~ (some +(a))))) prn prn) [1 1] "qs")
54 [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"]]]]
59 > (scan "aa" ;~((bend |=([a/char b/char] ?.(=(a b) ~ (some +(a))))) prn prn))
60 ~~b
62 > (scan "ba" ;~((bend |=([a/char b/char] ?.(=(a b) ~ (some +(a))))) prn prn))
63 ! {1 3}
64 ! exit
66 > `(unit @tas)`(scan "" ;~((bend) (easy ~) sym))
67 ~
69 > `(unit @tas)`(scan "sep" ;~((bend) (easy ~) sym))
70 [~ %sep]
71```
73---
75## `++comp`
77Arbitrary compose
79Parsing composer: connects the `++edge` `vex` with a following `++rule` `sab`,
80combining the contents of `vex` with the result of `sab` using a binary
81gate `raq`. Used to fold over the results of several `++rules`.
83#### Accepts
85`raq` is a gate that accepts a cell of two nouns, `a` and `b`, and
86produces a cell of two nouns.
88`sab` is a rule.
90`vex` is an edge.
92#### Produces
94A `++rule`.
96#### Source
98```hoon
99 ++ comp
100 ~/ %comp
101 |* raq/_|*({a/* b/*} [a b]) :: arbitrary compose
102 ~/ %fun
103 |* {vex/edge sab/rule}
104 ~! +<
105 ?~ q.vex
106 vex
107 =+ yit=(sab q.u.q.vex)
108 =+ yur=(last p.vex p.yit)
109 ?~ q.yit
110 [p=yur q=q.yit]
111 [p=yur q=[~ u=[p=(raq p.u.q.vex p.u.q.yit) q=q.u.q.yit]]]
112 ::
113```
115#### Examples
117```
118 > (scan "123" ;~((comp |=([a/@u b/@u] (add a b))) dit dit dit))
119 6
120 > (scan "12" ;~((comp |=([a/@u b/@u] (add a b))) dit dit dit))
121 ! {1 3}
122 ! exit
123```
125---
127## `++fail`
129Never parse
131Produces an `++edge` at the same text position (`++hair`) with a failing
132result (`q=~`).
134#### Accepts
136`tub` is a `++nail`.
138#### Produces
140An `++edge`.
142#### Source
144```hoon
145 ++ fail |=(tub/nail [p=p.tub q=~]) :: never parse
146```
148#### Examples
150```
151 > (fail [[1 1] "abc"])
152 [p=[p=1 q=1] q=~]
154 > (fail [[p=1.337 q=70] "Parse me, please?"])
155 [p=[p=1.337 q=70] q=~]
156```
158---
160## `++glue`
162Skip delimiter
164Parsing composer: connects an `++edge` `vex` with a following `++rule` `sab` by
165parsing the `++rule` `bus` (the delimiting symbol) and throwing out the
166result.
168#### Accepts
170`bus` is a `++rule`.
172`sab` is a `++rule`.
174`vex` is an `++edge`.
176#### Produces
178#### Source
180```hoon
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---
208## `++less`
210Parse unless
212Parsing composer: if an `++edge` `vex` reflects a success, fail. Otherwise,
213connect `vex` with the following `++rule`.
215#### Accepts
217`sab` is a `++rule`.
219`vex` is an `++edge`.
221#### Produces
223#### Source
225```hoon
226 ++ less :: no first and second
227 |* {vex/edge sab/rule}
228 ?~ q.vex
229 =+ roq=(sab)
230 [p=(last p.vex p.roq) q=q.roq]
231 (fail +<.sab)
232 ::
233```
235#### Examples
237```
238 > (scan "sas-/lo" (star ;~(less lus bar prn)))
239 "sas-/lo"
241 > (scan "sas-/l+o" (star ;~(less lus bar prn)))
242 ! {1 8}
243 ! exit
245 > (scan "sas|-/lo" (star ;~(less lus bar prn)))
246 ! {1 5}
247 ! exit
248```
250---
252## `++pfix`
254Discard first rule
256Parsing composer: connects an `++edge` `vex` with two subsequent `++rule`s,
257ignoring the result of the first and producing the result of the second.
259#### Accepts
261`vex` is an edge.
263#### Produces
265#### Source
267```hoon
268 ++ pfix :: discard first rule
269 ~/ %pfix
270 (comp |*({a/* b/*} b))
271```
273#### Examples
275```
276 > `@t`(scan "%him" ;~(pfix cen sym))
277 'him'
279 > (scan "+++10" ;~(pfix (star lus) dem))
280 q=10
281```
283---
285## `++plug`
287Parse to tuple
289Parsing composer: connects an `++edge` `vex` with a following `++rule` `sab`, producing
290a cell of both the results. See also: the monad applicator ;\~ for a
291more detailed explanation.
293#### Accepts
295`sab` is a `++rule`.
297`vex` is an `++edge`.
299#### Produces
301#### Source
303```hoon
304 ++ plug :: first then second
305 ~/ %plug
306 |* {vex/edge sab/rule}
307 ?~ q.vex
308 vex
309 =+ yit=(sab q.u.q.vex)
310 =+ yur=(last p.vex p.yit)
311 ?~ q.yit
312 [p=yur q=q.yit]
313 [p=yur q=[~ u=[p=[p.u.q.vex p.u.q.yit] q=q.u.q.yit]]]
314 ::
315```
317#### Examples
319```
320 > (scan "1..20" ;~(plug dem dot dot dem))
321 [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]]]
326 > ;;(,[@tas @t ~ %da @da] (scan "moke/~2014.1.1" ;~(plug sym fas nuck:so)))
327 [%moke '/' ~ %da ~2014.1.1]
328```
330---
332## `++pose`
334Parse options
336Parsing composer: if `vex` reflects a failure, connect it with the
337following rule `sab`. See also: the monad applicator ;\~
339#### Accepts
341`sab` is a `++rule`.
343`vex` is an `++edge`.
345#### Produces
347#### Source
349```hoon
350 ++ pose :: first or second
351 ~/ %pose
352 |* {vex/edge sab/rule}
353 ?~ q.vex
354 =+ roq=(sab)
355 [p=(last p.vex p.roq) q=q.roq]
356 vex
357 ::
358```
360#### Examples
362```
363 > `@t`(scan "+" ;~(pose lus tar cen))
364 '+'
366 > `@t`(scan "*" ;~(pose lus tar cen))
367 '*'
369 > `@t`(scan "%" ;~(pose lus tar cen))
370 '%'
372 > `@t`(scan "-" ;~(pose lus tar cen))
373 ! {1 1}
374 ! exit
375```
377---
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.
386#### Accepts
388`a` is the result of parsing the first `++rule`.
390`b` is the result of of parsing the second `++rule`.
392#### Produces
394#### Source
396```hoon
397 ++ sfix :: discard second rule
398 ~/ %sfix
399 (comp |*({a/* b/*} a))
400```
402#### Examples
404```
405 > `@t`(scan "him%" ;~(sfix sym cen))
406 'him'
408 > (scan "10+++" ;~(sfix dem (star lus)))
409 q=10
410```
412---
414## `++simu`
416First and second
418Parsing composer: if an `++edge` `vex` reflects a failure, fail. Otherwise,
419connect `vex` with the following `++rule`.
421#### Accepts
423`sab` is a `++rule`.
425`vex` is an `++edge`.
427#### Produces
429#### Source
431```hoon
432 ++ simu :: first and second
433 |* {vex/edge sab/rule}
434 ?~ q.vex
435 vex
436 =+ roq=(sab)
437 roq
438 ::
439```
441#### Examples
443```
444 > (scan "~zod" scat:vast)
445 [%dtzy p=%p q=0]
447 > (scan "%zod" scat:vast)
448 [%dtzz p=%tas q=6.582.138]
450 > (scan "%zod" ;~(simu cen scat:vast))
451 [%dtzz p=%tas q=6.582.138]
453 > (scan "~zod" ;~(simu cen scat:vast))
454 ! {1 1}
455 ! exit
456```
458---