z2oh

Untitled

Jul 19th, 2018
216
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 5.42 KB | None | 0 0
  1. // This is a custom implementation of nom::recognize_float that does not parse
  2. // the optional sign before the number, so that expressions like `x+3` parse
  3. // correctly and not as `x(+3)`.
  4. named!(recognize_float<CompleteStr, CompleteStr>,
  5.   recognize!(
  6.     tuple!(
  7.       alt!(
  8.         value!((), tuple!(nom::digit, opt!(pair!(char!('.'), opt!(nom::digit)))))
  9.       | value!((), tuple!(char!('.'), nom::digit))
  10.       ),
  11.       opt!(tuple!(
  12.         alt!(char!('e') | char!('E')),
  13.         nom::digit
  14.         )
  15.       )
  16.     )
  17.   )
  18. );
  19.  
  20. named!(parse_double<CompleteStr, f64>,
  21.     flat_map!(recognize_float, parse_to!(f64))
  22. );
  23.  
  24. named!(parse_constant<CompleteStr, ExpressionNode>,
  25.     do_parse!(
  26.         value: parse_double >>
  27.         (ExpressionNode::ConstantExprNode { value, })
  28.     )
  29. );
  30.  
  31. named!(parse_variable<CompleteStr, ExpressionNode>,
  32.     do_parse!(
  33.         var: take_while1!(|x| nom::is_alphabetic(x as u8)) >>
  34.         (ExpressionNode::VariableExprNode { variable_key: var.to_string(), })
  35.     )
  36. );
  37.  
  38. named!(parse_coefficient<CompleteStr, ExpressionNode>,
  39.     do_parse!(
  40.         coefficient: parse_priority_1 >>
  41.         res: parse_priority_1 >>
  42.         (ExpressionNode::BinaryExprNode {
  43.             operator: BinaryOperator::Multiplication,
  44.             left_node: Box::new(coefficient),
  45.             right_node: Box::new(res),
  46.         })
  47.     )
  48. );
  49.  
  50. named!(parse_parens<CompleteStr, ExpressionNode>,
  51.     delimited!( char!('('), parse_expr, char!(')') )
  52. );
  53.  
  54. named!(parse_sin<CompleteStr, ExpressionNode>,
  55.     do_parse!(
  56.         tag!("sin") >>
  57.         res: parse_parens >>
  58.         (ExpressionNode::UnaryExprNode {
  59.             operator: UnaryOperator::Sin,
  60.             child_node: Box::new(res),
  61.         })
  62.     )
  63. );
  64.  
  65. named!(parse_cos<CompleteStr, ExpressionNode>,
  66.     do_parse!(
  67.         tag!("cos") >>
  68.         res: parse_parens >>
  69.         (ExpressionNode::UnaryExprNode {
  70.             operator: UnaryOperator::Cos,
  71.             child_node: Box::new(res),
  72.         })
  73.     )
  74. );
  75.  
  76. named!(parse_expr<CompleteStr, ExpressionNode>,
  77.     call!(parse_priority_4)
  78. );
  79.  
  80. named!(parse_priority_0<CompleteStr, ExpressionNode>,
  81.     alt_complete!(
  82.         parse_constant   |
  83.         parse_variable   |
  84.         parse_parens     |
  85.         parse_parens     |
  86.         parse_sin        |
  87.         parse_cos
  88.     )
  89. );
  90.  
  91. named!(parse_priority_1<CompleteStr, ExpressionNode>,
  92.     do_parse!(
  93.         init: parse_priority_0 >>
  94.         res: fold_many0!(
  95.             pair!(alt!(tag!("^")), parse_priority_0),
  96.             init,
  97.             |acc, (op, val): (CompleteStr, ExpressionNode)| {
  98.                 let operator = match op.as_bytes()[0] as char {
  99.                     '^' => BinaryOperator::Exponentiation,
  100.                     // For now, default to Exponentiatino.
  101.                     _ => BinaryOperator::Exponentiation,
  102.                 };
  103.                 ExpressionNode::BinaryExprNode {
  104.                     operator,
  105.                     left_node: Box::new(val),
  106.                     right_node: Box::new(acc),
  107.                 }
  108.             }
  109.         ) >>
  110.         (res)
  111.     )
  112. );
  113.  
  114. named!(parse_priority_2<CompleteStr, ExpressionNode>,
  115.     alt_complete!(
  116.         parse_coefficient |
  117.         do_parse!(
  118.             init: parse_priority_1 >>
  119.             res: fold_many0!(
  120.                 pair!(alt!(tag!("*") | tag!("/")), parse_priority_1),
  121.                 init,
  122.                 |acc, (op, val): (CompleteStr, ExpressionNode)| {
  123.                     let operator = match op.as_bytes()[0] as char {
  124.                         '*' => BinaryOperator::Multiplication,
  125.                         '/' => BinaryOperator::Division,
  126.                         // For now, default to Multiplication.
  127.                         _   => BinaryOperator::Multiplication,
  128.                     };
  129.                     ExpressionNode::BinaryExprNode {
  130.                         operator,
  131.                         left_node: Box::new(acc),
  132.                         right_node: Box::new(val),
  133.                     }
  134.                 }
  135.             ) >>
  136.             (res)
  137.         )
  138.     )
  139. );
  140.  
  141. named!(parse_priority_3<CompleteStr, ExpressionNode>,
  142.     alt_complete!(
  143.         do_parse!(
  144.             op: alt!(tag!("-")) >>
  145.             res: parse_priority_2 >>
  146.             (ExpressionNode::UnaryExprNode {
  147.                 operator: match op.as_bytes()[0] as char {
  148.                     '-' => UnaryOperator::Negation,
  149.                     // For now, default to Negation.
  150.                     _ => UnaryOperator::Negation,
  151.                 },
  152.                 child_node: Box::new(res),
  153.             })
  154.         ) |
  155.         parse_priority_2
  156.     )
  157. );
  158.  
  159. named!(parse_priority_4<CompleteStr, ExpressionNode>,
  160.     do_parse!(
  161.         init: parse_priority_3 >>
  162.         res: fold_many0!(
  163.             pair!(alt!(tag!("+") | tag!("-")), parse_priority_3),
  164.             init,
  165.             |acc, (op, val): (CompleteStr, ExpressionNode)| {
  166.                 let operator = match op.as_bytes()[0] as char {
  167.                     '+' => BinaryOperator::Addition,
  168.                     '-' => BinaryOperator::Subtraction,
  169.                     // For now, default to Addition.
  170.                     _   => BinaryOperator::Addition,
  171.                 };
  172.                 ExpressionNode::BinaryExprNode {
  173.                     operator,
  174.                     left_node: Box::new(acc),
  175.                     right_node: Box::new(val),
  176.                 }
  177.             }
  178.         ) >>
  179.         (res)
  180.     )
  181. );
Advertisement
Add Comment
Please, Sign In to add comment