laps

github crates.io docs.rs build status

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:

```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 (or actually CSTs):

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

tokenast! { 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, which contains the following examples:

Changelog

See CHANGELOG.md.

License

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