diff --git a/.vscode/settings.json b/.vscode/settings.json index 5a95d22..c69d7d3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,11 +1,5 @@ { "rust-analyzer.linkedProjects": [ "./demo/Cargo.toml" - ], - "files.exclude": { - "**/*.rpyc": true, - "**/*.rpa": true, - "**/*.rpymc": true, - "**/cache/": true - } + ] } \ No newline at end of file diff --git a/demo/demo.csv b/demo/demo.csv new file mode 100644 index 0000000..20a98c9 --- /dev/null +++ b/demo/demo.csv @@ -0,0 +1,5 @@ +65279,1179403647,1463895090 +3.1415927,2.7182817,1.618034 +-40,-273.15 +13,42 +65537 diff --git a/demo/demo.rpy b/demo/demo.rpy deleted file mode 100644 index d986d46..0000000 --- a/demo/demo.rpy +++ /dev/null @@ -1,9 +0,0 @@ -show black amogus # this is a comment -# this is a full line comment -what the heck -"this is a string with a # comment" -"this is a string over -multiple lines" -this is cool # comment - -huh \ No newline at end of file diff --git a/demo/src/main.rs b/demo/src/main.rs index 4e2d100..79ef2ea 100644 --- a/demo/src/main.rs +++ b/demo/src/main.rs @@ -1,5 +1,5 @@ use renrs; fn main() { - renrs::parse("demo.rpy"); + renrs::parse("demo.csv"); } diff --git a/src/csv.pest b/src/csv.pest new file mode 100644 index 0000000..8b94fc7 --- /dev/null +++ b/src/csv.pest @@ -0,0 +1,9 @@ +// + indicates one or more times +field = { (ASCII_DIGIT | "." | "-")+ } +// ~ indicates directly followed by +// * indicates zero or more times (optional) +record = { field ~ ("," ~ field)* } +// SOI - start of input +// END - end of input +// There may be trailing newlines at the end +file = { SOI ~ (record ~ ("\r\n" | "\n"))* ~ "\n"* ~ EOI } diff --git a/src/lib.rs b/src/lib.rs index 8670d77..6b32541 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,32 +4,32 @@ use pest::Parser; use pest_derive::Parser; #[derive(Parser)] -#[grammar = "rpy.pest"] -struct RpyParser; +#[grammar = "csv.pest"] +struct CSVParser; pub fn parse(file_path: &str) { let unparsed_file = fs::read_to_string(file_path).expect("cannot find file"); - let file = RpyParser::parse(Rule::file, &unparsed_file) + let file = CSVParser::parse(Rule::file, &unparsed_file) .expect("unsuccessful parse") // unwrap the parse result .next().unwrap(); // get and unwrap the `file` rule; never fails - for line in file.into_inner() { - match line.as_rule() { - Rule::line => { - println!("Line:"); - for token in line.into_inner() { - match token.as_rule() { - Rule::token => { - println!("{}", token.as_str()); - }, - _ => { - println!("{}", token.as_str()); - } - } + + let mut field_sum = 0.0; + let mut record_count: u64 = 0; + + for record in file.into_inner() { + match record.as_rule() { + Rule::record => { + record_count += 1; + + for field in record.into_inner() { + field_sum += field.as_str().parse::().unwrap(); } - println!() }, Rule::EOI => (), _ => unreachable!(), } } + + println!("Sum of fields: {field_sum}"); + println!("Number of records: {record_count}"); } diff --git a/src/rpy.pest b/src/rpy.pest deleted file mode 100644 index 5fdaf5d..0000000 --- a/src/rpy.pest +++ /dev/null @@ -1,28 +0,0 @@ -// underscores mark are silent rules, are ignored -WHITESPACE = _{ " " } - -// characters are anything but newlines -char = { !NEWLINE ~ ANY } - -// token definition -// http://pest.rs/book/grammars/syntax.html#atomic -inner = @{ char* } - -token = { string | keyword } - -// has to be atomic for no implicit separate (spaces) -keyword = @{ (!(WHITESPACE | NEWLINE) ~ ANY)+ } - -// strings cannot contain quotes -// TODO: escaped quotes -string_data = @{ (!"\"" ~ ANY)* } -string = ${ "\"" ~ string_data ~ "\"" } - -// comments are a # followed by -// any number of non-newline characters -COMMENT = _{ "#" ~ char* } - -// lines are comprised of a statement -line = { token+ } - -file = { SOI ~ line ~ (NEWLINE+ ~ line)* ~ NEWLINE* ~ EOI } \ No newline at end of file