on 30aa030 help sign in
466 lines 6.8 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
33 ~/ %bend
34 =+ raq=|*([a=* b=*] [~ u=[a b]])
35 |@
36 ++ $
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 --
50```
52#### Examples
54```
55> (;~((bend |=([a=char b=char] ?.(=(a b) ~ (some +(a))))) prn prn) [1 1] "qs")
56[p=[p=1 q=3] q=[~ u=[p=113 q=[p=[p=1 q=2] q="s"]]]]
58> (;~((bend |=([a=char b=char] ?.(=(a b) ~ (some +(a))))) prn prn) [1 1] "qqq")
59[p=[p=1 q=3] q=[~ u=[p=114 q=[p=[p=1 q=3] q="q"]]]]
61> `@t`(scan "aa" ;~((bend |=([a=char b=char] ?.(=(a b) ~ (some +(a))))) prn prn))
62'b'
64> (scan "ba" ;~((bend |=([a=char b=char] ?.(=(a b) ~ (some +(a))))) prn prn))
65{1 3}
66syntax error
68> `(unit @tas)`(scan "" ;~((bend) (easy ~) sym))
71> `(unit @tas)`(scan "sep" ;~((bend) (easy ~) sym))
72[~ %sep]
73```
75---
77## `++comp`
79Arbitrary compose
81Parsing composer: connects the `edge` `vex` with a following `rule` `sab`,
82combining the contents of `vex` with the result of `sab` using a binary
83gate `raq`. Used to fold over the results of several `rule`s.
85#### Accepts
87`raq` is a gate that accepts a cell of two nouns, `a` and `b`, and
88produces a cell of two nouns.
90`vex` is an edge.
92`sab` is a rule.
94#### Produces
96A `rule`.
98#### Source
100```hoon
101++ comp
102 ~/ %comp
103 =+ raq=|*([a=* b=*] [a b])
104 |@
105 ++ $
106 ~/ %fun
107 |* [vex=edge sab=rule]
108 ~! +<
109 ?~ q.vex
110 vex
111 =+ yit=(sab q.u.q.vex)
112 =+ yur=(last p.vex p.yit)
113 ?~ q.yit
114 [p=yur q=q.yit]
115 [p=yur q=[~ u=[p=(raq p.u.q.vex p.u.q.yit) q=q.u.q.yit]]]
116 --
117```
119#### Examples
121```
122> (scan "123" ;~((comp |=([a=@ud b=@ud] (add a b))) dit dit dit))
125> (scan "12" ;~((comp |=([a=@ud b=@ud] (add a b))) dit dit dit))
126{1 3}
127syntax error
128```
130---
132## `++fail`
134Never parse
136Produces an `edge` at the same text position (`hair`) with a failing
137result (`q=~`).
139#### Accepts
141`tub` is a `nail`.
143#### Produces
145An `edge`.
147#### Source
149```hoon
150++ fail |=(tub=nail [p=p.tub q=~])
151```
153#### Examples
155```
156> (fail [[1 1] "abc"])
157[p=[p=1 q=1] q=~]
159> (fail [[p=1.337 q=70] "Parse me, please?"])
160[p=[p=1.337 q=70] q=~]
161```
163---
165## `++glue`
167Skip delimiter
169Parsing composer: connects an `edge` `vex` with a following `rule` `sab` by
170parsing the `rule` `bus` (the delimiting symbol) and throwing out the
171result.
173#### Accepts
175`bus` is a `rule`.
177`vex` is an `edge`.
179`sab` is a `rule`.
181#### Produces
183A `rule`.
185#### Source
187```hoon
188++ glue
189 ~/ %glue
190 |* bus=rule
191 ~/ %fun
192 |* [vex=edge sab=rule]
193 (plug vex ;~(pfix bus sab))
194```
196#### Examples
198```
199> `[@ud @tas @tas]`(scan "200|mal|bon" ;~((glue bar) dem sym sym))
200[200 %mal %bon]
202> `[@ud @t @tas]`(scan "200|;|bon" ;~((glue bar) dem mic sym))
203[200 ';' %bon]
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`vex` is an `edge`.
219`sab` is a `rule`.
221#### Produces
223An `edge`.
225#### Source
227```hoon
228++ less
229 |* [vex=edge sab=rule]
230 ?~ q.vex
231 =+ roq=(sab)
232 [p=(last p.vex p.roq) q=q.roq]
233 (fail +<.sab)
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```
251---
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`sab` is a `rule`.
266#### Produces
268An `edge`.
270#### Source
272```hoon
273++ pfix
274 ~/ %pfix
275 |* sam=[vex=edge sab=rule]
276 %. sam
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))
28710
288```
290---
292## `++plug`
294Parse to tuple
296Parsing composer: connects an `edge` `vex` with a following `rule` `sab`,
297producing a cell of both the results. See also: the monad applicator `;~` for a
298more detailed explanation.
300#### Accepts
302`vex` is an `edge`.
304`sab` is a `rule`.
306#### Produces
308An `edge`.
310#### Source
312```hoon
313++ plug
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```
325#### Examples
327```
328> (scan "1..20" ;~(plug dem dot dot dem))
329[1 '.' '.' 20]
330```
332---
334## `++pose`
336Parse options
338Parsing composer: if `vex` reflects a failure, connect it with the
339following rule `sab`. See also: the monad applicator `;~`
341#### Accepts
343`vex` is an `edge`.
345`sab` is a `rule`.
347#### Produces
349An `edge`.
351#### Source
353```hoon
354++ pose
355 ~/ %pose
356 |* [vex=edge sab=rule]
357 ?~ q.vex
358 =+ roq=(sab)
359 [p=(last p.vex p.roq) q=q.roq]
360 vex
361```
363#### Examples
365```
366> `@t`(scan "+" ;~(pose lus tar cen))
367'+'
369> `@t`(scan "*" ;~(pose lus tar cen))
370'*'
372> `@t`(scan "%" ;~(pose lus tar cen))
373'%'
375> `@t`(scan "-" ;~(pose lus tar cen))
376! {1 1}
377! exit
378```
380---
382## `++sfix`
384Discard second rule
386Parsing composer: connects `edge` `vex` with two subsequent `rule`s returning the
387result of the first and discarding the result of the second.
389#### Accepts
391`vex` is an `edge`.
393`sab` is a `rule`.
395#### Produces
397An `edge`.
399#### Source
401```hoon
402++ sfix
403 ~/ %sfix
404 |* sam=[vex=edge sab=rule]
405 %. sam
406 (comp |*([a=* b=*] a))
407```
409#### Examples
411```
412> `@t`(scan "him%" ;~(sfix sym cen))
413'him'
415> (scan "10+++" ;~(sfix dem (star lus)))
416q=10
417```
419---
421## `++simu`
423First and second
425Parsing composer: if an `edge` `vex` reflects a failure, fail. Otherwise,
426connect `vex` with the following `rule`.
428#### Accepts
430`vex` is an `edge`.
432`sab` is a `rule`.
434#### Produces
436An `edge`.
438#### Source
440```hoon
441++ simu
442 |* [vex=edge sab=rule]
443 ?~ q.vex
444 vex
445 =+ roq=(sab)
446 roq
447```
449#### Examples
451```
452> (scan "~zod" scat:vast)
453[%dtzy p=%p q=0]
455> (scan "%zod" scat:vast)
456[%dtzz p=%tas q=6.582.138]
458> (scan "%zod" ;~(simu cen scat:vast))
459[%dtzz p=%tas q=6.582.138]
461> (scan "~zod" ;~(simu cen scat:vast))
462! {1 1}
463! exit
464```
466---