diff options
Diffstat (limited to 'pest_consume')
-rw-r--r-- | pest_consume/Cargo.toml | 4 | ||||
-rw-r--r-- | pest_consume/examples/csv/main.rs | 44 | ||||
-rw-r--r-- | pest_consume/src/lib.rs | 3 |
3 files changed, 29 insertions, 22 deletions
diff --git a/pest_consume/Cargo.toml b/pest_consume/Cargo.toml index 1e2b1af..1b8ebf6 100644 --- a/pest_consume/Cargo.toml +++ b/pest_consume/Cargo.toml @@ -10,8 +10,6 @@ repository = "https://github.com/Nadrieril/dhall-rust" [dependencies] pest = "2.1" +pest_derive = "2.1" proc-macro-hack = "0.5.9" pest_consume_macros = { path = "../pest_consume_macros" } - -[dev-dependencies] -pest_derive = "2.1" diff --git a/pest_consume/examples/csv/main.rs b/pest_consume/examples/csv/main.rs index bb9f8fc..efb83ad 100644 --- a/pest_consume/examples/csv/main.rs +++ b/pest_consume/examples/csv/main.rs @@ -1,57 +1,60 @@ #![feature(slice_patterns)] -use pest_consume::{match_nodes, Parser}; - -#[derive(pest_derive::Parser)] -#[grammar = "../examples/csv/csv.pest"] -struct CSVParser; - -type ParseResult<T> = Result<T, pest::error::Error<Rule>>; -type Node<'i> = pest_consume::Node<'i, Rule, ()>; +use pest_consume::{match_nodes, Error, Parser}; #[derive(Debug)] enum CSVField<'a> { Number(f64), String(&'a str), } - type CSVRecord<'a> = Vec<CSVField<'a>>; type CSVFile<'a> = Vec<CSVRecord<'a>>; +type Result<T> = std::result::Result<T, Error<Rule>>; +type Node<'i> = pest_consume::Node<'i, Rule, ()>; + +#[derive(Parser)] +#[grammar = "../examples/csv/csv.pest"] +struct CSVParser; + #[pest_consume::parser(CSVParser, Rule)] impl CSVParser { - fn EOI(_input: Node) -> ParseResult<()> { + fn EOI(_input: Node) -> Result<()> { Ok(()) } - fn number(input: Node) -> ParseResult<f64> { - Ok(input.as_str().parse().unwrap()) + fn number(input: Node) -> Result<f64> { + input + .as_str() + .parse::<f64>() + // `input.error` links the error to the location in the input file where it occurred. + .map_err(|e| input.error(e.to_string())) } - fn string(input: Node) -> ParseResult<&str> { + fn string(input: Node) -> Result<&str> { Ok(input.as_str()) } - fn field(input: Node) -> ParseResult<CSVField> { + fn field(input: Node) -> Result<CSVField> { Ok(match_nodes!(input.children(); [number(n)] => CSVField::Number(n), [string(s)] => CSVField::String(s), )) } - fn record(input: Node) -> ParseResult<CSVRecord> { + fn record(input: Node) -> Result<CSVRecord> { Ok(match_nodes!(input.children(); [field(fields)..] => fields.collect(), )) } - fn file(input: Node) -> ParseResult<CSVFile> { + fn file(input: Node) -> Result<CSVFile> { Ok(match_nodes!(input.children(); [record(records).., EOI(_)] => records.collect(), )) } } -fn parse_csv(input_str: &str) -> ParseResult<CSVFile> { +fn parse_csv(input_str: &str) -> Result<CSVFile> { let inputs = CSVParser::parse(Rule::file, input_str)?; Ok(match_nodes!(<CSVParser>; inputs; [file(e)] => e, @@ -59,6 +62,9 @@ fn parse_csv(input_str: &str) -> ParseResult<CSVFile> { } fn main() { - let parsed = parse_csv("-273.15, ' a string '\n\n42, 0"); - println!("{:?}", parsed); + let successful_parse = parse_csv("-273.15, ' a string '\n\n42, 0"); + println!("success: {:?}", successful_parse.unwrap()); + + let unsuccessful_parse = parse_csv("0, 273.15.12"); + println!("failure: {}", unsuccessful_parse.unwrap_err()); } diff --git a/pest_consume/src/lib.rs b/pest_consume/src/lib.rs index 319810a..dd6c1f2 100644 --- a/pest_consume/src/lib.rs +++ b/pest_consume/src/lib.rs @@ -3,8 +3,11 @@ /// parse tree needs to be transformed into whatever datastructures your application uses. /// `pest_consume` provides two powerful macros to make this easy. use pest::error::Error; + +pub use pest::error::Error; use pest::Parser as PestParser; use pest::RuleType; +pub use pest_derive::Parser; #[proc_macro_hack::proc_macro_hack] pub use pest_consume_macros::match_nodes; |