Put lexer into it's own file

This commit is contained in:
Kasper 2019-12-09 00:31:34 +01:00
parent 47768ee208
commit 1fe9214a62
3 changed files with 64 additions and 64 deletions

View File

@ -5,8 +5,5 @@ authors = ["Kasper <kasperkh.kh@gmail.com>"]
edition = "2018" edition = "2018"
[dependencies] [dependencies]
# logos = "0.9.7"
# num-traits = "0.2"
# num-rational = "0.2"
nom = "5.0" nom = "5.0"
decimal = "2.0.4" decimal = "2.0.4"

59
src/lexer.rs Normal file
View File

@ -0,0 +1,59 @@
use std::str::FromStr;
use decimal::d128;
use crate::{Token, TokenVector, Operator::*};
pub fn lex(input: &str) -> Result<TokenVector, String> {
let mut chars = input.chars().enumerate().peekable();
let mut tokens: TokenVector = vec![];
while let Some((index, current_char)) = chars.next() {
match current_char {
'+' => tokens.push(Token::Operator(Plus)),
'-' => tokens.push(Token::Operator(Minus)),
'*' => tokens.push(Token::Operator(Multiply)),
'/' => tokens.push(Token::Operator(Divide)),
'%' => tokens.push(Token::Operator(PercentOrModulo)),
'^' => tokens.push(Token::Operator(Caret)),
'!' => tokens.push(Token::Operator(Factorial)),
'(' => tokens.push(Token::Operator(LeftParen)),
')' => tokens.push(Token::Operator(RightParen)),
',' => continue,
value if value.is_whitespace() => continue,
value if value.is_alphabetic() => {
},
'.' | '0'..='9' => {
let start_index = index;
let mut end_index = index+1;
while let Some((_idk, current_char)) = chars.peek() {
if current_char == &'.' || current_char.is_digit(10) {
chars.next();
end_index += 1;
} else {
break;
}
}
match d128::from_str(&input[start_index..end_index]) {
Ok(number) => {
if d128::get_status().is_empty() {
tokens.push(Token::Number(number));
} else {
return Err(format!("Error parsing d128 number: {}", &input[start_index..end_index]));
}
},
Err(_e) => {
return Err("Error parsing d128 number (This should not happen because d128 does not throw errors)".to_owned());
}
};
},
_ => {
return Err(format!("Unknown character: {}", current_char));
},
}
};
return Ok(tokens)
}

View File

@ -1,9 +1,8 @@
use std::time::{Instant}; use std::time::{Instant};
use decimal::d128; use decimal::d128;
use std::str::FromStr;
#[derive(Debug)] #[derive(Debug)]
enum Operator { pub enum Operator {
Plus, Plus,
Minus, Minus,
Multiply, Multiply,
@ -14,71 +13,16 @@ enum Operator {
LeftParen, LeftParen,
RightParen, RightParen,
} }
use Operator::*;
#[derive(Debug)] #[derive(Debug)]
enum Token { pub enum Token {
Operator(Operator), Operator(Operator),
Number(d128), Number(d128),
} }
type TokenVector = Vec<Token>; pub type TokenVector = Vec<Token>;
fn lex(input: &str) -> Result<TokenVector, String> { mod lexer;
let mut chars = input.chars().enumerate().peekable();
let mut tokens: TokenVector = vec![];
while let Some((index, current_char)) = chars.next() {
match current_char {
'+' => tokens.push(Token::Operator(Plus)),
'-' => tokens.push(Token::Operator(Minus)),
'*' => tokens.push(Token::Operator(Multiply)),
'/' => tokens.push(Token::Operator(Divide)),
'%' => tokens.push(Token::Operator(PercentOrModulo)),
'^' => tokens.push(Token::Operator(Caret)),
'!' => tokens.push(Token::Operator(Factorial)),
'(' => tokens.push(Token::Operator(LeftParen)),
')' => tokens.push(Token::Operator(RightParen)),
',' => continue,
value if value.is_whitespace() => continue,
value if value.is_alphabetic() => {
},
'.' | '0'..='9' => {
let start_index = index;
let mut end_index = index+1;
while let Some((_idk, current_char)) = chars.peek() {
if current_char == &'.' || current_char.is_digit(10) {
chars.next();
end_index += 1;
} else {
break;
}
}
match d128::from_str(&input[start_index..end_index]) {
Ok(number) => {
if d128::get_status().is_empty() {
tokens.push(Token::Number(number));
} else {
return Err(format!("Error parsing d128 number: {}", &input[start_index..end_index]));
}
},
Err(_e) => {
return Err("Error parsing d128 number (This should not happen because d128 does not throw errors)".to_owned());
}
};
},
_ => {
return Err(format!("Unknown character: {}", current_char));
},
}
};
return Ok(tokens)
}
fn main() { fn main() {
let now = Instant::now(); let now = Instant::now();
@ -87,7 +31,7 @@ fn main() {
let args: Vec<String> = env::args().collect(); let args: Vec<String> = env::args().collect();
let s = if args.len() == 2 { &args[1] } else { "0.1" }; let s = if args.len() == 2 { &args[1] } else { "0.1" };
match lex(s) { match lexer::lex(s) {
Ok(vector) => println!("{:?}", vector), Ok(vector) => println!("{:?}", vector),
Err(e) => println!("lexing error: {}", e), Err(e) => println!("lexing error: {}", e),
} }