# `Grammar.LRTable.Sets`
[🔗](https://github.com/joetjen/ichor/blob/v0.3.0/lib/grammar/lr_table/sets.ex#L1)

Standard textbook nullable/FIRST/FOLLOW fixpoint algorithms, over
`Grammar.LRTable.Desugar`'s flat CFG production list rather than the
original PEG IR -- recomputed fresh (not reusing `Grammar.Analysis`'s
own `compute_nullable/1`) since the augmented nonterminal set here
includes every helper nonterminal a `Star`/`Plus`/`Opt`/`Rep`/group
desugared into, which `Grammar.Analysis` never sees.

# `first_sets`

```elixir
@spec first_sets([Grammar.LRTable.Production.t()], MapSet.t(atom())) :: %{
  required(atom()) =&gt; MapSet.t(atom())
}
```

FIRST(N) for every nonterminal N -- FIRST of a terminal is just itself, never stored here.

# `follow_sets`

```elixir
@spec follow_sets(
  [Grammar.LRTable.Production.t()],
  MapSet.t(atom()),
  %{required(atom()) =&gt; MapSet.t(atom())},
  atom(),
  atom()
) :: %{required(atom()) =&gt; MapSet.t(atom())}
```

FOLLOW(N) for every nonterminal N. `start_symbol`'s FOLLOW seeds with
`end_symbol` -- the synthetic end-of-input terminal, never a real token.

# `nullable`

```elixir
@spec nullable([Grammar.LRTable.Production.t()]) :: MapSet.t(atom())
```

Every nonterminal that can derive the empty string.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
