on master help sign in
recursive parsers
3bfa12aJONATHAN PAPROCKI
tutorials/arvo/parsing.md+50−19
@@ -139,21 +139,6 @@ Maybe mention this from `/app/shoe.hoon` as well?
139|~(nail *(like [? command]))
139|~(nail *(like [? command]))
140```
140```
141
141
142−```hoon
143−++ edge {p/hair q/(unit {p/* q/nail})} :: parsing output
144−++ hair {p/@ud q/@ud} :: parsing trace
145−++ like |* a/$-(* *) :: generic edge
146− |: b=`*`[(hair) ~] ::
147− :- p=(hair -.b) ::
148− ^= q ::
149− ?@ +.b ~ ::
150− :- ~ ::
151− u=[p=(a +>-.b) q=[p=(hair -.b) q=(tape +.b)]] ::
152−++ nail {p/hair q/tape} :: parsing input
153−++ pint {p/{p/@ q/@} q/{p/@ q/@}} :: line+column range
154−++ rule _|:($:nail $:edge) :: parsing rule
155−++ spot {p/path q/pint} :: range in file
156−```
157
142
158## Parser builders
143## Parser builders
159
144
@@ -244,6 +229,12 @@ and returns a `rule`.
244[p=[p=1 q=2] q=[~ [p='a' q=[p=[p=1 q=2] q="bc"]]]]
229[p=[p=1 q=2] q=[~ [p='a' q=[p=[p=1 q=2] q="bc"]]]]
245```
230```
246
231
232+### `+knee`
233+
234+Another important function in the parser builder library is `+knee`, used for building
235+recursive parsers. We delay discussion of `+knee` to the
236+[section below](#recursive-parsers) as more context is needed to explain it properly.
237+
247
238
248## Outside callers
239## Outside callers
249
240
@@ -331,11 +322,12 @@ ASCII glyphs have counterparts of this sort, documented
331Building complex parsers from simpler parsers is accomplished in Hoon with the
322Building complex parsers from simpler parsers is accomplished in Hoon with the
332use of two tools: the monadic applicator rune
323use of two tools: the monadic applicator rune
333[`;~`](@/docs/reference/hoon-expressions/rune/mic.md#micsig) and [parsing
324[`;~`](@/docs/reference/hoon-expressions/rune/mic.md#micsig) and [parsing
334−combinators](@/docs/reference/library/4e.md).
325+combinators](@/docs/reference/library/4e.md). First we introduce a few
326+combinators, then we examine more closely how `;~` is used to chain them together.
335
327
336−The syntax to combine parsers (chain them together) is
328+The syntax to combine `rule`s is
337```hoon
329```hoon
338−;~(combinator rule-1 rule-2 ... rule-n)
330+;~(combinator [list rule])
339```
331```
340The `rule`s are composed together using the combinator as an
332The `rule`s are composed together using the combinator as an
341intermediate function, which takes product of a `rule` (an `edge`) and a `rule` and turns
333intermediate function, which takes product of a `rule` (an `edge`) and a `rule` and turns
@@ -376,6 +368,16 @@ results of each `rule`.
376syntax error
368syntax error
377```
369```
378
370
371+### `;~`
372+
373+Understanding the rune `;~` is essential to building parsers with Hoon. Let's
374+take this opportunity to think about it carefully.
375+
376+The `rule` created by `;~(combinator [list rule])`
377+```
378+> (scan "star" ;~(plug (jest 'star')))
379+'star'
380+```
379
381
380
382
381## Parsing atoms
383## Parsing atoms
@@ -403,7 +405,36 @@ for parsing decimal numbers.
403
405
404## Other parsing tidbits
406## Other parsing tidbits
405
407
406−Need to mention `cold`
408+Need to mention `cold`, `like`
409+
410+### Recursive parsers
411+
412+Naively attempting to write a recursive `rule`, i.e. like
413+```
414+> |-(;~(pose den ;~(pose $ (easy ~))))
415+```
416+results in an error, as the compiler will attempt to build an infinite function.
417+```
418+-find.,.+6
419+-find.,.+6
420+rest-loop
421+```
422+Thus some special sauce is required, the `+knee` function.
423+
424+`+knee` takes in a noun that is the default value of the parser, typically given
425+as the bunt value of the type that the `rule` produces, as well as a gate that
426+accepts a `rule`. `+knee` produces a `rule` that implements any recursive calls
427+in the `rule` in a manner acceptable to the compiler. Thus the preferred manner
428+to write the above `rule` is as follows:
429+```hoon
430+|-(;~(plug prn ;~(pose (knee *tape |.(^$)) (easy ~))))
431+```
432+
433+You may want to utilize the `~+` rune when writing recursive parsers to cache
434+the results as you go to improve performance. In [parsing arithmetic
435+expressions](#parsing-arithmetic-expressions) we will be writing a recursive
436+parser making use of `+knee` and `~+` throughout.
437+
407
438
408## Parsing arithmetic expressions
439## Parsing arithmetic expressions
409
440