# GLL parsing framework
[![Build Status](https://travis-ci.com/lykenware/gll.svg?branch=master)](https://travis-ci.com/lykenware/gll)
[![Latest Version](https://img.shields.io/crates/v/gll.svg)](https://crates.io/crates/gll)
[![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://docs.rs/gll)
## Usage
Easiest way to get started is through `gll-macros`:
```toml
[dependencies]
gll = "0.0.2"
gll-macros = "0.0.2"
```
```rust
extern crate gll;
extern crate gll_macros;
```
As an example, this is what you might write for a JSON-like syntax,
that uses plain identifiers instead of string literals for field names,
and allows values to be parenthesized Rust expressions:
```rust
mod json_like {
::gll_macros::proc_macro_parser! {
Value =
Null:"null" |
False:"false" |
True:"true" |
Literal:LITERAL |
Array:{ "[" elems:Value* % "," "]" } |
Object:{ "{" fields:Field* % "," "}" } |
InterpolateRust:{ "(" TOKEN_TREE+ ")" };
Field = name:IDENT ":" value:Value;
}
}
```
You can also use a build script to generate the parser (**TODO**: document).
To parse a string with that grammar:
```rust
let tokens = string.parse().unwrap();
// ...
});
```
## Grammar
All grammars contain a set of named rules, with the syntax `Name = rule;`.
(the order between the rules doesn't matter)
Rules are made out of:
* **grouping**, using `{...}`
* **string literals**, matching input characters / tokens exactly
* **character ranges**: `'a'..='d'` is equivalent to `"a"|"b"|"c"|"d"`
* only in scannerless mode
* **builtin rules**: `IDENT`, `PUNCT`, `LITERAL`, `TOKEN_TREE`
* only in proc macro mode
* **named rules**, referred to by their name
* **concatenation**: `A B` - "`A` followed by `B`"
* **alternation**: `A | B` - "either `A` or `B`"
* **optionals**: `A?` - "either `A` or nothing"
* **lists**: `A*` - "zero or more `A`s", `A+` - "one or more `A`s"
* optional separator: `A* % ","` - "comma-separated `A`s"
Parts of a rule can be labeled with **field names**, to allow later access to them:
`LetDecl = "let" pat:Pat { "=" init:Expr }? ";";` produces:
```rust
// Note: generic parameters omitted for brevity.
struct LetDecl {
pat: Handle<Pat>,
init: Option<Handle<Expr>>,
}
```
One Rust-specific convention is that alternation fields are enum variants.
`Expr = Lit:LITERAL | Add:{ a:Expr "+" b:Expr };` produces:
```rust
enum Expr {
Lit(Handle<LITERAL>),
Add {
a: Handle<Expr>,
b: Handle<Expr>,
},
}
```
## License
Licensed under either of
* Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
at your option.
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in this crate by you, as defined in the Apache-2.0 license, shall
be dual licensed as above, without any additional terms or conditions.