Frequently asked questions #
Short answers, including the unflattering ones. If something here is wrong or missing, that's worth an issue.
The basics #
- What is tabnas?
- A parsing engine you extend rather than replace. A grammar is data — a table of rules and token alternates the engine walks at runtime — so a new language is usually rules added to one that already parses. The long version is on why tabnas.
- Why does it exist?
- Writing a parser is expensive, so most formats never get a good one. Two things make it cheaper here: extension is the normal case instead of a fork, and the grammar is plain enough data that a language model can write it. See agents.
- What does the name mean?
- Tábla na nAistrithe — Irish for "a table of translations", which is what the engine walks.
- Is it ready to use?
- It works, and 28 packages are published — but everything is pre-1.0. Minor versions can break things, and grammar packages track the engine release they were built against. Pin exact versions. Per-repo CI and publish state is on the status page.
- What's the licence?
- MIT, across every repository in the org.
Using it #
- Do I have to write ABNF?
- No. There are three levels, and they produce the same thing: ABNF when a person is writing, a declarative rule table when an agent is, and a programmatic API for parameterised grammars — the level expr and directive are built at. The playground takes the first two.
- Can I connect an agent without installing anything?
-
Yes, but installing is better.
npx --yes @tabnas/mcp mcpruns the MCP server locally and is the supported path — free, private, unlimited, and reproducible. For clients that cannot spawn a process, the same tools are served over streamable HTTP atmcp.tabnas.dev/mcp. It is bounded (a body cap and a per-IP rate limit, both stated by its/.well-known/mcp), and it keeps nothing: see privacy. Both answer byte-for-byte identically, because there is one implementation behind them. - Do I have to write a lexer?
-
Mostly, yes. tabnas draws a hard line between lexing and parsing and
is really about the parsing half. It gives you tools — matchers,
fixed tokens, built-ins like
NR— but you assemble them. Lexing is the easy and boring part. - Can it handle ambiguous grammars?
- No. The engine is deterministic and does not backtrack. If you need every valid parse of an ambiguous input, an Earley or GLR parser is the right tool — other parsers covers when to reach for one.
- What about left recursion?
-
Accepted, but rewritten rather than natively supported. The ABNF
compiler applies Paull's
algorithm, so
P = P a / bbecomesP = b *(a). The resulting tree is flat rather than left-nested, and a purely left-recursive rule with no base branch is an error. - How do I extend an existing grammar?
- Add rules and token alternates to it. That's the whole mechanism, and it's how the packages are built: JSON is a handful of rules, JSONC adds comments, jsonic relaxes the quoting. See extending a grammar.
- My action never fires. Why?
-
Probably the mark name. An
@refalternate mark comes from the alternate's leading discriminator, which the compiler assigns — so ask it rather than guessing:tabnas-abnf --marks -f grammar.abnf. ABNF also desugars[ … ]and( … )into generated group rules, so a rule'sparentat runtime is often one of those. - How fast is it?
- Unmeasured, publicly. The design is a for-loop over tokens with a lookup table and no backtracking, which is a fast shape — but there are no published benchmarks, so treat any claim, including that one, as unproven until there are.
Scope #
Saying no is part of describing a project. These are deliberate; arguing for them is welcome, but the current answer is no.
- What can it actually parse?
- Real languages, not just config formats. The strongest evidence is @tabnas/c, which parses C source into a concrete syntax tree — preserving every token, comment, macro definition, macro use and compiler extension as written. There is also a Protocol Buffers IDL parser (proto2, proto3, editions 2023/2024), and CSS, Markdown and XML. Beyond the org, boru is a complete programming language — types, macros, an LSP — with its whole front end on this engine.
- The limits are shape rather than size: the grammar has to be deterministic. Ambiguity is the thing it can't do — not complexity, and not lookahead depth.
- Is there a hosted service?
- No, and there's nothing to host. tabnas is a library that runs in your process. No account, no API key, no paid tier.
- Does it generate parser code?
- No. Generating source would give back the drift problem the engine exists to avoid — grammars stay data, interpreted at runtime. It also means you can inspect a grammar while it runs, print it back as ABNF, or draw it.
- Which runtimes?
- TypeScript and Go. TypeScript is the reference implementation; the Go port tracks it and runs the same fixtures, so a grammar behaves the same in both.
- Is there an MCP server, or a grammar catalog?
- Not yet, and neither is promised. Both are under discussion in Discussions, which is where the argument about how they should work is happening.
The project #
- Who makes it?
- Richard Rodger, who also wrote Seneca and jsonic — which is where tabnas came from. Development is sponsored by Voxgig; see sponsors.
- Is anyone using it?
- Yes — examples covers two real languages built on the engine, one in TypeScript and one in Go. Beyond that it's early, and pretending otherwise wouldn't help you.
- Can I contribute with an AI agent?
-
Yes, and you don't have to disclose it. Every package repository
ships an
AGENTS.md, and the shared fixtures mean a change that doesn't actually work fails loudly. See community. - What would help most?
- Roughly in order: a grammar for a format you actually use, a failing fixture for something that parses wrongly, and documentation for the parts you found hard. There are 17 language grammars so far, most of them extensions of another.