Skip to main content

SciLex — a generic, linear-time maximal-munch lexer built on REAL

Project description

SciLex

A small, header-only C++20 maximal-munch lexer built on REAL.

  • Linear-time and ReDoS-safe by construction (via REAL).
  • Eager tokenize or lazy scan.
  • Optional indentation layout for significant-whitespace languages.
  • C++20 header-only + abi3 Python binding (CPython 3.10+).
  • Zero dependencies beyond REAL headers.

Define an ordered set of token rules — each a (kind, regex, skip) triple — and SciLex tokenizes by maximal munch: the longest anchored match wins, with rule order breaking ties. Because it is a thin layer over REAL, tokenization is linear and ReDoS-safe by construction.

This follows the same design principles as REAL: purity, simplicity, and measured optimality.

Features (v1)

  • Ordered token rules: (kind, real::regex, skip)
  • Maximal-munch matching (longest match wins, rule order for ties)
  • Source positions (byte offset, line, column)
  • Eager (tokenize) and lazy (scan) APIs
  • Optional END_OF_INPUT token
  • Optional indentation layout (NEWLINE / INDENT / DEDENT)
  • Positioned errors with context snippet
  • Linear-time / ReDoS-safe (via REAL)

Out of scope for v1: modes, static_lexer, codepoint columns, CLI.

See the guided tour for details and known limitations.

C++ API

#include <scilex/scilex.hpp>

std::vector<scilex::rule> rules = {
    {0, real::regex("\\s+"), true},           // whitespace (skip)
    {1, real::regex("if")},                   // keyword before identifier
    {2, real::regex("[a-z_][a-z0-9_]*")},     // identifier
    {3, real::regex("[0-9]+")},               // number
};

scilex::lexer lexer(std::move(rules));

// Eager
for (const auto& tok : lexer.tokenize("if x + 42")) { ... }

// Lazy (preferred for parsers)
for (const auto& tok : lexer.scan("if x + 42")) { ... }

See docs/design.dox for the complete C++ API (lexer, token, position, layout, lex_error).

Python binding

An abi3 CPython extension (CPython 3.10+, Limited API).

import scilex

lx = scilex.Lexer([
    (0, r"\s+", True),                 # whitespace (skip)
    (1, r"[0-9]+", False),             # number
    (2, r"[A-Za-z_][A-Za-z0-9_]*", False),
])

# Eager
tokens = lx.tokenize("foo 42", eof=True)

# Lazy (generator)
for tok in lx.scan("foo 42"):
    print(tok.kind, tok.lexeme, tok.position)

# Errors with context
try:
    lx.tokenize("foo @")
except scilex.error as e:
    e.position
    e.context

For significant indentation:

laid = scilex.Layout().apply(lx.tokenize(src, eof=True))

pip install scilex (wheels + sdist). Use scilex.get_include() to compile C++ code against the installed headers.

Build locally: make python && make python-test.

Dependencies

SciLex is header-only and depends only on REAL's headers (the package real-regex on PyPI / https://github.com/RECHE23/real-regex).

By default the build looks for them in a sibling checkout:

~/Projects/
├── real-regex/   # REAL (https://github.com/RECHE23/real-regex)
└── scilex/       # SciLex  (uses ../real-regex/include by default)

Point the build elsewhere with REAL_INCLUDE (Makefile) or -DSCILEX_REAL_INCLUDE=... (CMake) — for instance at the path printed by python -c "import real; print(real.get_include())" when REAL is installed via pip.

For CI or a reproducible build — where no on-disk layout can be assumed — fetch REAL with CMake FetchContent instead (make build FETCH=1, or -DSCILEX_FETCH_DEPS=ON); point it at a remote and pin a tag with -DSCILEX_REAL_REPO=https://… -DSCILEX_REAL_TAG=v2026.6.6.

Development

make test        # build and run the test suite
make coverage    # line-coverage summary + HTML report
make sanitize    # tests under AddressSanitizer + UndefinedBehaviorSanitizer
make lint        # clang-tidy
make format      # uncrustify, in place
make doc         # API reference (Doxygen) with embedded coverage

The API reference is published at https://reche23.github.io/scilex/.

Override the compiler with make test CXX=g++-14.

Coverage bar. SciLex holds the SciLang-stack gate — 100% on all four dimensions (lines, functions, regions and branches) of include/, checked by make coverage and enforced by make full-local-gate (using Apple clang 16). The published report on GitHub Pages / the doc tarball (built on clang 18) reads mid-90s (newer clang instruments more branches). This is the documented toolchain distinction; see the live report for exact figures. (REAL is the other documented exception to the 100% gate — see its README.)

scilex::scilex is the CMake target — add_subdirectory, FetchContent, or an installed config package. The config calls find_dependency(real), so installing REAL's config package alongside (on the same prefix) makes the whole chain resolve from one find_package:

# With REAL and SciLex installed under <prefix>:
find_package(scilex CONFIG REQUIRED)   # pulls in real:: transitively
target_link_libraries(app PRIVATE scilex::scilex)

Releasing

make release computes the next calendar version YYYY.M.PATCH (the patch resets each month; PEP 440 drops leading zeros). The pushed tag drives the release workflow — wheels + sdist + the API-reference tarball + a GitHub Release, published via Trusted Publishing — while docs.yml deploys the reference to GitHub Pages.

Design

A guided tour of how SciLex works (maximal munch, REAL foundation, layout, C++/Python API, limitations) lives in docs/design.dox (also rendered by make doc).

Performance

See BENCHMARKS.md. On normal input re is faster. On adversarial input SciLex stays linear while re explodes. See the benchmarks for details.

License

MIT — see LICENSE.

Author

René Chenard

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

scilex-2026.6.2.tar.gz (31.2 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

scilex-2026.6.2-cp310-abi3-win_amd64.whl (244.2 kB view details)

Uploaded CPython 3.10+Windows x86-64

scilex-2026.6.2-cp310-abi3-win32.whl (242.1 kB view details)

Uploaded CPython 3.10+Windows x86

scilex-2026.6.2-cp310-abi3-musllinux_1_2_x86_64.whl (1.5 MB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ x86-64

scilex-2026.6.2-cp310-abi3-musllinux_1_2_aarch64.whl (1.4 MB view details)

Uploaded CPython 3.10+musllinux: musl 1.2+ ARM64

scilex-2026.6.2-cp310-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl (448.3 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.24+ x86-64manylinux: glibc 2.28+ x86-64

scilex-2026.6.2-cp310-abi3-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl (439.8 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.24+ ARM64manylinux: glibc 2.28+ ARM64

scilex-2026.6.2-cp310-abi3-macosx_11_0_x86_64.whl (56.6 kB view details)

Uploaded CPython 3.10+macOS 11.0+ x86-64

scilex-2026.6.2-cp310-abi3-macosx_11_0_arm64.whl (54.1 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

File details

Details for the file scilex-2026.6.2.tar.gz.

File metadata

  • Download URL: scilex-2026.6.2.tar.gz
  • Upload date:
  • Size: 31.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for scilex-2026.6.2.tar.gz
Algorithm Hash digest
SHA256 0e67cf62abd36a1757c5471d0692e68e8522ea8ff39cc6654bdce944563ebece
MD5 56b00de15d0398c7fd65d46963c68995
BLAKE2b-256 530bfb41246ca25acad141ee0c5dbe31e0ac4b2702040e8073d96b1033886044

See more details on using hashes here.

Provenance

The following attestation bundles were made for scilex-2026.6.2.tar.gz:

Publisher: release.yml on RECHE23/scilex

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file scilex-2026.6.2-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: scilex-2026.6.2-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 244.2 kB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for scilex-2026.6.2-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 0f5a9f44dc4a374636b584cb9c322a37156454ba19d4452f2b1c94b9ad896140
MD5 29757d2eb1b0466db44abd25bbb3e085
BLAKE2b-256 b6da134787e76dfef876f1cfe62617d3b0bd752930ac585bdc83124a23cef831

See more details on using hashes here.

Provenance

The following attestation bundles were made for scilex-2026.6.2-cp310-abi3-win_amd64.whl:

Publisher: release.yml on RECHE23/scilex

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file scilex-2026.6.2-cp310-abi3-win32.whl.

File metadata

  • Download URL: scilex-2026.6.2-cp310-abi3-win32.whl
  • Upload date:
  • Size: 242.1 kB
  • Tags: CPython 3.10+, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for scilex-2026.6.2-cp310-abi3-win32.whl
Algorithm Hash digest
SHA256 619ad3114943e1c47ceea7e0c1418f258eacb4b8279eb1ba78bcd9076896c680
MD5 47b59756d37d6ff6270405e65c40409d
BLAKE2b-256 054722089027df873800c24eea8679d44e8fdd24552980290e75d40aaeaef998

See more details on using hashes here.

Provenance

The following attestation bundles were made for scilex-2026.6.2-cp310-abi3-win32.whl:

Publisher: release.yml on RECHE23/scilex

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file scilex-2026.6.2-cp310-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for scilex-2026.6.2-cp310-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 e637559089bde709621e8a6b8549597cad3b29b9214d006ea5046ad0d41238a8
MD5 36264e58f0810c7e4bd228829aa13cc1
BLAKE2b-256 418250cd26cc9364d88e4918901fd85948bf97d9d8194c4ceafde9ccfc1029ee

See more details on using hashes here.

Provenance

The following attestation bundles were made for scilex-2026.6.2-cp310-abi3-musllinux_1_2_x86_64.whl:

Publisher: release.yml on RECHE23/scilex

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file scilex-2026.6.2-cp310-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for scilex-2026.6.2-cp310-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 fd30d0304ac2f87de4ac9692b8da84c6285370be771944b4d5a36dcf2612b623
MD5 89925c0d3dc16936f1f4e686aeeee53d
BLAKE2b-256 63393ee730ae28e9153e51e48c9e0b1aa33559daa9b0e566912eecb6c197f771

See more details on using hashes here.

Provenance

The following attestation bundles were made for scilex-2026.6.2-cp310-abi3-musllinux_1_2_aarch64.whl:

Publisher: release.yml on RECHE23/scilex

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file scilex-2026.6.2-cp310-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for scilex-2026.6.2-cp310-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 3a3901d807bcc99809aad3070326fb791722343460a7c082d8f3545f9643132a
MD5 eee1a6ac22a67d7e7a6c1919363a228c
BLAKE2b-256 c2b9f4cd334d03a84670f6bc77dc3248052ba2e2972e6b66326e4e7c8ba5f81e

See more details on using hashes here.

Provenance

The following attestation bundles were made for scilex-2026.6.2-cp310-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl:

Publisher: release.yml on RECHE23/scilex

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file scilex-2026.6.2-cp310-abi3-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for scilex-2026.6.2-cp310-abi3-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 3ded57a74de58af21c893cbcb2da3175702b8ffd843899dd529e03257d8f95bc
MD5 42db0a1e2e17aaa41e78afe65eb3d1b6
BLAKE2b-256 9fb6d549b8ab40a71da2463b5197d4c14d911815e9b8d39afebabc468c75aad5

See more details on using hashes here.

Provenance

The following attestation bundles were made for scilex-2026.6.2-cp310-abi3-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl:

Publisher: release.yml on RECHE23/scilex

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file scilex-2026.6.2-cp310-abi3-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for scilex-2026.6.2-cp310-abi3-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 ce7bf074f5bc2237297b3b5df261a7bd1f5697f25804adf2b180247caf9d9813
MD5 12684473f66084a177c1bdc47dc029b6
BLAKE2b-256 f2c182c8ee9d3851cec88e77a6244e272ec32acc958080ad1471c79afe54d04d

See more details on using hashes here.

Provenance

The following attestation bundles were made for scilex-2026.6.2-cp310-abi3-macosx_11_0_x86_64.whl:

Publisher: release.yml on RECHE23/scilex

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file scilex-2026.6.2-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for scilex-2026.6.2-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 07e75a6cd4b6913311a236f986265055a972fb0fd5779bd78e9a4ced2ca4df1e
MD5 081332c063b8b1a7a10429e23ffa3ce3
BLAKE2b-256 61142b463ec61d612363e74b143d2ceb17689b5efbfbcfa2e7cf6f05edf20c02

See more details on using hashes here.

Provenance

The following attestation bundles were made for scilex-2026.6.2-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on RECHE23/scilex

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page