ralc/src/main.rs

72 lines
1.8 KiB
Rust

use std::io;
#[derive(Debug, PartialEq, Eq)]
enum Symbol {
Number,
LeftBracket,
RightBracket,
Add,
Sub,
Mul,
Div,
}
#[derive(Debug)]
enum ParseError {
WrongTokenError { pos: usize },
}
fn main() {
loop {
let user_input = get_user_input().expect("No input");
match tokenize(&user_input) {
Ok(tokenized_input) => {
for el in &tokenized_input {
println!("{:?}", el);
}
}
Err(ParseError::WrongTokenError { pos }) => {
for _ in 0..pos {
print!("-");
}
println!("^");
println!("Syntax Error\n");
}
}
}
}
fn get_user_input() -> io::Result<String> {
let mut buffer = String::new();
let stdin = io::stdin();
stdin.read_line(&mut buffer)?;
Ok(buffer)
}
#[test]
fn try_tokenizing() {
let tokenized_input = tokenize("1 + 1").unwrap();
let result = vec![Symbol::Number, Symbol::Add, Symbol::Number];
assert!(tokenized_input == result, "1 + 1 not working");
}
fn tokenize(input: &str) -> Result<Vec<Symbol>, ParseError> {
let mut tokens: Vec<Symbol> = vec![];
for (i, c) in input.chars().enumerate() {
match c {
' ' => continue,
'(' => tokens.push(Symbol::LeftBracket),
')' => tokens.push(Symbol::RightBracket),
'+' => tokens.push(Symbol::Add),
'-' => tokens.push(Symbol::Sub),
'*' => tokens.push(Symbol::Mul),
'/' => tokens.push(Symbol::Div),
'0'..='9' => tokens.push(Symbol::Number),
'\n' => break,
_ => return Err(ParseError::WrongTokenError { pos: i }),
}
}
Ok(tokens)
}