Fix operator precedence parsing
This commit is contained in:
		
							parent
							
								
									47b9d7e044
								
							
						
					
					
						commit
						c6e6e1dbee
					
				| @ -1,9 +1,9 @@ | ||||
| use reid::compile; | ||||
| 
 | ||||
| pub static EASIEST: &str = include_str!("./reid/easiest.reid"); | ||||
| pub static EASY: &str = include_str!("./reid/easy.reid"); | ||||
| 
 | ||||
| fn main() { | ||||
|     let text = match compile(EASIEST) { | ||||
|     let text = match compile(EASY) { | ||||
|         Ok(t) => t, | ||||
|         Err(e) => panic!("{}", e), | ||||
|     }; | ||||
|  | ||||
| @ -3,10 +3,10 @@ | ||||
| import std::print; | ||||
| 
 | ||||
| fn main() { | ||||
|     let test = 5; | ||||
|     let test = 9; | ||||
|     let simpleAdd = 2 + 2; | ||||
|     let simpleMult = 7 * 2; | ||||
|     let arithmetic = 3 + 2 * 5 + 1 * 2; | ||||
|     let multiplier = 5 * 2; | ||||
| 
 | ||||
|     return arithmetic + multiplier * arithmetic; | ||||
|     return arithmetic + simpleMult * arithmetic; | ||||
| } | ||||
							
								
								
									
										21
									
								
								src/ast.rs
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								src/ast.rs
									
									
									
									
									
								
							| @ -46,7 +46,7 @@ pub enum Expression { | ||||
| impl Parse for Expression { | ||||
|     fn parse(mut stream: TokenStream) -> Result<Expression, Error> { | ||||
|         let lhs = parse_primary_expression(&mut stream)?; | ||||
|         parse_binop_rhs(&mut stream, lhs, None) | ||||
|         parse_binop_rhs(&mut stream, lhs, 0, None).map(|(rhs, _)| rhs) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -81,27 +81,28 @@ fn parse_primary_expression(stream: &mut TokenStream) -> Result<Expression, Erro | ||||
| fn parse_binop_rhs( | ||||
|     stream: &mut TokenStream, | ||||
|     mut lhs: Expression, | ||||
|     expr_prec: i8, | ||||
|     mut operator: Option<BinaryOperator>, | ||||
| ) -> Result<Expression, Error> { | ||||
|     let expr_prec = if let Some(op) = operator { | ||||
|         op.get_precedence() + 1 | ||||
|     } else { | ||||
|         0 | ||||
|     }; | ||||
| 
 | ||||
| ) -> Result<(Expression, Option<BinaryOperator>), Error> { | ||||
|     while let Some(op) = operator.take().as_ref().or(stream.parse().as_ref().ok()) { | ||||
|         let curr_token_prec = op.get_precedence(); | ||||
| 
 | ||||
|         if curr_token_prec < expr_prec { | ||||
|             let _ = operator.insert(*op); | ||||
|             break; // Just return lhs
 | ||||
|         } else { | ||||
|             let mut rhs = parse_primary_expression(stream)?; | ||||
| 
 | ||||
|             if let Ok(next_op) = stream.parse::<BinaryOperator>() { | ||||
|                 let next_prec = next_op.get_precedence(); | ||||
|                 if curr_token_prec < next_prec { | ||||
|                     // Operator on the right of rhs has more precedence, turn
 | ||||
|                     // rhs into lhs for new binop
 | ||||
|                     rhs = parse_binop_rhs(stream, rhs, Some(next_op))?; | ||||
|                     let op; | ||||
|                     (rhs, op) = parse_binop_rhs(stream, rhs, curr_token_prec + 1, Some(next_op))?; | ||||
|                     if let Some(upcoming_op) = op { | ||||
|                         let _ = operator.insert(upcoming_op); | ||||
|                     } | ||||
|                 } else { | ||||
|                     let _ = operator.insert(next_op); | ||||
|                 } | ||||
| @ -111,7 +112,7 @@ fn parse_binop_rhs( | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     Ok(lhs) | ||||
|     Ok((lhs, operator)) | ||||
| } | ||||
| 
 | ||||
| #[derive(Debug, Clone, Copy)] | ||||
|  | ||||
| @ -57,7 +57,7 @@ impl<'a, 'b> TokenStream<'a, 'b> { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub fn parse<T: Parse>(&mut self) -> Result<T, Error> { | ||||
|     pub fn parse<T: Parse + std::fmt::Debug>(&mut self) -> Result<T, Error> { | ||||
|         let mut ref_pos = self.position; | ||||
| 
 | ||||
|         let position = self.position; | ||||
| @ -70,6 +70,7 @@ impl<'a, 'b> TokenStream<'a, 'b> { | ||||
|         match T::parse(clone) { | ||||
|             Ok(res) => { | ||||
|                 self.position = ref_pos.max(self.position); | ||||
|                 dbg!(&res); | ||||
|                 Ok(res) | ||||
|             } | ||||
|             Err(e) => Err(e), | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user