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.
- Host: GitHub
- URL: https://github.com/maxxsoft/laps
- Owner: MaxXSoft
- License: apache-2.0
- Created: 2022-10-01T09:05:28.000Z (over 3 years ago)
- Default Branch: master
- Last Pushed: 2024-01-03T08:04:07.000Z (about 2 years ago)
- Last Synced: 2025-01-14T15:53:33.728Z (about 1 year ago)
- Topics: lexer, parse, parser, rust
- Language: Rust
- Homepage: https://crates.io/crates/laps
- Size: 813 KB
- Stars: 22
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE-APACHE
Awesome Lists containing this project
README
# laps
[
](https://github.com/MaxXSoft/laps)
[
](https://crates.io/crates/laps)
[
](https://docs.rs/laps)
[
](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.