@@ -139,21 +139,6 @@ Maybe mention this from `/app/shoe.hoon` as well?
139|~(nail *(like [? command]))
139|~(nail *(like [? command]))
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) ~] ::
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
158## Parser builders
143## Parser builders
@@ -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"]]]]
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.
248## Outside callers
239## Outside callers
@@ -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.
336−The syntax to combine parsers (chain them together) is
328+The syntax to combine `rule`s is
338−;~(combinator rule-1 rule-2 ... rule-n)
330+;~(combinator [list rule])
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
373+Understanding the rune `;~` is essential to building parsers with Hoon. Let's
374+take this opportunity to think about it carefully.
376+The `rule` created by `;~(combinator [list rule])`
378+> (scan "star" ;~(plug (jest 'star')))
381## Parsing atoms
383## Parsing atoms
@@ -403,7 +405,36 @@ for parsing decimal numbers.
404## Other parsing tidbits
406## Other parsing tidbits
406−Need to mention `cold`
408+Need to mention `cold`, `like`
410+### Recursive parsers
412+Naively attempting to write a recursive `rule`, i.e. like
414+> |-(;~(pose den ;~(pose $ (easy ~))))
416+results in an error, as the compiler will attempt to build an infinite function.
422+Thus some special sauce is required, the `+knee` function.
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:
430+|-(;~(plug prn ;~(pose (knee *tape |.(^$)) (easy ~))))
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.
408## Parsing arithmetic expressions
439## Parsing arithmetic expressions