An open API service indexing awesome lists of open source software.

https://github.com/maxxsoft/laps

Build lexers and parsers by deriving traits.
https://github.com/maxxsoft/laps

lexer parse parser rust

Last synced: 4 months ago
JSON representation

Build lexers and parsers by deriving traits.

Awesome Lists containing this project

README

          

# laps

[github](https://github.com/MaxXSoft/laps)
[crates.io](https://crates.io/crates/laps)
[docs.rs](https://docs.rs/laps)
[build status](https://github.com/MaxXSoft/laps/actions?query=branch%3Amaster)

Lexer and parser collections.

With `laps`, you can build lexers/parsers by just defining tokens/ASTs and deriving `Tokenize`/`Parse` trait for them.

## Usage

Add `laps` to your project by running `cargo add`:

```
cargo add laps --features macros
```

## Example

Implement a lexer for [S-expression](https://en.wikipedia.org/wiki/S-expression):

```rust
use laps::prelude::*;

#[token_kind]
#[derive(Debug, Tokenize)]
enum TokenKind {
// This token will be skipped.
#[skip(r"\s+")]
_Skip,
/// Parentheses.
#[regex(r"[()]")]
Paren(char),
/// Atom.
#[regex(r"[^\s()]+")]
Atom(String),
/// End-of-file.
#[eof]
Eof,
}
```

And the parser and [ASTs](https://en.wikipedia.org/wiki/Abstract_syntax_tree) (or actually [CSTs](https://en.wikipedia.org/wiki/Parse_tree)):

```rust
type Token = laps::token::Token;

token_ast! {
macro Token {
[atom] => { kind: TokenKind::Atom(_), prompt: "atom" },
[lpr] => { kind: TokenKind::Paren('(') },
[rpr] => { kind: TokenKind::Paren(')') },
[eof] => { kind: TokenKind::Eof },
}
}

#[derive(Parse)]
#[token(Token)]
enum Statement {
Elem(Elem),
End(Token![eof]),
}

#[derive(Parse)]
#[token(Token)]
struct SExp(Token![lpr], Vec, Token![rpr]);

#[derive(Parse)]
#[token(Token)]
enum Elem {
Atom(Token![atom]),
SExp(SExp),
}
```

The above implementation is very close in form to the corresponding EBNF representation of the S-expression:

```ebnf
Statement ::= Elem | EOF;
SExp ::= "(" {Elem} ")";
Elem ::= ATOM | SExp;
```

## More Examples

See the [`examples` directory](examples), which contains the following examples:

* [`sexp`](examples/sexp): a [S-expression](https://en.wikipedia.org/wiki/S-expression) parser.
* [`calc`](examples/calc): a simple expression calculator.
* [`json`](examples/json): a simple JSON parser.
* [`clike`](examples/clike): interpreter for a C-like programming language.

## Accelerating Code Completion for IDEs

By default, Cargo does not enable optimizations for procedural macros, which may result in slower code completion if you are using `laps` to generate lexers. To avoid this, you can add the following configuration to `Cargo.toml`:

```toml
[profile.dev.build-override]
opt-level = 3
```

You can also try to manually enable/disable parallelization for lexer generation by adding:

```rust
#[derive(Tokenize)]
#[enable_par(true)] // or #[enable_par(false)]
enum TokenKind {
// ...
}
```

The parallelization setting only affects compilation speed and has no effect at runtime, it's set automatically by `laps` by default.

## Changelog

See [CHANGELOG.md](CHANGELOG.md).

## License

Copyright (C) 2022-2023 MaxXing. Licensed under either of [Apache 2.0](LICENSE-APACHE) or [MIT](LICENSE-MIT) at your option.