summaryrefslogtreecommitdiff
path: root/pest_consume/examples/csv
diff options
context:
space:
mode:
authorNadrieril2019-09-11 21:10:38 +0200
committerNadrieril2019-09-11 21:10:38 +0200
commit810a3d8066c2efed3f7c74cfb171d17988168080 (patch)
tree74424ede0dcdc81b9754a1e47239f06f1ecf316f /pest_consume/examples/csv
parentf1a4d315de5be701f29beb7d3c32af2e96f967b6 (diff)
Add an example to pest_consume
Diffstat (limited to 'pest_consume/examples/csv')
-rw-r--r--pest_consume/examples/csv/csv.pest15
-rw-r--r--pest_consume/examples/csv/main.rs64
2 files changed, 79 insertions, 0 deletions
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<T> = Result<T, pest::error::Error<Rule>>;
+type Node<'i> = pest_consume::Node<'i, Rule, ()>;
+
+#[derive(Debug)]
+enum CSVField<'a> {
+ Number(f64),
+ String(&'a str),
+}
+
+type CSVRecord<'a> = Vec<CSVField<'a>>;
+type CSVFile<'a> = Vec<CSVRecord<'a>>;
+
+#[pest_consume::parser(CSVParser, Rule)]
+impl CSVParser {
+ fn EOI(_input: Node) -> ParseResult<()> {
+ Ok(())
+ }
+
+ fn number(input: Node) -> ParseResult<f64> {
+ Ok(input.as_str().parse().unwrap())
+ }
+
+ fn string(input: Node) -> ParseResult<&str> {
+ Ok(input.as_str())
+ }
+
+ fn field(input: Node) -> ParseResult<CSVField> {
+ Ok(match_inputs!(input.children();
+ [number(n)] => CSVField::Number(n),
+ [string(s)] => CSVField::String(s),
+ ))
+ }
+
+ fn record(input: Node) -> ParseResult<CSVRecord> {
+ Ok(match_inputs!(input.children();
+ [field(fields)..] => fields.collect(),
+ ))
+ }
+
+ fn file(input: Node) -> ParseResult<CSVFile> {
+ Ok(match_inputs!(input.children();
+ [record(records).., EOI(_)] => records.collect(),
+ ))
+ }
+}
+
+fn parse_csv(input_str: &str) -> ParseResult<CSVFile> {
+ let inputs = CSVParser::parse(Rule::file, input_str)?;
+ Ok(match_inputs!(<CSVParser>; inputs;
+ [file(e)] => e,
+ ))
+}
+
+fn main() {
+ let parsed = parse_csv("-273.15, ' a string '\n\n42, 0");
+ println!("{:?}", parsed);
+}