use crate::journal::Journal; use std::fs; use std::iter::Peekable; extern crate itertools; extern crate time; use itertools::Itertools; use time::Date; #[derive(Debug, Eq, PartialEq, Clone)] pub enum Token { Word(String), DateSep, AccountSep, DecimalSep, Newline, Space, Indent, Marker(char), Comment(char), Numeric(String), } pub struct Lexer> { iter: Peekable } impl> Lexer { pub fn new(iter: I) -> Lexer { Lexer { iter: iter.peekable() } } } impl> Iterator for Lexer { type Item = Token; fn next(&mut self) -> Option { // let ch = *self.iter.peek().unwrap_or(&'`'); let ch = self.iter.peek() match ch { /* alphanumeric */ c if c.is_alphabetic() => { Some(Token::Word(self.iter.by_ref() .peeking_take_while(|&c| c.is_alphabetic()).collect())) }, c if c.is_numeric() => { Some(Token::Numeric(self.iter.by_ref() .peeking_take_while(|&c| c.is_numeric()).collect())) }, /* whitespace */ ' ' => { self.iter.next(); Some(Token::Space) }, '\n' => { self.iter.next(); Some(Token::Newline) }, '\t' => { self.iter.next(); Some(Token::Indent) }, /* separators */ '/' => { self.iter.next(); Some(Token::DateSep) }, ':' => { self.iter.next(); Some(Token::AccountSep) }, ',' | '.' => { self.iter.next(); Some(Token::DecimalSep) }, /* comments */ ';' | '#' | '%' => { self.iter.next(); Some(Token::Comment(ch)) }, /* markers */ '*' | '!' | '@' | '-' => { self.iter.next(); Some(Token::Marker(ch)) }, '`' => { println!("--"); None }, _ => self.next(), } } } pub fn lex(text: &str) -> Vec { Lexer::new(text.chars()).collect() } struct Parser { } pub fn parse(name: &str) -> Journal { let text = fs::read_to_string(name).expect("Cannot open file"); println!("{:?}", text); for token in lex(&text) { println!("{:?}", token); } Journal { accounts: vec![], commodities: vec![], transactions: vec![], } }