summaryrefslogtreecommitdiffstats
path: root/src/parser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.rs')
-rw-r--r--src/parser.rs124
1 files changed, 124 insertions, 0 deletions
diff --git a/src/parser.rs b/src/parser.rs
new file mode 100644
index 0000000..c57fe14
--- /dev/null
+++ b/src/parser.rs
@@ -0,0 +1,124 @@
+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<I: Iterator<Item=char>> {
+ iter: Peekable<I>
+}
+
+impl<I: Iterator<Item=char>> Lexer<I> {
+ pub fn new(iter: I) -> Lexer<I> {
+ Lexer {
+ iter: iter.peekable()
+ }
+ }
+}
+
+impl<I: Iterator<Item=char>> Iterator for Lexer<I> {
+ type Item = Token;
+
+ fn next(&mut self) -> Option<Token> {
+ // 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<Token> {
+ 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![],
+ }
+}