New parser #2

Merged
ThePerfectComputer merged 51 commits from new_parser into main 2022-08-01 21:00:00 +00:00
2 changed files with 87 additions and 87 deletions
Showing only changes of commit dad1fd2484 - Show all commits

View file

@ -8,4 +8,5 @@ edition = "2021"
[dependencies] [dependencies]
num = "0.4" num = "0.4"
clap = { version = "3.1.8", features = ["derive"] } clap = { version = "3.1.8", features = ["derive"] }
chrono = "0.4" chrono = "0.4"
function_name = "0.3.0"

View file

@ -4,6 +4,7 @@ use std::fs::File;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use chrono::prelude::*; use chrono::prelude::*;
use std::rc::Rc; use std::rc::Rc;
use ::function_name::named;
use num::*; use num::*;
use clap::Parser; use clap::Parser;
@ -59,32 +60,25 @@ struct VCD {
// the root scope should always be placed at index 0 // the root scope should always be placed at index 0
all_scopes : Vec<Scope>} all_scopes : Vec<Scope>}
// TODO : Date_PArser_State -> Parse_Date
#[derive(Debug)] #[derive(Debug)]
enum Date_Parser_State {Weekday, Month, Day, HHMMSS, Year, End} enum Date_Parser_State {Begin, Parsing}
#[derive(Debug)] #[derive(Debug)]
enum Version_Parser_State {Parsing, Done} enum Version_Parser_State {Begin, Parsing}
#[derive(Debug)]
enum Timescale_Parser_State {Begin, Parsing}
#[derive(Debug)] #[derive(Debug)]
enum VCD_Parser_State { enum Parser_State {
Begin,
Date(Date_Parser_State), Date(Date_Parser_State),
Parse_Version(Version_Parser_State), Version(Version_Parser_State),
Timescale(Timescale_Parser_State),
Parse_Signal_Tree, Parse_Signal_Tree,
Parse_Signal_Values} Parse_Signal_Values}
struct DateBuffer {
Weekday : Option<String>,
Month : Option<String>,
Day : Option<String>,
HHMMSS : Option<String>,
Year : Option<String>}
struct VCD_Parser<'a> { struct VCD_Parser<'a> {
vcd_parser_state : VCD_Parser_State, vcd_parser_state : Parser_State,
date_parser_state : Date_Parser_State, buffer : Option<String>,
date_buffer : DateBuffer,
vcd : &'a mut VCD, vcd : &'a mut VCD,
curr_scope : Option<&'a Scope>, curr_scope : Option<&'a Scope>,
@ -107,21 +101,13 @@ impl VCD {
impl<'a> VCD_Parser<'a> { impl<'a> VCD_Parser<'a> {
pub fn new(vcd : &'a mut VCD) -> Self { pub fn new(vcd : &'a mut VCD) -> Self {
let date_buffer = DateBuffer{
Weekday : None,
Month : None,
Day : None,
HHMMSS : None,
Year : None
};
VCD_Parser { VCD_Parser {
vcd_parser_state : VCD_Parser_State ::Begin, vcd_parser_state : Parser_State::Date(Date_Parser_State::Begin),
date_parser_state : Date_Parser_State::Weekday,
date_buffer : date_buffer, buffer : None,
vcd : vcd, vcd : vcd,
curr_scope : None, curr_scope : None,
curr_parent_scope : None curr_parent_scope : None
} }
} }
@ -129,13 +115,8 @@ impl<'a> VCD_Parser<'a> {
let mut state = &mut self.vcd_parser_state; let mut state = &mut self.vcd_parser_state;
let t = &self.vcd; let t = &self.vcd;
match state { match state {
VCD_Parser_State::Begin => Parser_State::Date(_) => self.parse_date(word),
match word { Parser_State::Version(_) => self.parse_version(word),
"$date" => {*state = VCD_Parser_State::Date(Date_Parser_State::Weekday); Ok(())}
_ => Err(format!("unsure what to do with {word:?} in state `{state:?}`"))
}
VCD_Parser_State::Date(_) => self.parse_date(word),
VCD_Parser_State::Parse_Version(_) => self.parse_date(word),
// TODO : Enable the following in production // TODO : Enable the following in production
// _ => Err(format!("parser in bad state : {state:?}"))TODO : Disable the following in production // _ => Err(format!("parser in bad state : {state:?}"))TODO : Disable the following in production
// TODO : Disable the following in production // TODO : Disable the following in production
@ -143,66 +124,84 @@ impl<'a> VCD_Parser<'a> {
} }
} }
#[named]
pub fn parse_date(&mut self, word : &str) -> Result<(), String> { pub fn parse_date(&mut self, word : &str) -> Result<(), String> {
let mut state = &mut self.vcd_parser_state; let mut state = &mut self.vcd_parser_state;
match state { match state {
VCD_Parser_State::Date(Date_Parser_State::Weekday) => Parser_State::Date(Date_Parser_State::Begin) =>
{
self.date_buffer.Weekday = Some(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 = Some(word.to_string());
*state = VCD_Parser_State::Date(Date_Parser_State::Day);
Ok(())
}
VCD_Parser_State::Date(Date_Parser_State::Day) =>
{
self.date_buffer.Day = Some(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 = Some(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 = Some(word.to_string());
// now that we've successfully parsed all the date information,
// we store it to the metadata.date struct
let weekday = &self.date_buffer.Weekday.as_ref().unwrap();
let month = &self.date_buffer.Month.as_ref().unwrap();
let day = &self.date_buffer.Day.as_ref().unwrap();
let hhmmss = &self.date_buffer.HHMMSS.as_ref().unwrap();
let year = &self.date_buffer.Year.as_ref().unwrap();
let date = &format!("{weekday} {month} {day} {hhmmss} {year}")[..];
let dt = Utc.datetime_from_str(date, "%a %b %e %T %Y")
.expect(&format!("invalid date {date}")[..]);
self.vcd.metadata.date = Some(dt);
*state = VCD_Parser_State::Date(Date_Parser_State::End);
Ok(())
}
VCD_Parser_State::Date(Date_Parser_State::End) =>
{
let expected_word = "$end";
match word { match word {
expected_word => { "$date" => {
*state = VCD_Parser_State::Parse_Version(Version_Parser_State::Parsing); *state = Parser_State::Date(Date_Parser_State::Parsing);
Ok(())
}
_ => {
*state = Parser_State::Version(Version_Parser_State::Begin);
self.parse_version(word);
Ok(()) Ok(())
} }
_ => Err(format!("expected `{expected_word}` but found `{word}`"))
} }
Parser_State::Date(Date_Parser_State::Parsing) =>
match word {
"$end" => {
*state = Parser_State::Version(Version_Parser_State::Begin);
let s = self.buffer.take().unwrap();
let dt = Utc.datetime_from_str(s.as_str(), "%a %b %e %T %Y")
.expect(&format!("invalid date {s}").as_str());
self.vcd.metadata.date = Some(dt);
Ok(())
}
_ => {
if let Some(ref mut buffer) = self.buffer {
buffer.push_str(" ");
buffer.push_str(word);
}
else {
self.buffer = Some(word.to_string());
}
Ok(())
}
} }
_ => Err(format!("{state:?} should be unreachable within DateParser.")), _ => Err(format!("{state:?} should be unreachable within {}.",function_name!())),
}
}
#[named]
pub fn parse_version(&mut self, word : &str) -> Result<(), String> {
let mut state = &mut self.vcd_parser_state;
match state {
Parser_State::Version(Version_Parser_State::Begin) =>
match word {
"$version" => {
*state = Parser_State::Version(Version_Parser_State::Parsing);
Ok(())
}
_ => {
*state = Parser_State::Timescale(Timescale_Parser_State::Begin);
Ok(())
}
}
Parser_State::Version(Version_Parser_State::Parsing) =>
match word {
"$end" => {
*state = Parser_State::Timescale(Timescale_Parser_State::Begin);
let s = self.buffer.take().unwrap();
self.vcd.metadata.version = Some(Version(s));
Ok(())
}
_ => {
if let Some(ref mut buffer) = self.buffer {
buffer.push_str(" ");
buffer.push_str(word);
}
else {
self.buffer = Some(word.to_string());
}
Ok(())
}
}
_ => Err(format!("{state:?} should be unreachable within {}.",function_name!())),
} }
} }
} }