use crate::journal::Journal; use std::fs; extern crate time; use time::Date; #[derive(Debug, Eq, PartialEq, Clone)] pub enum Token<'s> { Word(&'s str), Num(&'s str), DecimalSep(char), Newline, Space, Indent, OpenKet(char), CloseKet(char), Quote, Marker(char), CommentMarker, } struct Lexer<'s> { text: &'s str, tokens: Vec> } impl<'s> Lexer<'s> { fn new(input: &str) -> Lexer { Lexer { text: input, tokens: Vec::new(), } } fn lex(&mut self) { #[derive(Clone,Copy)] enum Predicate { Alphabetic, Numeric, } let mut start = 0; let mut lastp: Option = None; for (i, ch) in self.text.char_indices() { let token: Option = match ch { '\t' => Some(Token::Indent), '\n' => Some(Token::Newline), c if c.is_whitespace() => Some(Token::Space), '"' => Some(Token::Quote), ',' | '.' => Some(Token::DecimalSep(ch)), '(' | '[' | '{' => Some(Token::OpenKet(ch)), ')' | ']' | '}' => Some(Token::CloseKet(ch)), ';' | '#' | '%' => Some(Token::CommentMarker), '*' | '!' | '@' | '-' | '/' | ':' => Some(Token::Marker(ch)), c if c.is_alphabetic() => { lastp = Some(Predicate::Alphabetic); None }, c if c.is_numeric() => { lastp = Some(Predicate::Numeric); None }, _ => { println!("Invalid syntax token: {}", ch); None } }; if let Some(t) = token { if let Some(p) = lastp { if i != start { self.tokens.push(match p { Predicate::Alphabetic => Token::Word(&self.text[start..i]), Predicate::Numeric => Token::Num(&self.text[start..i]), }); } } self.tokens.push(t); start = i +1; } } } fn tokenize(input: & str) -> Vec { let mut lexer = Lexer::new(input); lexer.lex(); lexer.tokens } } struct Parser { } pub fn parse(name: &str) -> Journal { let text = fs::read_to_string(name).expect("Cannot open file"); println!("{:?}", text); for token in Lexer::tokenize(&text) { println!("{:?}", token); } Journal { accounts: vec![], commodities: vec![], transactions: vec![], } }