diff options
author | NerdyPepper <[email protected]> | 2019-03-20 16:39:12 +0000 |
---|---|---|
committer | NerdyPepper <[email protected]> | 2019-03-20 16:39:12 +0000 |
commit | 38d3446d46ece5a993b797fdb7b56d280c2e9422 (patch) | |
tree | be673ee395846b5f58842f21f1bffb694ee990cd | |
parent | f1c5f96ed4ab72a5d2f9ef2abb9645ae24d9e60e (diff) |
fix major parser bug
-rw-r--r-- | src/main.rs | 36 |
1 files changed, 17 insertions, 19 deletions
diff --git a/src/main.rs b/src/main.rs index 06d650e..5f75843 100644 --- a/src/main.rs +++ b/src/main.rs | |||
@@ -15,7 +15,7 @@ pub struct Function { | |||
15 | relation: fn(f64) -> f64, | 15 | relation: fn(f64) -> f64, |
16 | } | 16 | } |
17 | 17 | ||
18 | #[derive(Debug, Clone)] | 18 | #[derive(Debug, Clone, PartialEq)] |
19 | pub enum Token { | 19 | pub enum Token { |
20 | Operator(Operator), | 20 | Operator(Operator), |
21 | Num(f64), | 21 | Num(f64), |
@@ -162,6 +162,16 @@ fn lexer(input: &str) -> Result<Vec<Token>, String> { | |||
162 | Ok(result) | 162 | Ok(result) |
163 | } | 163 | } |
164 | 164 | ||
165 | fn tilt_until(operators: &mut Vec<Token>, output: &mut Vec<Token>, stop: Token) -> bool { | ||
166 | while let Some(token) = operators.pop() { | ||
167 | if token == stop { | ||
168 | return true; | ||
169 | } | ||
170 | output.push(token) | ||
171 | } | ||
172 | false | ||
173 | } | ||
174 | |||
165 | fn to_postfix(tokens: Vec<Token>) -> Result<Vec<Token>, String> { | 175 | fn to_postfix(tokens: Vec<Token>) -> Result<Vec<Token>, String> { |
166 | let mut postfixed: Vec<Token> = vec![]; | 176 | let mut postfixed: Vec<Token> = vec![]; |
167 | let mut op_stack: Vec<Token> = vec![]; | 177 | let mut op_stack: Vec<Token> = vec![]; |
@@ -179,10 +189,10 @@ fn to_postfix(tokens: Vec<Token>) -> Result<Vec<Token>, String> { | |||
179 | Token::LParen => { | 189 | Token::LParen => { |
180 | break; | 190 | break; |
181 | } | 191 | } |
182 | Token::Operator(top_op) => { | 192 | Token::Operator(x) => { |
183 | let tp = top_op.precedence; | 193 | let tp = x.precedence; |
184 | let cp = current_op.precedence; | 194 | let cp = current_op.precedence; |
185 | if tp > cp || (tp == cp && top_op.is_left_associative) { | 195 | if tp > cp || (tp == cp && x.is_left_associative) { |
186 | postfixed.push(op_stack.pop().unwrap()); | 196 | postfixed.push(op_stack.pop().unwrap()); |
187 | } else { | 197 | } else { |
188 | break; | 198 | break; |
@@ -192,7 +202,7 @@ fn to_postfix(tokens: Vec<Token>) -> Result<Vec<Token>, String> { | |||
192 | postfixed.push(op_stack.pop().unwrap()); | 202 | postfixed.push(op_stack.pop().unwrap()); |
193 | } | 203 | } |
194 | _ => { | 204 | _ => { |
195 | return Err(format!("Unexpected match branch part 2")) | 205 | return Err(format!("{:?} must not be on operator stack", top_op)) |
196 | } | 206 | } |
197 | } | 207 | } |
198 | } | 208 | } |
@@ -202,20 +212,8 @@ fn to_postfix(tokens: Vec<Token>) -> Result<Vec<Token>, String> { | |||
202 | op_stack.push(token); | 212 | op_stack.push(token); |
203 | }, | 213 | }, |
204 | Token::RParen => { | 214 | Token::RParen => { |
205 | let mut found: bool = false; | 215 | if !tilt_until(&mut op_stack, &mut postfixed, Token::LParen) { |
206 | while let Some(top_op) = op_stack.last() { | 216 | return Err(String::from("Mismatched ')'")); |
207 | match top_op { | ||
208 | Token::LParen => { | ||
209 | let _ = op_stack.pop().unwrap(); | ||
210 | found = true; | ||
211 | }, | ||
212 | _ => { | ||
213 | postfixed.push(op_stack.pop().unwrap()); | ||
214 | } | ||
215 | } | ||
216 | } | ||
217 | if found == false { | ||
218 | return Err(format!("Mismatched parentheses part 2")) | ||
219 | } | 217 | } |
220 | } | 218 | } |
221 | 219 | ||