Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/rust-lang/gll
GLL parsing framework.
https://github.com/rust-lang/gll
Last synced: 4 months ago
JSON representation
GLL parsing framework.
- Host: GitHub
- URL: https://github.com/rust-lang/gll
- Owner: rust-lang
- License: apache-2.0
- Created: 2018-08-14T13:26:41.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2024-03-18T15:02:47.000Z (10 months ago)
- Last Synced: 2024-09-28T20:41:07.110Z (4 months ago)
- Language: Rust
- Homepage:
- Size: 447 KB
- Stars: 138
- Watchers: 16
- Forks: 25
- Open Issues: 42
-
Metadata Files:
- Readme: README.md
- License: LICENSE-APACHE
Awesome Lists containing this project
README
# GLL parsing framework
[![Build Status](https://travis-ci.com/rust-lang/gll.svg?branch=master)](https://travis-ci.com/rust-lang/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"
```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();
json_like::Value::parse(tokens).unwrap().with(|value| {
// ...
});
```## 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"
* variant: `A* %% ","` - "comma-separated `A`s", with an optional trailing commaParts 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,
init: Option>,
}
```
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),
Add {
a: Handle,
b: Handle,
},
}
```## 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.