Advertisement
Guest User

Untitled

a guest
May 27th, 2016
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.33 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Text.RegularExpressions;
  6. using System.Threading.Tasks;
  7.  
  8. namespace ExpressionParser
  9. {
  10. public class ExpressionParser
  11. {
  12. private static Dictionary<string, int> precedence = new Dictionary<string, int>
  13. {
  14. ["("] = -1,
  15. ["+"] = 2,
  16. ["-"] = 2,
  17. ["*"] = 3,
  18. ["/"] = 3,
  19. ["^"] = 4,
  20. };
  21. public decimal Parse(string expression)
  22. {
  23. var tokens = Tokenize(expression);
  24. var postfixTokens = AsPostfix(tokens);
  25.  
  26. return ReducePostfix(postfixTokens);
  27. }
  28.  
  29. private decimal ReducePostfix(string[] postfixTokens)
  30. {
  31. var stack = new Stack<decimal>();
  32. foreach (var token in postfixTokens)
  33. {
  34. if (IsNumber(token))
  35. {
  36. stack.Push(Decimal.Parse(token));
  37. }
  38. else
  39. {
  40. var b = stack.Pop();
  41. var a = stack.Pop();
  42.  
  43. stack.Push(Result(token, a, b));
  44. }
  45. }
  46. return stack.Pop();
  47. }
  48.  
  49. private decimal Result(string token, decimal a, decimal b)
  50. {
  51. switch (token)
  52. {
  53. case "+":
  54. return a + b;
  55. case "-":
  56. return a - b;
  57. case "/":
  58. return a / b;
  59. case "*":
  60. return a * b;
  61. case "^":
  62. return (decimal)Math.Pow((double)a, (double)b);
  63. default:
  64. throw new SyntaxException();
  65. }
  66. }
  67.  
  68. private string[] AsPostfix(string[] tokens)
  69. {
  70. var stack = new Stack<string>();
  71. var outputQueue = new Queue<string>();
  72. foreach (var token in tokens)
  73. {
  74. if(String.IsNullOrWhiteSpace(token))
  75. {
  76. //do nothing
  77. }
  78. else if (IsNumber(token))
  79. {
  80. outputQueue.Enqueue(token);
  81. }
  82. else if (IsOperator(token))
  83. {
  84. while (stack.Any())
  85. {
  86. var tokenOperator = token;
  87. var stackOperator = stack.Peek();
  88.  
  89. if ((IsLeftAssosiative(tokenOperator) && precedence[tokenOperator] == precedence[stackOperator]) ||
  90. (precedence[tokenOperator] < precedence[stackOperator]))
  91. {
  92. outputQueue.Enqueue(stack.Pop());
  93. }
  94. else
  95. {
  96. break;
  97. }
  98. }
  99. stack.Push(token);
  100. } else if(token.Equals("("))
  101. {
  102. stack.Push(token);
  103. }
  104. else if(token.Equals(")"))
  105. {
  106. while(stack.Any() && stack.Peek() != "(")
  107. {
  108. outputQueue.Enqueue(stack.Pop());
  109. }
  110. stack.Pop(); // Pop left parenthesis
  111. }
  112. else
  113. {
  114. throw new SyntaxException();
  115. }
  116.  
  117.  
  118. }
  119. while (stack.Any())
  120. {
  121. outputQueue.Enqueue(stack.Pop());
  122. }
  123. return outputQueue.ToArray();
  124. }
  125.  
  126. bool IsLeftAssosiative(string token)
  127. {
  128. return !token.Equals("^");
  129. }
  130.  
  131. private bool IsOperator(string token)
  132. {
  133. return Regex.IsMatch(token, @"[+-/*]{1}");
  134. }
  135.  
  136. private bool IsNumber(string token)
  137. {
  138. return Regex.IsMatch(token, @"[0-9]+");
  139. }
  140.  
  141. private string[] specialChars = { "+", "-", "/", "*", "^", "(", ")" };
  142. private string[] Tokenize(string expression)
  143. {
  144. foreach(var specialChar in specialChars)
  145. {
  146. expression = expression.Replace(specialChar, " " + specialChar + " ");
  147. }
  148.  
  149. return Regex.Split(expression, @"\s");
  150. }
  151. }
  152. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement