Composition
GBNF
offers mechanisms for concisely writing new GBNF grammars.
(This does not cover the specifics of writing GBNF; for that, view the original spec in llama.cpp.)
g
template tag
GBNF
offers a g
template tag for writing rules:
GBNF
handles rule names automatically. The root rule is automatically root
.
Rules can be defined separately and included:
Rules don’t have to be explicitly defined as variables to be included; you can also define them inline:
GBNF
automatically finds duplicate rules and combines them.
Explicit rule keys
Sometimes a rule needs explicit name (for example, if it recursively references itself). You can define a custom rule name with key
:
Whitespace
Multiple whitespaces automatically resolve to a single whitespace:
This enables fluid formatting of complicated GBNF definitions.
If you need to maintain whitespace, use raw
:
Arrays
Arrays are automatically joined into whitespace-separated definitions:
Alternatively, you can specify the separator for an array with join
:
Joins apply to all arrays contained within a rule. If you need different behavior per array, wrap each array in its own rule.
Arrays can also contain rules:
Undefined, null, and booleans
undefined
, null
, and boolean
values are all ignored:
Wrap
You can wrap a rule with parantheses, which affects rule execution order
You can manually wrap a rule yourself, or you can leverage .wrap()
:
You can also provide a modifier for a wrapped rule:
Modifiers can be:
?
- optional*
- repeated invocations, 0 or more+
- repeated invocations, 1 or more
Extending template tags
You can provide your own grammar builders that implement custom grammar logic.
As an example, consider the StringRule
that handles string case from the sql2gbnf
package. SQL can support both lowercase and uppercase words, and we want to provide an option for our users to decide the case at runtime:
SELECT * FROM table; -- this is valid
select * from table; -- this is also valid
SeLeCt * FrOm table; -- even this is valid!
To implement this rule, we:
- Define our arguments -
caseKind
- Implement
toString()
to determine what comes out
We want to provide a rule that enables the case of the string to be set at runtime. The below implements the behavior: