2022-04-14 04:50:37 +00:00
|
|
|
use std::io::prelude::*;
|
|
|
|
use std::io;
|
|
|
|
use std::fs::File;
|
2022-05-18 02:04:32 +00:00
|
|
|
use std::collections::BTreeMap;
|
2022-05-19 07:44:24 +00:00
|
|
|
use chrono::prelude::*;
|
|
|
|
use std::rc::Rc;
|
2022-04-14 04:50:37 +00:00
|
|
|
|
|
|
|
use num::*;
|
|
|
|
use clap::Parser;
|
|
|
|
|
|
|
|
#[derive(Parser)]
|
|
|
|
struct Cli {
|
|
|
|
/// The path to the file to read
|
|
|
|
#[clap(parse(from_os_str))]
|
2022-05-21 02:52:26 +00:00
|
|
|
path: std::path::PathBuf}
|
2022-04-14 04:50:37 +00:00
|
|
|
|
2022-05-19 07:44:24 +00:00
|
|
|
|
|
|
|
// TODO: implement any timescales greater than a second
|
|
|
|
enum Timescale {ps, ns, us, ms, s}
|
|
|
|
|
2022-05-21 02:52:26 +00:00
|
|
|
struct Scope_Idx(usize);
|
|
|
|
struct Signal_Idx(usize);
|
|
|
|
|
2022-05-19 07:44:24 +00:00
|
|
|
struct Metadata {
|
2022-05-21 02:52:26 +00:00
|
|
|
date : DateTime<Utc>,
|
2022-05-19 07:44:24 +00:00
|
|
|
version : String,
|
2022-05-21 02:52:26 +00:00
|
|
|
timescale : Timescale}
|
2022-05-19 07:44:24 +00:00
|
|
|
|
2022-05-18 02:04:32 +00:00
|
|
|
struct Signal {
|
2022-05-21 02:52:26 +00:00
|
|
|
name : String,
|
|
|
|
timeline : BTreeMap<BigInt, BigInt>,
|
|
|
|
scope_parent : Scope_Idx}
|
2022-05-19 07:44:24 +00:00
|
|
|
|
|
|
|
struct SignalAlias {
|
|
|
|
name : String,
|
2022-05-21 02:52:26 +00:00
|
|
|
signal_alias : Signal_Idx}
|
2022-05-19 07:44:24 +00:00
|
|
|
|
|
|
|
enum SignalGeneric{
|
|
|
|
Signal(Signal),
|
2022-05-21 02:52:26 +00:00
|
|
|
SignalAlias(SignalAlias)}
|
2022-05-18 02:04:32 +00:00
|
|
|
|
2022-05-19 07:44:24 +00:00
|
|
|
struct Scope {
|
2022-05-21 02:52:26 +00:00
|
|
|
name : String,
|
|
|
|
child_signals : Vec<Signal_Idx>,
|
|
|
|
child_scopes : Vec<Scope_Idx>}
|
2022-05-19 07:44:24 +00:00
|
|
|
|
|
|
|
struct VCD {
|
2022-05-21 02:52:26 +00:00
|
|
|
metadata : Metadata,
|
|
|
|
all_signals : Vec<SignalGeneric>,
|
|
|
|
// the root scope should always be placed at index 0
|
|
|
|
all_scopes : Vec<Scope>}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
enum Date_Parser_State {Weekday, Month, Day, HHMMSS, Year}
|
2022-05-22 00:40:46 +00:00
|
|
|
|
2022-05-21 02:52:26 +00:00
|
|
|
#[derive(Debug)]
|
|
|
|
enum VCD_Parser_State {
|
|
|
|
Begin,
|
|
|
|
Date(Date_Parser_State),
|
2022-05-22 00:40:46 +00:00
|
|
|
Parse_Version,
|
|
|
|
Parse_Signal_Tree,
|
|
|
|
Parse_Signal_Values}
|
2022-05-21 02:52:26 +00:00
|
|
|
|
|
|
|
struct DateBuffer {
|
|
|
|
Weekday : String,
|
|
|
|
Month : String,
|
|
|
|
Day : String,
|
|
|
|
HHMMSS : String,
|
|
|
|
Year : String}
|
|
|
|
|
|
|
|
struct VCD_Parser<'a> {
|
|
|
|
vcd_parser_state : VCD_Parser_State,
|
|
|
|
date_parser_state : Date_Parser_State,
|
|
|
|
date_buffer : DateBuffer,
|
|
|
|
|
2022-05-22 00:40:46 +00:00
|
|
|
vcd : &'a mut VCD,
|
2022-05-21 02:52:26 +00:00
|
|
|
curr_scope : &'a Scope,
|
|
|
|
curr_parent_scope : &'a Scope}
|
|
|
|
|
|
|
|
impl VCD {
|
|
|
|
pub fn new() -> Self {
|
|
|
|
let dt = Utc
|
|
|
|
.datetime_from_str("Thu Jan 1 00:00:00 1970", "%a %b %e %T %Y")
|
|
|
|
.unwrap();
|
|
|
|
let metadata = Metadata {
|
|
|
|
date : dt,
|
|
|
|
version : "".to_string(),
|
|
|
|
timescale : Timescale::ps};
|
|
|
|
let signal = Vec::<SignalGeneric>::new();
|
|
|
|
VCD {
|
|
|
|
metadata : metadata,
|
|
|
|
all_signals : Vec::<SignalGeneric>::new(),
|
|
|
|
all_scopes : Vec::<Scope>::new()}}}
|
|
|
|
|
|
|
|
impl<'a> VCD_Parser<'a> {
|
2022-05-22 00:40:46 +00:00
|
|
|
pub fn new(&mut self, vcd : &'a mut VCD) {
|
2022-05-21 02:52:26 +00:00
|
|
|
self.vcd_parser_state = VCD_Parser_State::Begin;
|
|
|
|
self.date_parser_state = Date_Parser_State::Weekday;
|
|
|
|
self.vcd = vcd;}
|
|
|
|
|
|
|
|
pub fn parse_word(&mut self, word : &str) -> Result<(), String> {
|
|
|
|
let mut state = &mut self.vcd_parser_state;
|
|
|
|
match state {
|
|
|
|
VCD_Parser_State::Begin => {
|
|
|
|
match word {
|
2022-05-22 00:40:46 +00:00
|
|
|
"$date" =>
|
|
|
|
{
|
|
|
|
*state = VCD_Parser_State::Date(Date_Parser_State::Weekday);
|
|
|
|
Ok(())
|
|
|
|
}
|
2022-05-21 02:52:26 +00:00
|
|
|
// "$version" => {*state = VCD_Parser_State::VERSION_ENTER; Ok(())},
|
|
|
|
// "$timescale" => {*state = VCD_Parser_State::TIMESCALE_ENTER; Ok(())},
|
|
|
|
_ => Err(format!("unsure what to do with {word:?}"))}},
|
|
|
|
|
2022-05-21 19:22:05 +00:00
|
|
|
VCD_Parser_State::Date(_) => self.parse_date(word),
|
2022-05-21 02:52:26 +00:00
|
|
|
_ => Err(format!("parser in bad state : {state:?}"))}
|
|
|
|
}
|
2022-05-19 07:44:24 +00:00
|
|
|
|
2022-05-21 02:52:26 +00:00
|
|
|
pub fn parse_date(&mut self, word : &str) -> Result<(), String> {
|
2022-05-21 19:22:05 +00:00
|
|
|
let mut state = &mut self.vcd_parser_state;
|
|
|
|
match state {
|
|
|
|
VCD_Parser_State::Date(Date_Parser_State::Weekday) =>
|
|
|
|
{
|
|
|
|
self.date_buffer.Weekday = word.to_string();
|
|
|
|
*state = VCD_Parser_State::Date(Date_Parser_State::Month);
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
VCD_Parser_State::Date(Date_Parser_State::Month) =>
|
|
|
|
{
|
|
|
|
self.date_buffer.Month = word.to_string();
|
|
|
|
*state = VCD_Parser_State::Date(Date_Parser_State::Day);
|
|
|
|
Ok(())
|
|
|
|
}
|
2022-05-22 00:40:46 +00:00
|
|
|
VCD_Parser_State::Date(Date_Parser_State::Day) =>
|
|
|
|
{
|
|
|
|
self.date_buffer.Day = word.to_string();
|
|
|
|
*state = VCD_Parser_State::Date(Date_Parser_State::HHMMSS);
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
VCD_Parser_State::Date(Date_Parser_State::HHMMSS) =>
|
|
|
|
{
|
|
|
|
self.date_buffer.HHMMSS = word.to_string();
|
|
|
|
*state = VCD_Parser_State::Date(Date_Parser_State::Year);
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
VCD_Parser_State::Date(Date_Parser_State::Year) =>
|
|
|
|
{
|
|
|
|
self.date_buffer.Year = word.to_string();
|
|
|
|
|
|
|
|
// now that we've successfully parsed all the date information,
|
|
|
|
// we store it to a d
|
|
|
|
let weekday = &self.date_buffer.Weekday;
|
|
|
|
let month = &self.date_buffer.Month;
|
|
|
|
let day = &self.date_buffer.Day;
|
|
|
|
let hhmmss = &self.date_buffer.HHMMSS;
|
|
|
|
let year = &self.date_buffer.Year;
|
|
|
|
|
|
|
|
let date = &format!("{weekday} {month} {day} {hhmmss} {year}")[..];
|
|
|
|
let dt = Utc.datetime_from_str(date, "%a %b %e %T %Y").unwrap();
|
|
|
|
|
|
|
|
self.vcd.metadata.date = dt;
|
|
|
|
|
|
|
|
*state = VCD_Parser_State::Parse_Version;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
_ => Err(format!("{state:?} should be unreachable within DateParser.")),
|
2022-05-21 19:22:05 +00:00
|
|
|
}
|
2022-05-21 02:52:26 +00:00
|
|
|
}
|
|
|
|
}
|
2022-04-14 04:50:37 +00:00
|
|
|
|
2022-05-21 02:52:26 +00:00
|
|
|
fn advance_VCD_parser_FSM(word: &str, mut state : VCD_Parser_State) {}
|
|
|
|
fn advance_Date_parser_FSM(word : &str, mut state : Date_Parser_State) {}
|
2022-05-19 07:44:24 +00:00
|
|
|
|
|
|
|
fn yield_word_and_apply(file : File, mut f : impl FnMut(&str)) {
|
2022-04-14 04:50:37 +00:00
|
|
|
let mut reader = io::BufReader::new(file);
|
|
|
|
|
2022-05-19 01:32:41 +00:00
|
|
|
let mut buffer = String::new();
|
2022-05-18 02:04:32 +00:00
|
|
|
let mut word_count = 0u64;
|
2022-05-19 02:57:42 +00:00
|
|
|
let mut EOF = false;
|
2022-05-19 01:32:41 +00:00
|
|
|
let line_chunk_size = 25;
|
2022-04-14 04:50:37 +00:00
|
|
|
|
2022-05-19 02:57:42 +00:00
|
|
|
while {!EOF} {
|
2022-05-19 01:32:41 +00:00
|
|
|
for _ in 0..line_chunk_size {
|
|
|
|
let bytes_read = reader.read_line(&mut buffer).unwrap();
|
|
|
|
if bytes_read == 0 {
|
2022-05-19 02:57:42 +00:00
|
|
|
EOF = true;
|
2022-05-19 01:32:41 +00:00
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
2022-05-19 00:47:55 +00:00
|
|
|
|
2022-05-19 01:32:41 +00:00
|
|
|
let words = buffer.split_ascii_whitespace();
|
|
|
|
|
|
|
|
for word in words {
|
2022-05-19 07:44:24 +00:00
|
|
|
f(word);
|
2022-05-19 01:32:41 +00:00
|
|
|
}
|
2022-05-19 00:47:55 +00:00
|
|
|
|
2022-05-19 01:32:41 +00:00
|
|
|
buffer.clear();
|
2022-04-14 04:50:37 +00:00
|
|
|
}
|
2022-05-19 01:32:41 +00:00
|
|
|
|
2022-05-19 02:57:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn main() -> std::io::Result<()> {
|
|
|
|
let args = Cli::parse();
|
|
|
|
|
2022-05-19 07:44:24 +00:00
|
|
|
// let dt = Utc.datetime_from_str("Fri Nov 28 12:00:09 2014", "%a %b %e %T %Y");
|
|
|
|
|
|
|
|
let file = File::open(&args.path)?;
|
2022-05-19 02:57:42 +00:00
|
|
|
let mut word_count = 0;
|
|
|
|
|
2022-05-19 07:44:24 +00:00
|
|
|
yield_word_and_apply(file, |word| {word_count += 1});
|
|
|
|
dbg!(word_count);
|
2022-04-14 04:50:37 +00:00
|
|
|
Ok(())
|
2022-05-21 19:22:05 +00:00
|
|
|
}
|