Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Here is some rust code for how i did it (its part of a larger program so won't compile on its own)
- its initally called with precedence_level=0
- :
- let precedence: BTreeMap<&'static str, i16> = [
- ("=~", 1), ("-=", 1), ("+=", 1), ("*=", 1), ("/=", 1), ("=", 1),
- ("^=", 1), ("**=", 13), ("|=", 1), ("&=", 1), ("%=", 1),
- ("<<=", 1), (">>=", 1), ("||", 2), ("&&", 3), ("|", 4), ("^", 5),
- ("&", 6), ("==", 7), ("!=", 7), ("<", 8), (">", 8), ("<=", 8),
- (">=", 8), ("<<", 9), (">>", 9), ("+", 10), ("-", 10),
- ("*", 11), ("/", 11), ("%", 11), ("**", 12), ("..", 15),
- ]
- .into_iter()
- .collect();
- let right_associative: BTreeMap<&'static str, bool> = [
- ("=", true), ("**", true), ("**=", true), ("=~", true),
- ("+=", true), ("-=", true), ("*=", true), ("/=", true),
- ("^=", true), ("|=", true), ("&=", true), ("%=", true),
- ("<<=", true), (">>=", true),
- ]
- .into_iter()
- .collect();let precedence: BTreeMap<&'static str, i16> = [
- ("=~", 1), ("-=", 1), ("+=", 1), ("*=", 1), ("/=", 1), ("=", 1),
- ("^=", 1), ("**=", 13), ("|=", 1), ("&=", 1), ("%=", 1),
- ("<<=", 1), (">>=", 1), ("||", 2), ("&&", 3), ("|", 4), ("^", 5),
- ("&", 6), ("==", 7), ("!=", 7), ("<", 8), (">", 8), ("<=", 8),
- (">=", 8), ("<<", 9), (">>", 9), ("+", 10), ("-", 10),
- ("*", 11), ("/", 11), ("%", 11), ("**", 12), ("..", 15),
- ]
- .into_iter()
- .collect();
- let right_associative: BTreeMap<&'static str, bool> = [
- ("=", true), ("**", true), ("**=", true), ("=~", true),
- ("+=", true), ("-=", true), ("*=", true), ("/=", true),
- ("^=", true), ("|=", true), ("&=", true), ("%=", true),
- ("<<=", true), (">>=", true),
- ]
- .into_iter()
- .collect();
- async fn parse_expression(&mut self, precedence_level:i16) -> Object {
- // Scope parse_primary call to release mutable borrow of self before the loop
- let mut left = self.parse_primary().await;
- while self.pos<self.tokens.len() &&
- self.tokens[self.pos].name != TokenType::Eol &&
- self.tokens[self.pos].name != TokenType::BracketOpen &&
- self.tokens[self.pos].name != TokenType::BracketClose &&
- self.tokens[self.pos].name != TokenType::ParClose {
- let op=self.tokens[self.pos].value.clone();
- let mut prec=-1;
- if self.precedence.contains_key(op.clone().as_str()){
- prec=self.precedence[op.clone().as_str()];
- }
- if prec < precedence_level {
- break;
- }
- let mut is_right=false;
- if self.right_associative.contains_key(op.clone().as_str()){
- is_right=self.right_associative[op.clone().as_str()];
- }
- let next_precedence_level=if is_right {prec} else {prec+1};
- self.pos+=1;
- let right=self.parse_expression(next_precedence_level).await;
- let op_node =AST::new("operator", op.clone()).await;
- AST::add_child(&op_node, left).await;
- AST::add_child(&op_node, right).await;
- left= Arc::clone(&op_node);
- }
- return left;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement