From 810a3d8066c2efed3f7c74cfb171d17988168080 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Wed, 11 Sep 2019 21:10:38 +0200 Subject: Add an example to pest_consume --- pest_consume/examples/csv/csv.pest | 15 +++++++++ pest_consume/examples/csv/main.rs | 64 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 pest_consume/examples/csv/csv.pest create mode 100644 pest_consume/examples/csv/main.rs (limited to 'pest_consume/examples/csv') diff --git a/pest_consume/examples/csv/csv.pest b/pest_consume/examples/csv/csv.pest new file mode 100644 index 0000000..a67af8c --- /dev/null +++ b/pest_consume/examples/csv/csv.pest @@ -0,0 +1,15 @@ +WHITESPACE = _{ " "+ } +newline = _{ "\r\n" | "\n" } +number = { "-"? ~ (ASCII_DIGIT | ".")+ } +string = { (!"'" ~ ASCII)* } +field = ${ + number + | "'" ~ string ~ "'" +} +record = { + field ~ ("," ~ field)* + | "" +} +file = { + SOI ~ record ~ (newline ~ record)* ~ newline? ~ EOI +} diff --git a/pest_consume/examples/csv/main.rs b/pest_consume/examples/csv/main.rs new file mode 100644 index 0000000..037948b --- /dev/null +++ b/pest_consume/examples/csv/main.rs @@ -0,0 +1,64 @@ +#![feature(slice_patterns)] +use pest_consume::{match_inputs, Parser}; + +#[derive(pest_derive::Parser)] +#[grammar = "../examples/csv/csv.pest"] +struct CSVParser; + +type ParseResult = Result>; +type Node<'i> = pest_consume::Node<'i, Rule, ()>; + +#[derive(Debug)] +enum CSVField<'a> { + Number(f64), + String(&'a str), +} + +type CSVRecord<'a> = Vec>; +type CSVFile<'a> = Vec>; + +#[pest_consume::parser(CSVParser, Rule)] +impl CSVParser { + fn EOI(_input: Node) -> ParseResult<()> { + Ok(()) + } + + fn number(input: Node) -> ParseResult { + Ok(input.as_str().parse().unwrap()) + } + + fn string(input: Node) -> ParseResult<&str> { + Ok(input.as_str()) + } + + fn field(input: Node) -> ParseResult { + Ok(match_inputs!(input.children(); + [number(n)] => CSVField::Number(n), + [string(s)] => CSVField::String(s), + )) + } + + fn record(input: Node) -> ParseResult { + Ok(match_inputs!(input.children(); + [field(fields)..] => fields.collect(), + )) + } + + fn file(input: Node) -> ParseResult { + Ok(match_inputs!(input.children(); + [record(records).., EOI(_)] => records.collect(), + )) + } +} + +fn parse_csv(input_str: &str) -> ParseResult { + let inputs = CSVParser::parse(Rule::file, input_str)?; + Ok(match_inputs!(; inputs; + [file(e)] => e, + )) +} + +fn main() { + let parsed = parse_csv("-273.15, ' a string '\n\n42, 0"); + println!("{:?}", parsed); +} -- cgit v1.2.3