6 releases
new 0.3.5 | Dec 20, 2024 |
---|---|
0.3.4 | Apr 16, 2023 |
0.3.3 | Oct 31, 2018 |
#971 in Procedural macros
1,064 downloads per month
Used in 17 crates
(9 directly)
34KB
610 lines
pest-ast
Convert from pest parse trees into typed syntax trees with ease!
Which would you rather have?
Pest Parse Tree
[
Pair {
rule: file,
span: Span {
str: "65279,1179403647,1463895090\n3.1415927,2.7182817,1.618034\n-40,-273.15\n13,42\n65537\n",
start: 0,
end: 81
},
inner: [
Pair {
rule: record,
span: Span {
str: "65279,1179403647,1463895090",
start: 0,
end: 27
},
inner: [
Pair {
rule: field,
span: Span {
str: "65279",
start: 0,
end: 5
},
inner: []
},
Pair {
rule: field,
span: Span {
str: "1179403647",
start: 6,
end: 16
},
inner: []
},
Pair {
rule: field,
span: Span {
str: "1463895090",
start: 17,
end: 27
},
inner: []
}
]
},
Pair {
rule: record,
span: Span {
str: "3.1415927,2.7182817,1.618034",
start: 28,
end: 56
},
inner: [
Pair {
rule: field,
span: Span {
str: "3.1415927",
start: 28,
end: 37
},
inner: []
},
Pair {
rule: field,
span: Span {
str: "2.7182817",
start: 38,
end: 47
},
inner: []
},
Pair {
rule: field,
span: Span {
str: "1.618034",
start: 48,
end: 56
},
inner: []
}
]
},
Pair {
rule: record,
span: Span {
str: "-40,-273.15",
start: 57,
end: 68
},
inner: [
Pair {
rule: field,
span: Span {
str: "-40",
start: 57,
end: 60
},
inner: []
},
Pair {
rule: field,
span: Span {
str: "-273.15",
start: 61,
end: 68
},
inner: []
}
]
},
Pair {
rule: record,
span: Span {
str: "13,42",
start: 69,
end: 74
},
inner: [
Pair {
rule: field,
span: Span {
str: "13",
start: 69,
end: 71
},
inner: []
},
Pair {
rule: field,
span: Span {
str: "42",
start: 72,
end: 74
},
inner: []
}
]
},
Pair {
rule: record,
span: Span {
str: "65537",
start: 75,
end: 80
},
inner: [
Pair {
rule: field,
span: Span {
str: "65537",
start: 75,
end: 80
},
inner: []
}
]
},
Pair {
rule: EOI,
span: Span {
str: "",
start: 81,
end: 81
},
inner: []
}
]
}
]
Typed Syntax Tree
File {
records: [
Record {
fields: [
Field {
value: 65279.0
},
Field {
value: 1179403647.0
},
Field {
value: 1463895090.0
}
]
},
Record {
fields: [
Field {
value: 3.1415927
},
Field {
value: 2.7182817
},
Field {
value: 1.618034
}
]
},
Record {
fields: [
Field {
value: -40.0
},
Field {
value: -273.15
}
]
},
Record {
fields: [
Field {
value: 13.0
},
Field {
value: 42.0
}
]
},
Record {
fields: [
Field {
value: 65537.0
}
]
}
],
eoi: EOI
}
The above parse tree is produced by the following pest grammar:
field = { (ASCII_DIGIT | "." | "-")+ }
record = { field ~ ("," ~ field)* }
file = { SOI ~ (record ~ ("\r\n" | "\n"))* ~ EOI }
parsing this csv:
65279,1179403647,1463895090
3.1415927,2.7182817,1.618034
-40,-273.15
13,42
65537
And converting it to a typed syntax tree is as simple as the following code:
mod ast {
use super::csv::Rule;
use pest::Span;
fn span_into_str(span: Span) -> &str {
span.as_str()
}
#[derive(Debug, FromPest)]
#[pest_ast(rule(Rule::field))]
pub struct Field {
#[pest_ast(outer(with(span_into_str), with(str::parse), with(Result::unwrap)))]
pub value: f64,
}
#[derive(Debug, FromPest)]
#[pest_ast(rule(Rule::record))]
pub struct Record {
pub fields: Vec<Field>,
}
#[derive(Debug, FromPest)]
#[pest_ast(rule(Rule::file))]
pub struct File {
pub records: Vec<Record>,
eoi: EOI,
}
#[derive(Debug, FromPest)]
#[pest_ast(rule(Rule::EOI))]
struct EOI;
}
And doing the actual parse is as simple as
let mut parse_tree = csv::Parser::parse(csv::Rule::file, &source)?;
let syntax_tree = File::from_pest(&mut parse_tree).expect("infallible");
Dependencies
~0.6–1MB
~24K SLoC