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

Builds an SLR(1) action/goto table (`Grammar.LRTable`, from
`ichor_runtime`) from an `@engine lr`/`@engine glr` grammar -- shared
by both `Grammar.LR` (which additionally requires the result be
conflict-free) and `Grammar.GLR` (which accepts conflicts and forks
over them at runtime).

Pipeline: `Grammar.LRTable.Desugar` flattens `grammar.rules`' PEG-shaped
IR into a flat CFG production list; `Grammar.LRTable.Sets` computes
nullable/FIRST/FOLLOW over that list; `Grammar.LRTable.Automaton` builds
the canonical LR(0) item-set collection and, on top of it, the SLR(1)
action/goto tables. `build/1` never itself decides a conflict is
fatal -- a cell with more than one action is simply present in
`action` as a list of length > 1; it's each engine's own call whether
that's acceptable.

Dev-time-only: nothing here runs once a grammar's table has already
been built (or generated code compiled from it) -- that's
`Grammar.LRTable` itself, the one piece of this pipeline that ships in
`ichor_runtime`.

# `build`

```elixir
@spec build(Aether.Grammar.t()) ::
  {:ok, Grammar.LRTable.t()} | {:error, [Ichor.Error.t()]}
```

Builds the SLR(1) table for `grammar`, or every unsupported-construct error found.

# `conflicts`

```elixir
@spec conflicts(Grammar.LRTable.t()) :: [
  {Grammar.LRTable.state_id(), atom(), [Grammar.LRTable.action()]}
]
```

Every `{state, symbol, [actions]}` cell with more than one action -- a shift/reduce or reduce/reduce conflict.

---

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