shunting yard works for text
This commit is contained in:
parent
a518550cf1
commit
87b761b85c
|
@ -11,11 +11,13 @@
|
|||
* expression parser.
|
||||
*/
|
||||
|
||||
#[derive(PartialEq)]
|
||||
enum Associativity {
|
||||
Right,
|
||||
Left
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub struct Operator {
|
||||
character: char,
|
||||
precedence: u8,
|
||||
|
@ -29,6 +31,17 @@ impl Operator {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn get_operator(c: char) -> Option<Operator> {
|
||||
match c {
|
||||
'+' => Some(ADDITION),
|
||||
'-' => Some(SUBTRACTION),
|
||||
'*' => Some(MULTIPLICATION),
|
||||
'/' => Some(DIVISION),
|
||||
'^' => Some(EXPONENTIATION),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ADDITION: Operator = Operator {
|
||||
|
@ -58,7 +71,7 @@ const DIVISION: Operator = Operator {
|
|||
const EXPONENTIATION: Operator = Operator {
|
||||
character: '*',
|
||||
precedence: 2,
|
||||
associativity: Associativity::Left
|
||||
associativity: Associativity::Right
|
||||
};
|
||||
|
||||
const OPERATORS: [Operator; 5] = [ADDITION, SUBTRACTION, MULTIPLICATION, DIVISION, EXPONENTIATION];
|
||||
|
@ -68,38 +81,78 @@ pub fn form_reverse_polish_notation(regular_math: &str) -> Result<String, String
|
|||
let mut input_queue: Vec<char> = regular_math.chars().rev().collect();
|
||||
let mut operator_stack: Vec<char> = Vec::new();
|
||||
|
||||
// process all tokens first.
|
||||
// while there are tokens to br read:
|
||||
while !(input_queue.is_empty()) {
|
||||
let token: char = *(input_queue.last().unwrap());
|
||||
input_queue.pop();
|
||||
// read a token
|
||||
let token: char = input_queue.pop().unwrap();
|
||||
dbg!(&token);
|
||||
|
||||
// if the token is:
|
||||
// a number:
|
||||
if token.is_numeric() {
|
||||
println!("number");
|
||||
}
|
||||
else if Operator::is_operator(token) {
|
||||
println!("operator");
|
||||
}
|
||||
// Unnessecary, will be processed by the expression parser
|
||||
//else if '(' == token {
|
||||
// println!("(");
|
||||
//}
|
||||
//else if ')' == token {
|
||||
// println!(")");
|
||||
//}
|
||||
else {
|
||||
eprintln!("Unrecognized token: '{token}'");
|
||||
std::process::exit(1);
|
||||
// put it into the output_queue
|
||||
output_queue.push(token);
|
||||
}
|
||||
// a function
|
||||
// handled by the expression parser
|
||||
|
||||
// a operator o1
|
||||
else if Operator::is_operator(token) {
|
||||
// (get the constant Operator (which is a struct) that fits to that token.)
|
||||
let o1 = match Operator::get_operator(token) {
|
||||
Some(valid_op) => valid_op,
|
||||
None => {panic!("Operator '{token}' not found.");},
|
||||
};
|
||||
|
||||
// while there is an operator o2 at the top of the stack
|
||||
if !operator_stack.is_empty() {
|
||||
dbg!(&operator_stack);
|
||||
dbg!(&operator_stack);
|
||||
let o2 = match Operator::get_operator(*(operator_stack.clone().last().clone().unwrap())) {
|
||||
Some(valid_op) => valid_op,
|
||||
None => {panic!("Operator '{token}' not found.");},
|
||||
};
|
||||
// and
|
||||
// (o2 has greater precedence than o1 or (o1 and o2 have the same precedence and o1
|
||||
// is left associative))
|
||||
while ((operator_stack.last().is_some()) & ((o2.precedence > o1.precedence) | ((o1.precedence == o2.precedence) & (o1.associativity == Associativity::Left)))) {
|
||||
dbg!(&operator_stack);
|
||||
println!("REACHED THE MAGIC WHILE");
|
||||
// pop o2 from the operator stack into the output queue.
|
||||
// after this debug statement, the operator_stack is empty for no reason!!!!
|
||||
// FIXME
|
||||
let my_c = match operator_stack.pop() {
|
||||
Some(c) => c,
|
||||
None => {panic!("weirdly gone!")},
|
||||
};
|
||||
output_queue.push(my_c);
|
||||
}
|
||||
}
|
||||
operator_stack.push(o1.character);
|
||||
}
|
||||
/*
|
||||
// Unnessecary, will be processed by the expression parser
|
||||
else if '(' == token {
|
||||
println!("(");
|
||||
}
|
||||
else if ')' == token {
|
||||
println!(")");
|
||||
}
|
||||
*/
|
||||
else {
|
||||
return Err("Unrecognized token: '{token}'".to_string());
|
||||
}
|
||||
}
|
||||
dbg!(&output_queue);
|
||||
|
||||
// afterwards, process any operators still on the operator_stack
|
||||
while !(operator_stack.is_empty()) {
|
||||
todo!();
|
||||
output_queue.push(operator_stack.pop().unwrap());
|
||||
}
|
||||
|
||||
Ok("TODO".to_string())
|
||||
dbg!(&output_queue);
|
||||
let rpn: String = output_queue.iter().cloned().collect::<String>();
|
||||
Ok(rpn)
|
||||
}
|
||||
|
||||
// after we have the rpn, we may want to calculate the values with it.
|
||||
|
|
Reference in New Issue