From f5bb8d5a7c718e24a4dedd60d2518546d5f35b5b Mon Sep 17 00:00:00 2001 From: Yehowshua Immanuel Date: Sun, 19 Jun 2022 09:44:57 -0400 Subject: [PATCH] some re-org --- README.md | 16 +++-- src/vcd/parse.rs | 107 ++---------------------------- src/vcd/parse/combinator_atoms.rs | 70 +++++++++++++++++++ src/vcd/parse/types.rs | 25 +++++++ 4 files changed, 112 insertions(+), 106 deletions(-) create mode 100644 src/vcd/parse/combinator_atoms.rs create mode 100644 src/vcd/parse/types.rs diff --git a/README.md b/README.md index 641c3da..42e9eb9 100644 --- a/README.md +++ b/README.md @@ -26,14 +26,20 @@ The first build of the program may take some time. # TODO - [x] We need a way to merge lines. - - [ ] We need to start regression testing the parser over all files - - [ ] Decide if I want to return option types - - [ ] Propagate all to question mark unwrap types. - - [ ] Don't want variation in hh:mm:ss + - [x] We need to start regression testing the parser over all files + - [x] Decide if I want to return option types + - [x] Propagate all to question mark unwrap types. + - [x] Don't want variation in hh:mm:ss + - [x] parser_atoms -> combinator_atoms + - [x] make parse/types.rs + - [x] remove/replace calls to match_not_empty + - [ ] Split ``parse.rs``. It's getting too large. + - [ ] support parsing dates with commas + - [ ] move list of files to separate test file/folder + - [ ] Consolidate error messages and add cursors. - [ ] Consider what to do with don't care values will probably just convert them to strings for now. - - [ ] Split ``parse.rs``. It's getting too large. - [ ] Include line and possible column numbers - [ ] Change states to lowercase - [ ] Take a look at GTKWave parser to compare effificiency. diff --git a/src/vcd/parse.rs b/src/vcd/parse.rs index 198839a..3956214 100644 --- a/src/vcd/parse.rs +++ b/src/vcd/parse.rs @@ -1,111 +1,16 @@ -use super::*; use chrono::prelude::*; use itertools::Itertools; use std::fs::File; use ::function_name::named; -#[derive(Debug)] -pub struct Residual<'a>(&'a str); -#[derive(Debug)] -pub struct ParseResult<'a> {matched : &'a str, residual : &'a str} +use super::*; -pub fn digit(chr : u8) -> bool { - let zero = b'0' as u8; - let nine = b'9' as u8; +mod combinator_atoms; +use combinator_atoms::*; - let between_zero_and_nine = (chr >= zero) && (nine >= chr); +mod types; +use types::*; - return between_zero_and_nine -} - -pub fn take_until<'a>(word : &'a str, pattern : u8) -> ParseResult<'a> { - let mut new_start = 0; - - for chr in word.as_bytes() { - if (*chr == pattern) { - break - } - else { - new_start += 1; - } - } - - return - ParseResult{ - matched : &word[0..new_start], - residual : &word[new_start..] - }; - -} - -pub fn take_while<'a>(word : &'a str, cond : fn(u8) -> bool) -> ParseResult<'a> { - let mut new_start = 0; - - for chr in word.as_bytes() { - if (cond(*chr)) { - new_start += 1; - } - else { - break - } - } - - return - ParseResult{ - matched : &word[0..new_start], - residual : &word[new_start..] - }; - -} - -fn tag<'a>(word : &'a str, pattern : &'a str) -> ParseResult<'a> { - let lhs = word.as_bytes().iter(); - let rhs = pattern.as_bytes(); - let iter = lhs.zip(rhs); - let mut new_start = 0; - - let mut res = true; - for (c_lhs, c_rhs) in iter { - res = res && (c_lhs == c_rhs); - if !res {break} - new_start += 1; - } - - return - ParseResult{ - matched : &word[0..new_start], - residual : &word[new_start..] - }; -} - -impl<'a> ParseResult<'a> { - fn match_not_empty(& self) -> Result<(), String> { - if self.matched == "" { - return Err("failed".to_string()) - } - else { - return Ok(()) - } - } - - fn assert_match(& self) -> Result<&str, String> { - if self.matched == "" { - return Err("no match".to_string()) - } - else { - return Ok(self.matched) - } - } - - fn assert_residual(& self) -> Result<&str, String> { - if self.residual == "" { - return Err("no residual".to_string()) - } - else { - return Ok(self.residual) - } - } -} #[named] fn parse_date( @@ -311,7 +216,7 @@ fn parse_timescale(word_reader : &mut WordReader) -> Result<(Option, Timesc // then check for the `$end` keyword let (end, cursor) = word_reader.next_word().ok_or(&err_msg)?; - tag(end, "$end").match_not_empty()?; + tag(end, "$end").assert_match()?; return Ok(timescale); diff --git a/src/vcd/parse/combinator_atoms.rs b/src/vcd/parse/combinator_atoms.rs new file mode 100644 index 0000000..86ca84a --- /dev/null +++ b/src/vcd/parse/combinator_atoms.rs @@ -0,0 +1,70 @@ +use super::types::ParseResult; + +pub(super) fn digit(chr : u8) -> bool { + let zero = b'0' as u8; + let nine = b'9' as u8; + + let between_zero_and_nine = (chr >= zero) && (nine >= chr); + + return between_zero_and_nine +} + +pub(super) fn take_until<'a>(word : &'a str, pattern : u8) -> ParseResult<'a> { + let mut new_start = 0; + + for chr in word.as_bytes() { + if (*chr == pattern) { + break + } + else { + new_start += 1; + } + } + + return + ParseResult{ + matched : &word[0..new_start], + residual : &word[new_start..] + }; + +} + +pub(super) fn take_while<'a>(word : &'a str, cond : fn(u8) -> bool) -> ParseResult<'a> { + let mut new_start = 0; + + for chr in word.as_bytes() { + if (cond(*chr)) { + new_start += 1; + } + else { + break + } + } + + return + ParseResult{ + matched : &word[0..new_start], + residual : &word[new_start..] + }; + +} + +pub(super) fn tag<'a>(word : &'a str, pattern : &'a str) -> ParseResult<'a> { + let lhs = word.as_bytes().iter(); + let rhs = pattern.as_bytes(); + let iter = lhs.zip(rhs); + let mut new_start = 0; + + let mut res = true; + for (c_lhs, c_rhs) in iter { + res = res && (c_lhs == c_rhs); + if !res {break} + new_start += 1; + } + + return + ParseResult{ + matched : &word[0..new_start], + residual : &word[new_start..] + }; +} diff --git a/src/vcd/parse/types.rs b/src/vcd/parse/types.rs new file mode 100644 index 0000000..8bab3d4 --- /dev/null +++ b/src/vcd/parse/types.rs @@ -0,0 +1,25 @@ +#[derive(Debug)] +pub(super) struct ParseResult<'a> { + pub(super) matched : &'a str, + pub(super) residual : &'a str} + +impl<'a> ParseResult<'a> { + + pub(super) fn assert_match(& self) -> Result<&str, String> { + if self.matched == "" { + return Err("no match".to_string()) + } + else { + return Ok(self.matched) + } + } + + pub(super) fn assert_residual(& self) -> Result<&str, String> { + if self.residual == "" { + return Err("no residual".to_string()) + } + else { + return Ok(self.residual) + } + } +} \ No newline at end of file