https://github.com/jezza/progger
A fairly simple set of parser and lexer tools. Built on top of logos and bumpalo.
https://github.com/jezza/progger
Last synced: about 1 year ago
JSON representation
A fairly simple set of parser and lexer tools. Built on top of logos and bumpalo.
- Host: GitHub
- URL: https://github.com/jezza/progger
- Owner: Jezza
- License: mit
- Created: 2020-09-06T14:15:58.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2020-11-01T14:13:44.000Z (over 5 years ago)
- Last Synced: 2025-02-12T14:31:07.682Z (over 1 year ago)
- Language: Rust
- Size: 9.77 KB
- Stars: 3
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Progger
Nothing too crazy.
Just a bunch of small utilities that I kept on bringing from one language project to another.
## Parser
It contains a simple Parser base.
It handles things like peeking and span wrapping.
```rust
progger::new_parser! {
Context = Context;
TokenKind = TokenKind;
Span = progger::span::Span;
}
```
## Span
It also contains a simple Span impl.
The Span that logos exports doesn't meet my requirements, and under the hood, it's just a range from the standard library.
That can be found under `progger::span::Span`.
Contains methods like `merge`, etc.
## Arena and Interner
This project also contains things like an allocation arena and an Interner.
They can be found under `mem`.
The arena allows for better cache locality when allocating a ton of AST nodes.
The interner allows for faster string book keeping and management.
## Full Usage
A more full-blown example using all the features would be something like:
```rust
use logos::Logos;
mod ast {
use progger::mem::ArenaId;
type ExprId = ArenaId;
enum Expr {
Negate(ExprId),
Add(ExprId, ExprId),
}
}
struct Context {
file_name: String,
pub(crate) interner: Interner,
pub(crate) expr: Arena<'static, Expression>,
}
impl Context {
fn new(file_name: impl Into) -> Self {
Context {
file_name: file_name.into(),
interner: Interner::new(),
expr: Arena::new(),
}
}
}
#[derive(Logos)]
enum TokenKind {
#[error]
Error,
#[token("value")]
Value,
}
mod parser {
progger::new_parser! {
Context = Context;
TokenKind = TokenKind;
Span = progger::span::Span;
}
}
fn main() {
let file_name = "Input.lance";
let content = "value";
let ctx = Context::new(file_name);
let mut parser = parser::new(ctx, content);
if parser.is(TokenKind::Value) {
panic!("Yay!");
}
}
```