diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 112 |
1 files changed, 43 insertions, 69 deletions
diff --git a/src/main.rs b/src/main.rs index 7e2057c..c9d02f7 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -1,82 +1,56 @@ | |||
1 | use std::str; | ||
2 | |||
3 | #[derive(Debug)] | 1 | #[derive(Debug)] |
4 | struct Token { | 2 | enum Token { |
5 | kind: String, | 3 | Operator(char), |
6 | val: String, | 4 | Num(f64), |
5 | Paren(char) | ||
7 | } | 6 | } |
8 | 7 | ||
9 | fn main() { | 8 | fn main() { |
10 | let input: &str = "2y + 11(1 + 2 + 3) + 12 / 4"; | 9 | let input = "11(12)"; |
11 | let input = input.replace(" ", ""); | 10 | let input = input.replace(" ", ""); |
12 | println!("{}", input); | ||
13 | 11 | ||
14 | let mut num_vec: String = String::new(); | 12 | let lexed = lexer(&input); |
15 | let mut char_vec: String = String::new(); | ||
16 | 13 | ||
17 | let mut result: Vec<Token> = vec![]; | 14 | println!("{:?}", lexed); |
15 | } | ||
18 | 16 | ||
17 | fn lexer(input: &str) -> Result<Vec<Token>, String> { | ||
18 | let mut num_vec: String = String::new(); | ||
19 | let mut result: Vec<Token> = vec![]; | ||
19 | for letter in input.chars() { | 20 | for letter in input.chars() { |
20 | if letter.is_digit(10) { | 21 | match letter { |
21 | num_vec.push(letter); | 22 | '0'...'9' | '.' => { |
22 | } else if letter == '.' { | 23 | num_vec.push(letter); |
23 | num_vec.push(letter); | 24 | }, |
24 | } else if letter.is_alphabetic() { | 25 | '+' | '-' | '/' | '*' | '^' => { |
25 | drain_buffer("Literal", &num_vec[..], &mut result); | 26 | let parse_num = num_vec.parse::<f64>().ok(); |
26 | char_vec.push(letter); | 27 | if let Some(x) = parse_num { |
27 | num_vec.clear(); | 28 | result.push(Token::Num(x)); |
28 | } else if is_operator(letter) { | 29 | num_vec.clear(); |
29 | drain_buffer("Literal", &num_vec[..], &mut result); | 30 | } |
30 | num_vec.clear(); | 31 | result.push(Token::Paren(letter)); |
31 | drain_buffer("Variable", &char_vec[..], &mut result); | 32 | }, |
32 | char_vec.clear(); | 33 | '(' => { |
33 | result.push(Token { kind: "Operator".into(), val: letter.to_string() }); | 34 | let parse_num = num_vec.parse::<f64>().ok(); |
34 | } else if letter == '(' { | 35 | if let Some(x) = parse_num { |
35 | if char_vec.len() > 0 { | 36 | result.push(Token::Num(x)); |
36 | drain_buffer("Function", &char_vec[..], &mut result); | 37 | result.push(Token::Operator('*')); |
37 | char_vec.clear(); | 38 | num_vec.clear(); |
38 | } else if num_vec.len() > 0 { | 39 | } |
39 | drain_buffer("Literal", &num_vec[..], &mut result); | 40 | result.push(Token::Paren(letter)); |
40 | result.push( Token{kind: "Operator".into(), val: "*".to_string()} ); | 41 | }, |
41 | num_vec.clear(); | 42 | ')' => { |
43 | let parse_num = num_vec.parse::<f64>().ok(); | ||
44 | if let Some(x) = parse_num { | ||
45 | result.push(Token::Num(x)); | ||
46 | num_vec.clear(); | ||
47 | } | ||
48 | result.push(Token::Paren(letter)); | ||
49 | } | ||
50 | _ => { | ||
51 | return Err(format!("Unexpected character: {}", letter)) | ||
42 | } | 52 | } |
43 | result.push( Token{kind: "Left Paren".into(), val: letter.to_string()} ); | ||
44 | } else if letter == ')' { | ||
45 | drain_buffer("Literal", &num_vec[..], &mut result); | ||
46 | num_vec.clear(); | ||
47 | drain_buffer("Variable", &char_vec[..], &mut result); | ||
48 | char_vec.clear(); | ||
49 | result.push(Token { kind: "Right Paren".into(), val: letter.to_string() }); | ||
50 | } else if letter == ',' { | ||
51 | drain_buffer("Literal", &num_vec[..], &mut result); | ||
52 | num_vec.clear(); | ||
53 | drain_buffer("Variable", &char_vec[..], &mut result); | ||
54 | char_vec.clear(); | ||
55 | result.push(Token { kind: "Function Arg Separator".into(), val: letter.to_string() }); | ||
56 | } | 53 | } |
57 | } | 54 | } |
58 | drain_buffer("Literal", &num_vec[..], &mut result); | 55 | Ok(result) |
59 | num_vec.clear(); | ||
60 | drain_buffer("Variable", &char_vec[..], &mut result); | ||
61 | char_vec.clear(); | ||
62 | for token in &result { | ||
63 | println!("{} => {}", token.kind, token.val); | ||
64 | } | ||
65 | } | ||
66 | |||
67 | fn drain_buffer(k: &str, v: &str, result: &mut Vec<Token>) { | ||
68 | if v.len() > 0 { | ||
69 | let token = Token { | ||
70 | kind: k.into(), | ||
71 | val: v.chars().collect::<String>() | ||
72 | }; | ||
73 | result.push(token); | ||
74 | } | ||
75 | } | ||
76 | |||
77 | fn is_operator(x: char) -> bool { | ||
78 | match x { | ||
79 | '+' | '-' | '/' | '*' | '^' => true, | ||
80 | _ => false | ||
81 | } | ||
82 | } | 56 | } |