Macro gramma::define_rule
source · macro_rules! define_rule { ($( $(#$attr:tt)* $vis:vis struct $Name:ident { $( $(#$field_attr:tt)* $field_vis:vis $field:ident ),* $(,)? } )*) => { ... }; ($( $(#$attr:tt)* $vis:vis enum $Name:ident { $( $(#$variant_attr:tt)* $Variant:ident { $( $(#$field_attr:tt)* $field_vis:vis $field:ident ),* $(,)? } ),* $(,)? } )*) => { ... }; ($( $(#$attr:tt)* $vis:vis $kind:ident $Name:ident { $($x:tt)* } )*) => { ... }; }
Expand description
Define AST rules by declaring structs and enums.
§Basic Example
// Define Ident, LParen, RParen, Whitespace here:
gramma::define_token! {
/* ... */
}
gramma::define_rule! {
struct Group {
l_paren: LParen,
exprs: Vec<Expr>,
r_paren: RParen,
}
// Enum rules may only have struct-like variants:
#[transform(ignore_around<Whitespace>)]
enum Expr {
Group { group: Group },
Ident { ident: Ident },
}
}
let src = "
(list
(add a b)
(mul (sub c d) e)
)
";
let expr: Expr = gramma::parse_tree::<_, 1>(src).unwrap();
let display = format!("{:#}", gramma::display_tree(src, &expr));
assert_eq!(display, r#"Group -> {
"(",
[
<Ident "list">,
Group -> {
"(",
[
<Ident "add">,
<Ident "a">,
<Ident "b">,
],
")",
},
Group -> {
"(",
[
<Ident "mul">,
Group -> {
"(",
[
<Ident "sub">,
<Ident "c">,
<Ident "d">,
],
")",
},
<Ident "e">,
],
")",
},
],
")",
}"#);§Transformations
In the example above, Expr was given the attribute
#[transform(ignore_around<Whitespace>)].
Transformations, denoted by the #[transform(...)] attribute,
modify the way a rule is parsed.
All built-in transformations are declared as types in the
ast::transform module.
Some of the more common transformations are:
| Transformation | Description |
|---|---|
|
Parse an optional | |
|
Parse an optional | |
|
Parse an optional | |
|
Parse a required | |
|
Parse a required | |
|
Parse a required | |
|
Rejects if the section matched by the target rule starts with | |
|
Apply the transformation |
A #[transform(...)] can be applied to the entirety of a struct or enum rule,
an enum variant, or an individual field.