1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
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<Token<'s>>
}
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<Predicate> = None;
for (i, ch) in self.text.char_indices() {
let token: Option<Token> = 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<Token> {
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![],
}
}
|