Lexer and parser collections.
With laps
, you can build parsers by just defining ASTs and deriving Parse
trait for them.
Add laps
to your project by running cargo add
:
cargo add laps
Implement a lexer for S-expression:
```rust use laps::prelude::*;
enum TokenKind { /// Atom. Atom(String), /// Parentheses. Paren(char), /// End-of-file. Eof, }
type Token = laps::token::Token
struct Lexer
impl
fn nexttoken(&mut self) -> laps::span::Result
And the parser and ASTs (or actually CSTs):
```rust tokenast! { macro Token(mod = crate, Kind = TokenKind) { [atom] => (TokenKind::Atom(), "atom"), [lpr] => (TokenKind::Paren('('), _), [rpr] => (TokenKind::Paren(')'), _), [eof] => (TokenKind::Eof, _), } }
enum Statement { Elem(Elem), End(Token![eof]), }
struct SExp(Token![lpr], Vec
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;
See the examples
directory, which contains the following examples:
sexp
: a S-expression parser.calc
: a simple expression calculator.json
: a simple JSON parser.clike
: interpreter for a C-like programming language.See CHANGELOG.md.
Copyright (C) 2022-2023 MaxXing. Licensed under either of Apache 2.0 or MIT at your option.