# 4e: Parsing (Combinators)

## `+bend` <a href="#bend" id="bend"></a>

Conditional composer.

Parsing composer: connects the `$edge` `.vex` with the subsequent `$rule` `.sab` as an optional suffix, using gate `.raq` to compose or reject its result. If there is no suffix, or if the suffix fails to be composed with the current result, the current result is produced. Used to map a group of `$rule`s to a specified output.

#### Accepts

`.raq` is a gate.

`.sab` is a rule.

`.vex` is an edge.

#### Produces

A `$rule`.

#### Source

```hoon
++  bend
  ~/  %bend
  =+  raq=|*([a=* b=*] [~ u=[a b]])
  |@
  ++  $
    ~/  %fun
    |*  [vex=edge sab=rule]
    ?~  q.vex
      vex
    =+  yit=(sab q.u.q.vex)
    =+  yur=(last p.vex p.yit)
    ?~  q.yit
      [p=yur q=q.vex]
    =+  vux=(raq p.u.q.vex p.u.q.yit)
    ?~  vux
      [p=yur q=q.vex]
    [p=yur q=[~ u=[p=u.vux q=q.u.q.yit]]]
  --
```

#### Examples

```
> (;~((bend |=([a=char b=char] ?.(=(a b) ~ (some +(a))))) prn prn) [1 1] "qs")
[p=[p=1 q=3] q=[~ u=[p=113 q=[p=[p=1 q=2] q="s"]]]]
```

```
> (;~((bend |=([a=char b=char] ?.(=(a b) ~ (some +(a))))) prn prn) [1 1] "qqq")
[p=[p=1 q=3] q=[~ u=[p=114 q=[p=[p=1 q=3] q="q"]]]]
```

```
> `@t`(scan "aa" ;~((bend |=([a=char b=char] ?.(=(a b) ~ (some +(a))))) prn prn))
'b'
```

```
> (scan "ba" ;~((bend |=([a=char b=char] ?.(=(a b) ~ (some +(a))))) prn prn))
{1 3}
syntax error
```

```
> `(unit @tas)`(scan "" ;~((bend) (easy ~) sym))
~
```

```
> `(unit @tas)`(scan "sep" ;~((bend) (easy ~) sym))
[~ %sep]
```

***

## `+comp` <a href="#comp" id="comp"></a>

Arbitrary compose.

Parsing composer: connects the `$edge` `.vex` with a following `$rule` `.sab`, combining the contents of `.vex` with the result of `.sab` using a binary gate `.raq`. Used to fold over the results of several `$rule`s.

#### Accepts

`.raq` is a gate that accepts a cell of two `$noun`s, `.a` and `.b`, and produces a cell of two `$noun`s.

`.vex` is an edge.

`.sab` is a rule.

#### Produces

A `$rule`.

#### Source

```hoon
++  comp
  ~/  %comp
  =+  raq=|*([a=* b=*] [a b])
  |@
  ++  $
    ~/  %fun
    |*  [vex=edge sab=rule]
    ~!  +<
    ?~  q.vex
      vex
    =+  yit=(sab q.u.q.vex)
    =+  yur=(last p.vex p.yit)
    ?~  q.yit
      [p=yur q=q.yit]
    [p=yur q=[~ u=[p=(raq p.u.q.vex p.u.q.yit) q=q.u.q.yit]]]
  --
```

#### Examples

```
> (scan "123" ;~((comp |=([a=@ud b=@ud] (add a b))) dit dit dit))
6
```

```
> (scan "12" ;~((comp |=([a=@ud b=@ud] (add a b))) dit dit dit))
{1 3}
syntax error
```

***

## `+fail` <a href="#fail" id="fail"></a>

Never parse.

Produces an `$edge` at the same text position (`$hair`) with a failing result (`q=~`).

#### Accepts

`.tub` is a `$nail`.

#### Produces

An `$edge`.

#### Source

```hoon
++  fail  |=(tub=nail [p=p.tub q=~])
```

#### Examples

```
> (fail [[1 1] "abc"])
[p=[p=1 q=1] q=~]
```

```
> (fail [[p=1.337 q=70] "Parse me, please?"])
[p=[p=1.337 q=70] q=~]
```

***

## `+glue` <a href="#glue" id="glue"></a>

Skip delimiter.

Parsing composer: connects an `$edge` `.vex` with a following `$rule` `.sab` by parsing the `$rule` `.bus` (the delimiting symbol) and throwing out the result.

#### Accepts

`.bus` is a `$rule`.

`.vex` is an `$edge`.

`.sab` is a `$rule`.

#### Produces

A `$rule`.

#### Source

```hoon
++  glue
  ~/  %glue
  |*  bus=rule
  ~/  %fun
  |*  [vex=edge sab=rule]
  (plug vex ;~(pfix bus sab))
```

#### Examples

```
> `[@ud @tas @tas]`(scan "200|mal|bon" ;~((glue bar) dem sym sym))
[200 %mal %bon]
```

```
> `[@ud @t @tas]`(scan "200|;|bon" ;~((glue bar) dem mic sym))
[200 ';' %bon]
```

***

## `+less` <a href="#less" id="less"></a>

Parse unless.

Parsing composer: if an `$edge` `.vex` reflects a success, fail. Otherwise, connect `.vex` with the following `$rule`.

#### Accepts

`.vex` is an `$edge`.

`.sab` is a `$rule`.

#### Produces

An `$edge`.

#### Source

```hoon
++  less
  |*  [vex=edge sab=rule]
  ?~  q.vex
    =+  roq=(sab)
    [p=(last p.vex p.roq) q=q.roq]
  (fail +<.sab)
```

#### Examples

```
> (scan "sas-/lo" (star ;~(less lus bar prn)))
"sas-/lo"
```

```
> (scan "sas-/l+o" (star ;~(less lus bar prn)))
! {1 8}
! exit
```

```
> (scan "sas|-/lo" (star ;~(less lus bar prn)))
! {1 5}
! exit
```

***

## `+pfix` <a href="#pfix" id="pfix"></a>

Discard first rule.

Parsing composer: connects an `$edge` `.vex` with two subsequent `$rule`s, ignoring the result of the first and producing the result of the second.

#### Accepts

`.vex` is an `$edge`.

`.sab` is a `$rule`.

#### Produces

An `$edge`.

#### Source

```hoon
++  pfix
  ~/  %pfix
  |*  sam=[vex=edge sab=rule]
  %.  sam
  (comp |*([a=* b=*] b))
```

#### Examples

```
> `@t`(scan "%him" ;~(pfix cen sym))
'him'
```

```
> (scan "+++10" ;~(pfix (star lus) dem))
10
```

***

## `+plug` <a href="#plug" id="plug"></a>

Parse to tuple.

Parsing composer: connects an `$edge` `.vex` with a following `$rule` `.sab`, producing a cell of both the results. See also: the monad applicator `;~` for a more detailed explanation.

#### Accepts

`.vex` is an `$edge`.

`.sab` is a `$rule`.

#### Produces

An `$edge`.

#### Source

```hoon
++  plug
  ~/  %plug
  |*  [vex=edge sab=rule]
  ?~  q.vex
    vex
  =+  yit=(sab q.u.q.vex)
  =+  yur=(last p.vex p.yit)
  ?~  q.yit
    [p=yur q=q.yit]
  [p=yur q=[~ u=[p=[p.u.q.vex p.u.q.yit] q=q.u.q.yit]]]
```

#### Examples

```
> (scan "1..20" ;~(plug dem dot dot dem))
[1 '.' '.' 20]
```

***

## `+pose` <a href="#pose" id="pose"></a>

Parse options.

Parsing composer: if `.vex` reflects a failure, connect it with the following `$rule` `.sab`. See also: the monad applicator `;~`

#### Accepts

`.vex` is an `$edge`.

`.sab` is a `$rule`.

#### Produces

An `$edge`.

#### Source

```hoon
++  pose
  ~/  %pose
  |*  [vex=edge sab=rule]
  ?~  q.vex
    =+  roq=(sab)
    [p=(last p.vex p.roq) q=q.roq]
  vex
```

#### Examples

```
> `@t`(scan "+" ;~(pose lus tar cen))
'+'
```

```
> `@t`(scan "*" ;~(pose lus tar cen))
'*'
```

```
> `@t`(scan "%" ;~(pose lus tar cen))
'%'
```

```
> `@t`(scan "-" ;~(pose lus tar cen))
! {1 1}
! exit
```

***

## `+sfix` <a href="#sfix" id="sfix"></a>

Discard second rule.

Parsing composer: connects `$edge` `.vex` with two subsequent `$rule`s returning the result of the first and discarding the result of the second.

#### Accepts

`.vex` is an `$edge`.

`.sab` is a `$rule`.

#### Produces

An `$edge`.

#### Source

```hoon
++  sfix
  ~/  %sfix
  |*  sam=[vex=edge sab=rule]
  %.  sam
  (comp |*([a=* b=*] a))
```

#### Examples

```
> `@t`(scan "him%" ;~(sfix sym cen))
'him'
```

```
> (scan "10+++" ;~(sfix dem (star lus)))
q=10
```

***

## `+simu` <a href="#simu" id="simu"></a>

First and second.

Parsing composer: if an `$edge` `.vex` reflects a failure, fail. Otherwise, connect `.vex` with the following `$rule`.

#### Accepts

`.vex` is an `$edge`.

`.sab` is a `$rule`.

#### Produces

An `$edge`.

#### Source

```hoon
++  simu
  |*  [vex=edge sab=rule]
  ?~  q.vex
    vex
  =+  roq=(sab)
  roq
```

#### Examples

```
> (scan "~zod" scat:vast)
[%dtzy p=%p q=0]
```

```
> (scan "%zod" scat:vast)
[%dtzz p=%tas q=6.582.138]
```

```
> (scan "%zod" ;~(simu cen scat:vast))
[%dtzz p=%tas q=6.582.138]
```

```
> (scan "~zod" ;~(simu cen scat:vast))
! {1 1}
! exit
```

***


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.urbit.org/hoon/stdlib/4e.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
