# `Ichor.Conformance`
[🔗](https://github.com/joetjen/ichor/blob/v0.7.0/lib/ichor/conformance.ex#L1)

This implementation's answers to the Ichor Conformance Suite,
through either backend.

The suite runs every Ichor implementation against the same
grammars and inputs, reaching each one through an adapter
(`mix ichor.conformance` here) with a JSON request, and reading a JSON
answer back:

    %{"cases" => [%{"id" => "trees: one number", "operation" => "parse",
                    "grammar" => "/abs/calculator.aether", "text" => "2"}]}
    #=> %{"results" => [%{"id" => "trees: one number", "tree" => ...}]}

**A grammar may be written in any notation Ichor reads** -- Aether,
ABNF, BNF, ISO EBNF, PEG -- told by its extension or an `@style` line,
exactly as `mix ichor.gen` tells it (`Ichor.GrammarImport.styled/2`).
What the suite compares is the parse, so the same language written
twice must come to the same tree.

**It lives here, not in `ichor_runtime`**, because the runtime is only
ever called by generated code: to answer a case, a parser has to be
made from the case's grammar first, and making one is Ichor's.

**The backend is the implementation.** `:interpreted` runs the
grammar through `Grammar.VM`, `Grammar.LR` or `Grammar.GLR`, by its
engine; `:compiled` generates a module with `Ichor.generate_from_grammar/2`
and runs that. The suite configures each as an implementation of its
own, which is what checks that the two agree.

A `"render"` answers `"rendered"`, the first error exactly as
`Ichor.Error.format/1` writes it for a person -- location, message,
the source line and a caret -- or `"tree"` when the text parses.
Word for word: what a person reading an error is given is output, and
every implementation gives the same.

`"pratt"`, `"unify"`, `"solve"` and `"walk"` hold the toolkits to
their cases, through the same standard callbacks every adapter
supplies (`Ichor.Conformance.Toolkits`).

A `"tokens"` answers `"tokens"`, the grammar's token stream for the
text -- every token in order, trivia included, `@keywords` applied, as
`{name, text, line, column}`, an inline literal's token named nil --
or `"error"`, the lexer error's stage, line and column.

A `"lossless"` answers `"tree"`, the lossless tree of the text
(`Ichor.Syntax`) -- a node as `{:rule, name, offset, size, line,
column, children}`, a token as `{:token, name, text, trivia, offset,
line, column}`, an inline literal's token named nil -- or `"error"`, as
a `"parse"` does. Every field is one an implementation computes, so
the offsets are held to the cases as the structure is.

A `"parse"` answers one of:

- `"tree"` -- the default tree, what the parse comes to with no
  actions of its own: a token is its text, a rule with exactly one
  capture matched once is that capture's value, and any other rule is
  `{:node, rule, captures}`, its captures a map from name to value;
- `"error"` -- `%{stage: ..., line: ..., column: ...}` of the first
  error, from reading the grammar, analysing it, or parsing the text.

Both travel as the suite's typed JSON (`{"keyword": "node"}`,
`{"integer": "1"}`, `{"tuple": [...]}`, `{"map": [[k, v], ...]}`), so
nothing tells two values apart differently here than in Praxis.

# `backend`

```elixir
@type backend() :: :interpreted | :compiled
```

Which of this implementation's two backends answers.

# `answer`

```elixir
@spec answer(map(), backend()) :: map()
```

The answer to `request` through `backend`, one result per case, in order.

---

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