Tencent/matrix · error
Empty grammar.
Error message
Empty grammar.
What it means
Lemon (the SQLite parser generator, bundled with matrix-sqlite-lint) prints 'Empty grammar.' and exits with status 1 when, after parsing the .y grammar file, no grammar rules were defined (lem.rule==0). The generator cannot build a parser from zero rules, so it aborts before symbol counting. This means the input file either had no '%%' rule section or every rule was excluded by conditional compilation.
Solutions
- Open the .y file and add at least one rule after the %% separator (e.g. `input ::= .;`)
- Check the declarations section: the second %% (start of rules) must be present; add it if missing
- Audit %ifdef/%ifndef blocks around the rule section and ensure at least one branch keeps rules for the current build flags
- Verify you are invoking lemon on the actual grammar file, not an include/tokens file
Example fix
// before (foo.y)
%name Foo
%token_type {int}
%%
// after
%name Foo
%token_type {int}
%%
input ::= expr.
expr ::= INT. Defensive patterns
Strategy: validation
Validate before calling
// shell check before invoking lemon
grep -q '^%%' grammar.y || { echo 'grammar.y has no rules section (missing second %%)'; exit 1; }
after=$(awk '/^%%/{c++} END{print c+0}' grammar.y)
[ "$after" -ge 2 ] && awk 'p;/^%%/{p=1}' grammar.y | grep -vE '^\s*(//.*)?$' | grep -q . && echo OK || { echo 'rules section is empty'; exit 1; } Prevention
- Always end a .y file with a rules section after the second %%
- Add a lint step that asserts at least one production exists before running lemon
- Review %ifdef guards so at least one branch keeps rules
- Run lemon on the actual grammar file, not auxiliary token lists
When it happens
Trigger: Running `lemon foo.y` where foo.y contains no rules after %% (only %name/%token declarations or comments), or all rules were stripped by %ifdef/%ifndef blocks whose condition excluded the entire grammar section.
Common situations: Hand-written .y files where the author stopped after the declarations section and forgot the rules after the second %%; scripted generation of grammars that emits an empty rule section; a %ifdef guard whose macro is undefined so all rules are skipped; wrong file passed to lemon (a header or token list instead of a grammar).
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- parsing conflicts.
- unterminated %%ifdef starting on line
- Unable to allocate memory for a new follow-set propagation…
- Can't find the parser driver template file
- Need zip align apk but the path of zipalign is not…
AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08).
Data as JSON: /api/errors/0662c9a48569ce42.
Report an issue: GitHub.
Appendix: source
Thrown at matrix/matrix-android/matrix-sqlite-lint/src/lemon/lemon-gen/lemon.c:1450
lem.filename = OptArg(0);
lem.basisflag = basisflag;
lem.has_fallback = 0;
lem.nconflict = 0;
lem.name = lem.include = lem.arg = lem.tokentype = lem.start = 0;
lem.vartype = 0;
lem.stacksize = 0;
lem.error = lem.overflow = lem.failure = lem.accept = lem.tokendest =
lem.tokenprefix = lem.outname = lem.extracode = 0;
lem.vardest = 0;
lem.tablesize = 0;
Symbol_new("$");
lem.errsym = Symbol_new("error");
/* Parse the input file */
Parse(&lem);
if( lem.errorcnt ) exit(lem.errorcnt);
if( lem.rule==0 ){
fprintf(stderr,"Empty grammar.\n");
exit(1);
}
/* Count and index the symbols of the grammar */
lem.nsymbol = Symbol_count();
Symbol_new("{default}");
lem.symbols = Symbol_arrayof();
for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i;
qsort(lem.symbols,lem.nsymbol+1,sizeof(struct symbol*),
(int(*)())Symbolcmpp);
for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i;
for(i=1; isupper(lem.symbols[i]->name[0]); i++);
lem.nterminal = i;
/* Generate a reprint of the grammar, if requested on the command line */
if( rpflag ){
Reprint(&lem);
}else{View on GitHub (pinned to 3b8293bd65)