From 80bd718677080227f7b2e26744456cb13debca27 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Wed, 11 Sep 2019 22:42:15 +0200 Subject: Various tweaks --- dhall_syntax/src/parser.rs | 14 +++++------ pest_consume/Cargo.toml | 4 +--- pest_consume/examples/csv/main.rs | 44 +++++++++++++++++++--------------- pest_consume/src/lib.rs | 3 +++ pest_consume_macros/src/make_parser.rs | 18 +++++++------- pest_consume_macros/src/match_nodes.rs | 6 ++--- 6 files changed, 47 insertions(+), 42 deletions(-) diff --git a/dhall_syntax/src/parser.rs b/dhall_syntax/src/parser.rs index c0b9712..8f6f423 100644 --- a/dhall_syntax/src/parser.rs +++ b/dhall_syntax/src/parser.rs @@ -285,17 +285,15 @@ impl DhallParser { } )) } - fn single_quote_char<'a>(input: ParseInput<'a>) -> ParseResult<&'a str> { + fn single_quote_char(input: ParseInput) -> ParseResult<&str> { Ok(input.as_str()) } #[alias(single_quote_char)] - fn escaped_quote_pair<'a>(_input: ParseInput<'a>) -> ParseResult<&'a str> { + fn escaped_quote_pair(_input: ParseInput) -> ParseResult<&str> { Ok("''") } #[alias(single_quote_char)] - fn escaped_interpolation<'a>( - _input: ParseInput<'a>, - ) -> ParseResult<&'a str> { + fn escaped_interpolation(_input: ParseInput) -> ParseResult<&str> { Ok("${") } @@ -549,9 +547,9 @@ impl DhallParser { }, )) } - fn posix_environment_variable_character<'a>( - input: ParseInput<'a>, - ) -> ParseResult<&'a str> { + fn posix_environment_variable_character( + input: ParseInput, + ) -> ParseResult<&str> { Ok(match input.as_str() { "\\\"" => "\"", "\\\\" => "\\", 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 = Result>; -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>; type CSVFile<'a> = Vec>; +type Result = std::result::Result>; +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 { - Ok(input.as_str().parse().unwrap()) + fn number(input: Node) -> Result { + input + .as_str() + .parse::() + // `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 { + fn field(input: Node) -> Result { Ok(match_nodes!(input.children(); [number(n)] => CSVField::Number(n), [string(s)] => CSVField::String(s), )) } - fn record(input: Node) -> ParseResult { + fn record(input: Node) -> Result { Ok(match_nodes!(input.children(); [field(fields)..] => fields.collect(), )) } - fn file(input: Node) -> ParseResult { + fn file(input: Node) -> Result { Ok(match_nodes!(input.children(); [record(records).., EOI(_)] => records.collect(), )) } } -fn parse_csv(input_str: &str) -> ParseResult { +fn parse_csv(input_str: &str) -> Result { let inputs = CSVParser::parse(Rule::file, input_str)?; Ok(match_nodes!(; inputs; [file(e)] => e, @@ -59,6 +62,9 @@ fn parse_csv(input_str: &str) -> ParseResult { } 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; diff --git a/pest_consume_macros/src/make_parser.rs b/pest_consume_macros/src/make_parser.rs index 2ed3271..c30b12f 100644 --- a/pest_consume_macros/src/make_parser.rs +++ b/pest_consume_macros/src/make_parser.rs @@ -261,7 +261,7 @@ fn apply_special_attrs(f: &mut ParsedFn, rule_enum: &Path) -> Result<()> { // While the current rule allows shortcutting, and there is a single child, and the // child can still be parsed by the current function, then skip to that child. while #self_ty::allows_shortcut(#input_arg.as_rule()) { - if let Some(child) = #input_arg.single_child() { + if let ::std::option::Option::Some(child) = #input_arg.single_child() { if child.as_aliased_rule::() == #self_ty::AliasedRule::#fn_name { #input_arg = child; continue; @@ -273,9 +273,9 @@ fn apply_special_attrs(f: &mut ParsedFn, rule_enum: &Path) -> Result<()> { match #input_arg.as_rule() { #(#rule_enum::#aliases => Self::#aliases(#input_arg),)* #rule_enum::#fn_name => #block, - r => unreachable!( + r => ::std::unreachable!( "make_parser: called {} on {:?}", - stringify!(#fn_name), + ::std::stringify!(#fn_name), r ) } @@ -349,14 +349,14 @@ pub fn make_parser( #(#rule_enum::#srcs => Self::#srcs(#input_arg),)* // We can't match on #rule_enum::#tgt since `tgt` might be an arbitrary // identifier. - r if &format!("{:?}", r) == stringify!(#tgt) => - return Err(#input_arg.error(format!( + r if &::std::format!("{:?}", r) == ::std::stringify!(#tgt) => + return ::std::result::Result::Err(#input_arg.error(::std::format!( "make_parser: missing method for rule {}", - stringify!(#tgt), + ::std::stringify!(#tgt), ))), - r => unreachable!( + r => ::std::unreachable!( "make_parser: called {} on {:?}", - stringify!(#tgt), + ::std::stringify!(#tgt), r ) } @@ -383,7 +383,7 @@ pub fn make_parser( match rule { #(#rule_alias_branches)* // TODO: return a proper error ? - r => unreachable!("Rule {:?} does not have a corresponding parsing method", r), + r => ::std::unreachable!("Rule {:?} does not have a corresponding parsing method", r), } } fn allows_shortcut(rule: Self::Rule) -> bool { diff --git a/pest_consume_macros/src/match_nodes.rs b/pest_consume_macros/src/match_nodes.rs index 251b7ef..4d9fd52 100644 --- a/pest_consume_macros/src/match_nodes.rs +++ b/pest_consume_macros/src/match_nodes.rs @@ -173,7 +173,7 @@ fn make_parser_branch( parses.push(quote!( let #binder = #i_inputs .map(|i| #parser::#rule_name(i)) - .collect::, _>>()? + .collect::<::std::result::Result<::std::vec::Vec<_>, _>>()? .into_iter(); )) } @@ -210,8 +210,8 @@ pub fn match_nodes( #[allow(unreachable_code)] match #i_input_rules.as_slice() { #(#branches,)* - [..] => return Err(#i_inputs.error( - format!("Unexpected children: {:?}", #i_input_rules) + [..] => return ::std::result::Result::Err(#i_inputs.error( + std::format!("Unexpected children: {:?}", #i_input_rules) )), } })) -- cgit v1.2.3