No description
  • Rust 99.2%
  • Mermaid 0.8%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Daniel Baumann cabf334ef6
Releasing fastforward version 0.16.1-2~ffwd13+u1.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2026-10-12 15:58:27 +02:00
debian Releasing fastforward version 0.16.1-2~ffwd13+u1. 2026-10-12 15:58:27 +02:00
src Merging upstream version 0.16.1. 2026-10-12 15:57:51 +02:00
tests Merging upstream version 0.16.1. 2026-10-12 15:57:51 +02:00
.cargo_vcs_info.json Merging upstream version 0.16.1. 2026-10-12 15:57:51 +02:00
Cargo.lock Merging upstream version 0.16.1. 2026-10-12 15:57:51 +02:00
Cargo.toml Merging upstream version 0.16.1. 2026-10-12 15:57:51 +02:00
Cargo.toml.orig Merging upstream version 0.16.1. 2026-10-12 15:57:51 +02:00
LICENSE-APACHE Adding upstream version 0.15.1. 2026-08-04 22:00:16 +02:00
LICENSE-MIT Adding upstream version 0.15.1. 2026-08-04 22:00:16 +02:00
README.md Adding upstream version 0.15.1. 2026-08-04 22:00:16 +02:00

Logos logo

Logos

Book Crates.io version shield Docs Crates.io license shield Code coverage

Create ridiculously fast Lexers.

Logos has two goals:

  • To make it easy to create a Lexer, so you can focus on more complex problems.
  • To make the generated Lexer faster than anything you'd write by hand.

To achieve those, Logos:

Example

use logos::Logos;

#[derive(Logos, Debug, PartialEq)]
#[logos(skip r"[ \t\n\f]+")] // Ignore this regex pattern between tokens
enum Token {
    // Tokens can be literal strings, of any length.
    #[token("fast")]
    Fast,

    #[token(".")]
    Period,

    // Or regular expressions.
    #[regex("[a-zA-Z]+")]
    Text,
}

fn main() {
    let mut lex = Token::lexer("Create ridiculously fast Lexers.");

    assert_eq!(lex.next(), Some(Ok(Token::Text)));
    assert_eq!(lex.span(), 0..6);
    assert_eq!(lex.slice(), "Create");

    assert_eq!(lex.next(), Some(Ok(Token::Text)));
    assert_eq!(lex.span(), 7..19);
    assert_eq!(lex.slice(), "ridiculously");

    assert_eq!(lex.next(), Some(Ok(Token::Fast)));
    assert_eq!(lex.span(), 20..24);
    assert_eq!(lex.slice(), "fast");

    assert_eq!(lex.next(), Some(Ok(Token::Text)));
    assert_eq!(lex.slice(), "Lexers");
    assert_eq!(lex.span(), 25..31);

    assert_eq!(lex.next(), Some(Ok(Token::Period)));
    assert_eq!(lex.span(), 31..32);
    assert_eq!(lex.slice(), ".");

    assert_eq!(lex.next(), None);
}

For more examples and documentation, please refer to the Logos handbook or the crate documentation.

How fast?

Ridiculously fast!

test identifiers                       ... bench:         647 ns/iter (+/- 27) = 1204 MB/s
test keywords_operators_and_punctators ... bench:       2,054 ns/iter (+/- 78) = 1037 MB/s
test strings                           ... bench:         553 ns/iter (+/- 34) = 1575 MB/s

Acknowledgements

Thank you

Logos is very much a labor of love. If you find it useful, consider getting me some coffee. ☕

If you'd like to contribute to Logos, then consider reading the Contributing guide.

Contributing

Logos welcome any kind of contribution: bug reports, suggestions, or new features!

Please use the issues or pull requests tabs, when appropriate.

To release a new version, follow the RELEASE-PROCESS

License

This code is distributed under the terms of both the MIT license and the Apache License (Version 2.0), choose whatever works for you.

See LICENSE-APACHE and LICENSE-MIT for details.