summaryrefslogtreecommitdiff
path: root/pest_consume
diff options
context:
space:
mode:
authorNadrieril2019-09-11 22:42:15 +0200
committerNadrieril2019-09-11 22:42:15 +0200
commit80bd718677080227f7b2e26744456cb13debca27 (patch)
tree5ec397012fbfe65192c07c16c7fd20a6bd73e2db /pest_consume
parentf4f83af7831c309923feaf453069a6a75e181084 (diff)
Various tweaks
Diffstat (limited to '')
-rw-r--r--pest_consume/Cargo.toml4
-rw-r--r--pest_consume/examples/csv/main.rs44
-rw-r--r--pest_consume/src/lib.rs3
-rw-r--r--pest_consume_macros/src/make_parser.rs18
-rw-r--r--pest_consume_macros/src/match_nodes.rs6
5 files changed, 41 insertions, 34 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;
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>() == #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::<Result<Vec<_>, _>>()?
+ .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)
)),
}
}))