litex is a small pattern language and CLI that compiles readable .lx rules into regular expressions.
It is built for cases where raw regex is too dense to write or review directly, but you still want regex-compatible matching, captures, search, and replacement.
- Defines patterns in a whitespace-oriented DSL.
- Compiles
.lxsource to a Go regular expression. - Supports reusable variables, named captures, alternation, classes, quantifiers, and builtin patterns.
- Exposes a CLI for compile, find, find-all, test, and replace workflows.
- Includes a
tree-sittergrammar intree-sitter-lxfor editor integration.
main.go: CLI entry point.engine: lexer, parser, resolver, compiler, and builtins.tree-sitter-lx: Tree-sitter grammar for.lxfiles.engine/builtin: built-in.lxpatterns and the compiled regex registry.
Requirements:
- Go 1.21.4+.
Run without installing:
go run . helpBuild a local binary:
go build -o lx .
./lx helplx compile [-f pattern.lx | <pattern>] [--name=value ...]
lx find [-f pattern.lx | <pattern>] [-f content.txt | <content>] [--name=value ...]
lx findall [-f pattern.lx | <pattern>] [-f content.txt | <content>] [--name=value ...]
lx test [-f pattern.lx | <pattern>] [-f content.txt | <content>] [--name=value ...]
lx replace [-f pattern.lx | <pattern>] <replacement> [-f content.txt | <content>] [--name=value ...]
Notes:
- Inline patterns are treated as the body of
pattern:automatically. - Use
-fwhen you want to pass a full.lxsource file as-is. - Content can be inline text or loaded from a file with
-f. replaceallis also implemented even though it is not listed inhelp.
Compile an inline pattern:
go run . compile 'digit 4 "-" digit 4'Test whether text matches:
go run . test 'digit 4' 1234Find all matches:
go run . findall '@email' 'a@b.com x y@test.dev'Compile a file-backed pattern:
go run . compile -f engine/builtin/email.lxUse a required CLI variable from a file-backed pattern:
go run . test -f pattern.lx hello --value=helloAn .lx program has two parts:
- Optional variable definitions at the top.
- A required
pattern:section.
Minimal file:
pattern:
digit 4
Variables:
$sep = ("-" | whitespace)
pattern:
digit 4
$sep 0..1
digit 4
Required CLI variables:
$value = require value
pattern:
$value
Run it with:
go run . test -f pattern.lx hello --value=helloCaptures:
pattern:
UserId {
letter 2..4
digit 3
}
Alternation and grouping:
pattern:
("yes" | "no" | "maybe")
Character classes:
pattern:
[letter digit _ -] 3..12
Negation:
pattern:
not whitespace 1..
These compile directly to regex fragments:
digitletterwhitespacetabspacenewlineupperlowerlinestartlineendanychar
Quantifiers are written after the target expression:
1means exactly once.0..1means optional.0..means zero or more.1..means one or more.2..5means between 2 and 5 times.
Examples:
digit 4
letter 1..
"ab" 2..3
Use double quotes for literal strings:
"@"
"https://"
# starts a comment that runs to the end of the line.
The engine includes reusable higher-level patterns:
@email@phone@creditcard@url@domain
Example:
pattern:
@email
engine/builtin/email.lx shows a non-trivial pattern with variables and nested captures:
$alwaysValid = [letter digit _ % +]
pattern:
email {
email_localpart { (
$alwaysValid
(
[letter digit _ % + - .] 0..
$alwaysValid
) 0..1
) 1..64 }
"@"
email_domain {
[letter digit]
(
[letter digit - .] 0..
[letter digit]
) 0..1
"."
[letter digit] 1..63
}
}
Compiling it:
go run . compile -f engine/builtin/email.lx- Definitions must appear before
pattern:. - Defined variables must be used, or resolution fails.
- Required variables are injected as literal strings from CLI flags.
- Builtins cannot be used more than once in a single pattern.
- Capture names must be unique.
- Anchors like
linestartandlineendcannot be quantified.
Errors include a message, source line, and caret position.
Missing a required CLI variable:
LitexCompileError: missing required variable: value
Hint: add --value=... to your command
1 | $value = require value
| ^
Using not with an unsupported target:
LitexCompileError: 'not' expects an identifier or character class
1 | pattern: not "x"
| ^
Reusing a capture name:
LitexCompileError: duplicate capture name: User
3 | User { letter }
| ^
The repo includes a separate Tree-sitter grammar in tree-sitter-lx for syntax highlighting and editor support.
See tree-sitter-lx/README.md for setup details.
This repo is still small and evolving. The language and CLI are usable now, but the surface area is intentionally narrow and a few behaviors are still implementation-shaped rather than polished product conventions.