[](https://crates.io/crates/alder)
[](https://docs.rs/alder)
[](https://raw.githubusercontent.com/rust-lang/docs.rs/master/LICENSE)

# Alder
### Warning: Library is under development and may be subject to change.
Hand written recursive descent and non-backtracking parsing "combinator" library designed with nice error in mind
and lossless data.
### Goals
* [x] Almost no backtracking
* [x] Lossless tree generation (for formatters and IDE approach)
* [x] UTF-8 support
* [ ] Nice informative errors with contexts.
* [ ] AST generation based on CST (some macro and trait magic)
I'm somehow inspired by [this post](https://matklad.github.io/2018/06/06/modern-parser-generator.html). It's about parser generators but I prefer writing them manually.
### TODO
* [ ] Add the problem resolving in common parsers like `chomp_while`
* [ ] Add more common parsers
* [ ] Remove Arc if possible
* [ ] Documentation (right now I have only WIP JSON example)
* [ ] Maybe incremental parsing...
## Install
Use cargo-edit:
```sh
cargo add alder
```
Or add it manually:
```toml
alder = "0.8.0"
```
You may want to enable a derive feature as well:
```toml
alder = { version = "0.8.0" , features = ["derive"] }
```
## Example
```rust
// Doc tests are treated as a test cases for snapshots.
// To enable them use `derive` feature and add `#[alder_test]` macro.
// It also supports /** multiline comments */
/// []
/// [true]
/// [true,false]
/// [ ]
/// [ true ]
/// [ true, false ]
/// [ true, false, ]
/// [trua, falsa]
/// [truadsadsa, falsa]
/// [true, false
/// [truad sadsa, falsa]
/**
[
true,
false,
"foo"
]
*/
#[alder_test]
fn array() -> impl Parser {
with_extra(
extra(),
node(Json::Array, |state| {
state.add("[");
match state.peek(1).as_ref() {
"]" => (),
_ => 'outer: loop {
state.add(value());
'inner: loop {
// Until we find either ']' or ','
match state.peek(1).as_ref() {
"]" => {
break 'outer;
}
"," => {
state.add(recover(","));
if let "]" = state.peek(1).as_ref() {
// Trailing comma
break 'outer;
}
break 'inner;
}
"" => { // EOF
state.add(raise(Problem::InvalidTokenArray, 1));
break 'outer;
}
_ => state.add(raise(Problem::InvalidTokenArray, 1)),
};
}
},
}
state.add(recover("]"));
}),
)
}
```
Parsers should return information about what happened and where it happened:
```
--------------------------------- SYNTAX ERROR ---------------------------------
I was parsing Boolean when found issue:
--------------------------------- SYNTAX ERROR ---------------------------------
I was parsing Boolean when found issue:
```
## Contribute
Please use git-hooks.
```sh
cp .git-hooks/* .git/hooks/
```