.\" lime.1 - manual page for the Lime parser generator .\" Copyright (c) 2024-2026 Lime Parser Generator Project .\" Public Domain .\" .TH LIME 1 "May 2026" "Lime 0.5.1" "User Commands" .SH NAME lime \- LALR(1) parser generator .SH SYNOPSIS .B lime .RI [ options ] .I grammar-file .SH DESCRIPTION .B lime is an LALR(1) parser generator that reads a grammar specification from .I grammar-file and produces C source code implementing a parser for that grammar. It is derived from the Lemon parser generator and generates reentrant, thread-safe parsers with a push-model interface. .PP Unlike yacc and bison which use a pull model (the parser calls the lexer), Lime generates push parsers where the caller feeds tokens to the parser one at a time. The generated parser is contained in a single C source file with no external dependencies beyond the C standard library. .PP The input grammar file uses the .B .lime file extension by convention. Lime produces up to four output files based on the input filename: .TP .IB basename .c The generated C parser source code. .TP .IB basename .h A header file containing token number definitions (\fB#define\fR constants) for use by the lexer. .TP .IB basename .out A report file describing the parser states, conflicts, and actions. Useful for debugging grammar issues. .TP .IB basename .sql An SQL file describing the parser tables (only with .BR \-S ). .SH OPTIONS .TP .B \-b Print only the basis configurations in the report file, omitting derived configurations. This makes the .B .out file shorter and easier to read for large grammars. .TP .B \-c Do not compress the action table. By default, Lime compresses the action table to reduce generated code size. This option disables compression, which may improve parser speed at the cost of larger tables. .TP .BI \-d " directory" Write output files to .I directory instead of the current working directory. .TP .BI \-D " macro" Define a preprocessor macro for use with .B %ifdef directives in the grammar file. Multiple .B \-D options may be given. .IP As a v0.4.0 shorthand, .BI \-Ddialect= NAME is recognized specially: it expands to .BI \-Ddialect_ NAME before the macro table is updated, so a single argument activates any matching .BI %dialect " NAME blocks (see .BR lime_grammar (5)). The .I NAME portion is validated against .BR [A-Za-z_][A-Za-z0-9_]* ; an empty, leading-digit, or non-identifier name produces a diagnostic and a non-zero exit. No umbrella .B dialect macro is defined; only the specific .BI dialect_ NAME name is added. All other .B \-D uses still take a bare macro name. See .B docs/DIALECT.md for the design rules. .TP .B \-E Print the input file after preprocessing .RB ( %ifdef / %ifndef / %endif expansion) and exit. Useful for debugging conditional grammar sections. .TP .B \-F Format the grammar file consistently and write the result to a new file. The formatted file should be reviewed and manually renamed to replace the original. .TP .BI \-f " value" Ignored. Placeholder for passing .B \-f compiler options through build systems. .TP .B \-g Print the grammar without semantic actions and exit. This produces a clean listing of all production rules. .TP .BI \-I " value" Ignored. Placeholder for passing .B \-I compiler options through build systems. .TP .B \-j Generate an AOT-compiled (ahead-of-time) action table in a separate .IB basename _aot.c file. .TP .B \-L Lint mode. Run the opinionated grammar-hygiene linter (E001-E005, W001-W009, M001-M003, plus optional S001-S002 with .BR \-\-lint-style ). Reports errors, warnings, and suggestions, then exits. No .BR .c , .BR .h , or .B .out output files are generated. Exits 0 on a clean grammar (or warnings only); exits 1 if any error fired. With .B \-\-lint-strict warnings also force exit 1. The lint pass runs .I after .BR FindActions() , so conflict-count rules (e.g. W005) have full data. See .B docs/LINT.md for the rule catalog and CI integration recipes. .TP .B \-\-lint-strict Treat lint warnings as errors. With .B \-L this promotes any W- or M- diagnostic to error severity and forces a non-zero exit. Intended for CI. v0.5.0. .TP .B \-\-lint-style Enable the opt-in style suggestions S001 (missing-grammar-doc) and S002 (missing-rule-doc). These are silent without this flag. v0.5.0. .TP .BI \-\-lint-format= format Select the lint output format. .I format is one of .BR human , .BR gcc , or .BR json : .RS .IP \(bu 2 .B human (default) -- pretty stderr lines plus a totals summary. .IP \(bu 2 .B gcc -- .B path:line:col: severity: [code] message on stderr; consumable by emacs/vim/IDE compile-error lists. .IP \(bu 2 .B json -- a top-level array of diagnostics on stdout, with a stable v1 schema (\fIpath\fP, \fIline\fP, \fIcol\fP, \fIseverity\fP, \fIcode\fP, \fImessage\fP, \fIfix\fP). A clean grammar produces exactly .BR []\en . .RE .IP v0.5.0. .TP .B \-l Do not generate .B #line directives in the output C file. By default, Lime inserts .B #line directives so that compiler error messages refer to line numbers in the original grammar file. .TP .B \-m Generate a makeheaders-compatible output file. When this option is given, a separate .B .h header file is not produced; the token definitions are included in the .B .c file in a format compatible with the makeheaders utility. .TP .B \-n Generate snapshot initialization code in a separate .IB basename _snapshot.c file. .TP .BI \-O " value" Ignored. Placeholder for passing .B \-O compiler options through build systems. .TP .B \-p Show conflicts that were resolved by precedence rules. Normally, resolved conflicts are not reported. This option is useful for verifying that precedence declarations have the intended effect. .TP .BI \-P PREFIX Override the parser symbol prefix. By default, the generated parser exports identifiers starting with .B Parse (or the value of the .B %name directive if set in the grammar). .B \-P replaces this prefix at the command line, which is useful when linking multiple generated parsers into the same binary without editing the grammar files. For example, .B "\-PSqlParser" produces .BR SqlParserAlloc() ", " SqlParser() ", " SqlParserFree() ", " and so on. .TP .B \-q Quiet mode. Do not generate the .B .out report file. .TP .B \-r Do not sort or renumber states. By default, Lime reorders states so that states with fewer choices appear at the end, which helps reduce table size. .TP .B \-s Print parser statistics to standard output after generation. The statistics include the number of terminal and non-terminal symbols, rules, states, conflicts, and action table size. .TP .B \-S Generate an .B .sql file describing the parser tables in SQL format. .TP .BI \-T " template-file" Use .I template-file as the parser template instead of the built-in .BR limpar.c . The template contains the runtime parser code with .B %% markers where Lime inserts generated content. .TP .BI \-U " macro" Undefine a preprocessor macro, counteracting a previous .B \-D option or an .B %ifdef that would otherwise match. .TP .B \-V Enable verbose conflict diagnostics with derivation paths. When a conflict is reported, this option shows the chain of productions that leads to the conflict. .TP .BI \-W " value" Ignored. Placeholder for passing .B \-W compiler options through build systems. .TP .B \-x Print the version number and exit. .TP .B \-v Alias for .BR \-x . Print the version number and exit. .TP .BI \-\-diff-conflicts " base.lime ext.lime" Diff the LALR(1) conflict surface of two grammars. Each grammar is compiled in a forked child process (each child gets pristine global state), conflicts are matched by symbolic identity (\fI(reduce_lhs, reduce_rhs, lookahead, kind)\fP for SR; sorted rule-shape pair for RR), and the diff is written to stdout. Designed for the dialect-overlay workflow: prove that adding .I ext.lime to .I base.lime introduces no new shift/reduce or reduce/reduce conflicts. .IP Exit codes are CI-friendly: .RS .IP \(bu 2 .B 0 -- no NEW conflicts; safe to merge. .IP \(bu 2 .B 1 -- NEW conflicts present; review or reject. .IP \(bu 2 .B 2 -- argument or pipeline error (missing file, fork failure, etc.). .RE .IP Not supported on Windows builds (returns exit 2 with a diagnostic). v0.4.3. See .B docs/DIFF_CONFLICTS.md for the symbolic-identity rules and limitations. .TP .B \-\-json With .BR \-\-diff-conflicts , emit machine-readable output: a single JSON object with \fIschema_version\fP, \fIsummary\fP (new / resolved / unchanged / net_change counts), per-NEW and per-RESOLVED records, and an \fIunchanged_count\fP scalar. The schema is documented in .BR docs/DIFF_CONFLICTS.md . v0.4.3. .TP .B \-X Run in lex-compiler mode (lexer subsystem M3 frontend). Reads the input as a .B .lex source file, parses it, resolves .B %pattern interpolations, compiles per-state DFAs, and emits .IR _lex.c " and " _lex.h where .I stem is the input filename without its .B .lex extension. Output goes to the directory specified by .B \-d (default current directory). The generated .B .c + .B .h pair has no Lime runtime dependency -- compile and link with any C code, no library required. See .BR lime_grammar (5) and .B docs/LEXER_DESIGN.md for the .B .lex syntax. .TP .BI \-t " " target " | " \-\-target= target Output target language: either .B c (the default) or .BR rust . With .BR \-\-target=rust , Lime emits a self-contained Rust parser .RI ( .rs ) alongside the C .B .c + .B .h output. Additive: the C output is unchanged. The .B .rs file is a standalone module: no Lime runtime dependency, no Cargo crate dependency, compiles with .B "rustc \-\-crate-type lib" in isolation. The Rust parser supports .BR %fallback , .BR %first_token , .BR "%left / %right / %nonassoc" , .BR %name , and .B %start_symbol transparently. Rust-specific grammar directives .RB ( %rust_action , .BR %rust_extra_argument , .BR %rust_value_type , parse hooks) let action bodies and types diverge from the C side; see .B docs/RUST_OUTPUT.md for the full directive set and worked examples. Short form .B "\-trust" (glued, lime convention) is equivalent to .BR \-\-target=rust ; separate-arg form .B "\-t rust" is also accepted. Available since v0.8.6. .TP .BI \-e " " list " | " \-\-enable= list Enable a comma-separated list of feature toggles. Recognised feature names: .B simd (SIMD-accelerated fast-path scans, default ON), .B memchr (memchr crate dispatch on the Rust side, default OFF), .B per-token-dfa (per-rule DFA dispatch \(em lifts both C and Rust output, default OFF until benched), .B vectorize (C-side SIMD/intrinsic emit, default ON), .B crate (emit a Cargo crate skeleton next to the parser \(em Rust target only, default OFF), and .B nostd (emit .B "#![no_std]" on the .BR .rs , Rust target only, default OFF). Multiple .B \-\-enable= or .B \-\-disable= options may be repeated; later flags override earlier ones. Unknown feature names are a hard error. Rust-only features specified without .B \-\-target=rust print a stderr warning and have no effect. Short form .B "\-esimd,memchr" (glued) and .B "\-e simd,memchr" (separated) both work. Available since v0.8.6. .TP .BI \-\-disable= list Disable a comma-separated list of feature toggles. Same set of names as .BR \-\-enable= . No short form ( .B \-d is taken by the existing .B \-d flag). Available since v0.8.6. .SS Deprecated flags The pre-v0.8.6 spellings continue to function but each prints a one-line stderr warning suggesting the canonical replacement. Existing user scripts keep working unchanged; the deprecation messages are harmless on stdout-focused pipelines. .TP .B \-\-rust Deprecated alias for .BR \-\-target=rust . .TP .B \-\-rust-crate Deprecated alias for .BR "\-\-target=rust \-\-enable=crate" . The older spelling .B \-\-rustcrate (no hyphen) is also accepted with the same warning. .TP .B \-\-rust-nostd Deprecated alias for .BR "\-\-target=rust \-\-enable=nostd" . The older spelling .B \-\-rustnostd (no hyphen) is also accepted with the same warning. With .BR \-\-enable=nostd , the parser .B .rs emits .B "extern crate alloc; use alloc::vec::Vec;" instead of relying on .BR std . The parser still requires the .B alloc crate (Vec for the LALR stack); for true no-std with no allocator the user supplies a no-Vec stack. When combined with .BR \-\-enable=crate , the generated .B lib.rs gets .B "#![no_std]" + .B "extern crate alloc;" at its top. .TP .B \-\-rustlex Deprecated alias for .BR "\-X \-\-target=rust" . With .BR \-X , emit a Rust mirror of the .B .lex tokenizer alongside the C output. The .B .rs contains per-state DFA tables, rule constants, a .B Token struct, a .B LexError enum, and a .B Lexer impl block with .B "tokenize(&mut self, &str) \-> Result, LexError>" . Longest-match DFA simulation in O(input.len()). See .B docs/RUST_OUTPUT.md for the API surface and .B docs/RUST_BENCHMARK.md for performance numbers vs logos / lalrpop / nom / pest / serde_json. .TP .B \-\-rustlex-simd Deprecated alias for .BR "\-\-target=rust \-\-enable=simd" (default since v0.8.6). With the .B simd feature enabled, the lex emitter inlines hand-rolled SIMD intrinsics (SSE2/AVX2 on x86_64, NEON on AArch64, RVV on RISC-V) in fast-path scans. .TP .B \-\-rustlex-memchr Deprecated alias for .BR "\-\-target=rust \-\-enable=memchr" . With the .B memchr feature, fast-path scans dispatch into the memchr(2) crate. Adds .B "memchr = \"2\"" to the generated .B Cargo.toml when used with .BR \-\-enable=crate ; raw .B .rs output gains an .B "extern crate memchr;" so the user must list it. .TP .B \-\-per-token-dfa Deprecated alias for .BR \-\-enable=per-token-dfa . With .B \-X and .BR \-\-enable=per-token-dfa , emit leading-byte dispatch + per-rule DFA tables alongside the unified DFA. Default OFF until benched. .SH GRAMMAR FILE FORMAT A grammar file consists of a sequence of production rules and directives. Rules define the grammar; directives configure parser behavior. .PP Production rules have the form: .PP .RS .EX nonterminal(alias) ::= symbol1(A) symbol2(B). { C code; } .EE .RE .PP The parenthesized aliases are optional and provide names for referencing semantic values in the action code. Each rule is terminated by a period. .PP See .BR lime_grammar (5) for a complete description of the grammar file syntax and all supported directives. .SH EXAMPLES Generate a parser from a grammar file: .PP .RS .EX lime calc.lime .EE .RE .PP This produces .BR calc.c , .BR calc.h , and .BR calc.out . .PP Generate with statistics and no report file: .PP .RS .EX lime -s -q calc.lime .EE .RE .PP Define a macro and specify an output directory: .PP .RS .EX lime -DENABLE_JSON -d build/ grammar.lime .EE .RE .PP Validate a modular grammar without generating output: .PP .RS .EX lime -L grammar.lime .EE .RE .PP Lint with strict warnings, gcc-format errors: .PP .RS .EX lime -L \-\-lint-strict \-\-lint-format=gcc grammar.lime .EE .RE .PP Build a dialect variant via the .BI \-Ddialect= NAME shorthand: .PP .RS .EX lime \-Ddialect=oracle pg_sql.lime .EE .RE .PP Diff the LALR conflict surface between two grammars (CI-friendly, exits 1 on any new conflict): .PP .RS .EX lime \-\-diff-conflicts pg_core.lime pg_oracle.lime lime \-\-diff-conflicts \-\-json pg_core.lime pg_oracle.lime > diff.json .EE .RE .PP Preprocess and display the grammar after macro expansion: .PP .RS .EX lime -E grammar.lime .EE .RE .SH "EXIT STATUS" .TP .B 0 Successful parser generation with no errors or unresolved conflicts. If .B %expect .I N is declared, the exit status is 0 when exactly .I N conflicts are found. For .BR \-L , zero diagnostics fired (or warnings only without .BR \-\-lint-strict ). For .BR \-\-diff-conflicts , no NEW conflicts. .TP .B 1 One or more errors occurred during parsing or code generation, or there are unresolved shift/reduce or reduce/reduce conflicts (unless suppressed by .BR %expect ). For .BR \-L , at least one E- or M- error (or W- with .BR \-\-lint-strict ). For .BR \-\-diff-conflicts , at least one NEW conflict. .TP .B 2 Reserved for .BR \-\-diff-conflicts : argument validation, file-open, or pipeline error (e.g. fork failure, child crash, Windows build where .B \-\-diff-conflicts is stubbed). .SH ENVIRONMENT .TP .B LIME_PATH Colon-separated list of directories searched by .B %extends (after the absolute / current-file-directory probes) and by the template lookup that backs .BR \-T . v0.4.1. .TP .B LIME_JIT Forces JIT-compilation policy at runtime when read by the generated parser binary. Set to .B 1 to force eager compile, or .B 0 to disable. Has no effect on .B lime itself; consumed only by parsers compiled with .BR \-Dllvm=enabled . .TP .B LIME_BIN Used by the runtime extension framework when rebuilding a merged snapshot from a grammar source. Overrides the binary looked up on .BR PATH . .TP .B LIME_CC Used by the runtime extension framework as the C compiler when rebuilding a merged snapshot from a grammar source. Defaults to .BR cc . .TP .B LIME_TEMPLATE Absolute path to a parser template file. Used by .B lime_snapshot_create() and siblings when .B limpar.c is not found in the standard install layout. .TP .B LIME_LIBDIR Absolute path to the directory holding .B limpar.c and .BR snapshot_build.c . Falls back to compiled-in defaults (\fI/usr/local/share/lime/\fP, \fI/usr/share/lime/\fP). .TP .B LIME_SNAPSHOT_BUILD_C Absolute path to .B snapshot_build.c for the runtime grammar-compile pipeline. Override when the default discovery (relative to .BR LIME_LIBDIR ) is wrong. .TP .B TMPDIR Used for scratch files during preprocessing, .BR \-\-diff-conflicts , and the runtime grammar-compile pipeline. Falls back to .B /tmp when unset. .PP The build-time macro .B LIME_STRICT (auto-defined by meson .BR buildtype=debug " / " debugoptimized ) is not an environment variable but affects the binary's behaviour: it promotes .B %remove misses and a handful of other soft warnings to hard errors. See .B docs/EXTENDS.md for the full list. .SH FILES .TP .I limpar.c The default parser template file. Lime searches for this file in the same directory as the .B lime executable unless overridden with .BR \-T . .SH "GENERATED PARSER API" The generated parser provides the following C functions (where .I Parse is replaced by the .B %name directive value, defaulting to \(lqParse\(rq): .TP .BI "void *" Parse "Alloc(void *(*)(size_t));" Allocate and return a new parser instance. The argument is a memory allocation function (typically .BR malloc (3)). .TP .BI "void " Parse "Free(void *, void (*)(void *));" Deallocate a parser instance. The second argument is a deallocation function (typically .BR free (3)). .TP .BI "void " Parse "(void *, int, " TokenType ", " ExtraArg ");" Feed a token to the parser. The second argument is the token code (from the generated .B .h file), and the third is the token's semantic value. The fourth argument is the extra argument declared by .BR %extra_argument . Feed token code 0 to signal end of input. .TP .BI "void " Parse "Trace(FILE *, char *);" Enable parser tracing for debugging. Each trace line is prefixed with the given string. Pass .B NULL to disable tracing. .SH "SEE ALSO" .BR lime_grammar (5), .BR lime_lex (5), .BR lime-lsp (1), .BR yacc (1), .BR bison (1) .PP Further documentation in the source tree: .B docs/DIALECT.md (\fB%dialect\fP), .B docs/EXTENDS.md (\fB%extends\fP / \fB%override\fP / \fB%remove\fP), .B docs/EMBED.md (\fB%embed\fP), .B docs/DIFF_CONFLICTS.md (\fB--diff-conflicts\fP), .B docs/LINT.md (\fB-L\fP rule catalog), .B docs/GLR.md (\fBlime_parse_glr()\fP), .B docs/LSP.md (\fBlime-lsp\fP). .SH AUTHORS The Lemon parser generator was originally written by D. Richard Hipp for the SQLite project. Lime is an extended version of Lemon with support for modular grammars, runtime extensions, and additional code generation features. .SH LICENSE Public Domain. .SH BUGS Report bugs at: .UR https://codeberg.org/gregburd/lime/issues .UE