3 releases
Uses old Rust 2015
0.0.2 | Oct 31, 2018 |
---|---|
0.0.1 | Sep 27, 2018 |
0.0.0 | Aug 18, 2018 |
#311 in Parser tooling
Used in gll-macros
125KB
3.5K
SLoC
GLL parsing framework
Usage
Easiest way to get started is through gll-macros
:
[dependencies]
gll = "0.0.2"
gll-macros = "0.0.2"
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:
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:
let tokens = string.parse().unwrap();
json_like::Value::parse_with(tokens, |parser, result| {
let value = result.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 byB
" - alternation:
A | B
- "eitherA
orB
" - optionals:
A?
- "eitherA
or nothing" - lists:
A*
- "zero or moreA
s",A+
- "one or moreA
s"- optional separator:
A* % ","
- "comma-separatedA
s"
- optional separator:
Parts of a rule can be labeled with field names, to allow later access to them:
LetDecl = "let" pat:Pat { "=" init:Expr }? ";";
produces:
// 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:
enum Expr {
Lit(Handle<LITERAL>),
Add {
a: Handle<Expr>,
b: Handle<Expr>,
},
}
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (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.
Dependencies
~560KB
~12K SLoC