Simple Python lexer generator
Translation pending
Developer toolsPython · MakefileGitHub @Maxcode123OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
Name the rules. Get the tokens. lectes is a small Python scanner (lexer)
generator. Give it named regexes, and it yields tokens.Read the full README ↗Name the rules. Get the tokens. lectes is a small Python scanner (lexer) generator. Give it named regexes, and it yields tokens.
NAME regex rule per line, in Python or in a
.lectes file.lectes command. Scan files or stdin from the shell, as aligned text
or JSON Lines.Try it in the playground: lectes.dev lets you write a grammar and see the tokens as you type, right in your browser. Hover a token to see which rules fought for it.
As a library:
pip install lectes # or: uv add lectes
As a command-line tool:
uv tool install lectes # or: pipx install lectes
uvx lectes grammar.lectes input.txt # run once without installing
from lectes import Configuration, Scanner
config = Configuration.from_text(r"""
# Longest match wins; on a tie, the earlier rule wins.
FOR for
IN in
ID [a-zA-Z_][a-zA-Z0-9_]*
INT [0-9]+
WS [ ]+
""")
scanner = Scanner(config)
for token in scanner.scan("for item in items format 42"):
if token.rule.name != "WS":
print(token.location.column, token.rule.name, repr(token.literal))
1 FOR 'for'
5 ID 'item'
10 IN 'in'
13 ID 'items'
19 ID 'format'
26 INT '42'
for matches both FOR and ID with the same length, so the earlier rule,
FOR, wins. format is an ID, because the longer match always wins.
You can also build the rules in Python:
from lectes import Configuration, Regex, Rule
config = Configuration(
[
Rule(name="FOR", regex=Regex("for")),
Rule(name="ID", regex=Regex("[a-zA-Z_][a-zA-Z0-9_]*")),
]
)
The usage guide covers grammar errors and warnings, custom handlers, unmatched text and debugging.
The lectes command scans a file, or stdin, with a grammar file:
$ cat arithmetic.lectes
INT [0-9]+
PLUS \+
WS \s+
$ echo '12 + 3' | lectes arithmetic.lectes
1:1 INT '12'
1:3 WS ' '
1:4 PLUS '+'
1:5 WS ' '
1:6 INT '3'
1:7 WS '\n'
Use --format json for JSON Lines output, and --check to validate a grammar
without scanning. The exit codes are 0 on success, 1 for unmatched text, and 2
for a usage, grammar or I/O error. See the
command-line docs for every option.