some re-org
This commit is contained in:
parent
5445891b8d
commit
f5bb8d5a7c
16
README.md
16
README.md
|
@ -26,14 +26,20 @@ The first build of the program may take some time.
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
- [x] We need a way to merge lines.
|
- [x] We need a way to merge lines.
|
||||||
- [ ] We need to start regression testing the parser over all files
|
- [x] We need to start regression testing the parser over all files
|
||||||
- [ ] Decide if I want to return option types
|
- [x] Decide if I want to return option types
|
||||||
- [ ] Propagate all to question mark unwrap types.
|
- [x] Propagate all to question mark unwrap types.
|
||||||
- [ ] Don't want variation in hh:mm:ss
|
- [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.
|
- [ ] Consolidate error messages and add cursors.
|
||||||
- [ ] Consider what to do with don't care values
|
- [ ] Consider what to do with don't care values
|
||||||
will probably just convert them to strings for now.
|
will probably just convert them to strings for now.
|
||||||
- [ ] Split ``parse.rs``. It's getting too large.
|
|
||||||
- [ ] Include line and possible column numbers
|
- [ ] Include line and possible column numbers
|
||||||
- [ ] Change states to lowercase
|
- [ ] Change states to lowercase
|
||||||
- [ ] Take a look at GTKWave parser to compare effificiency.
|
- [ ] Take a look at GTKWave parser to compare effificiency.
|
||||||
|
|
107
src/vcd/parse.rs
107
src/vcd/parse.rs
|
@ -1,111 +1,16 @@
|
||||||
use super::*;
|
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use ::function_name::named;
|
use ::function_name::named;
|
||||||
|
|
||||||
#[derive(Debug)]
|
use super::*;
|
||||||
pub struct Residual<'a>(&'a str);
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct ParseResult<'a> {matched : &'a str, residual : &'a str}
|
|
||||||
|
|
||||||
pub fn digit(chr : u8) -> bool {
|
mod combinator_atoms;
|
||||||
let zero = b'0' as u8;
|
use combinator_atoms::*;
|
||||||
let nine = b'9' as u8;
|
|
||||||
|
|
||||||
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]
|
#[named]
|
||||||
fn parse_date(
|
fn parse_date(
|
||||||
|
@ -311,7 +216,7 @@ fn parse_timescale(word_reader : &mut WordReader) -> Result<(Option<u32>, Timesc
|
||||||
|
|
||||||
// then check for the `$end` keyword
|
// then check for the `$end` keyword
|
||||||
let (end, cursor) = word_reader.next_word().ok_or(&err_msg)?;
|
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);
|
return Ok(timescale);
|
||||||
|
|
||||||
|
|
70
src/vcd/parse/combinator_atoms.rs
Normal file
70
src/vcd/parse/combinator_atoms.rs
Normal file
|
@ -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..]
|
||||||
|
};
|
||||||
|
}
|
25
src/vcd/parse/types.rs
Normal file
25
src/vcd/parse/types.rs
Normal file
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue