Advertisement
Pavle_nis

PARSER

Mar 25th, 2017
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 3.48 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6.  
  7. namespace Slagalica
  8. {
  9.     class Parser
  10.     {
  11.         public int EvaluateExpression(char[] exp)
  12.         {
  13.  
  14.             Stack<int> vStack = new Stack<int>();
  15.             Stack<char> opStack = new Stack<char>();
  16.  
  17.             opStack.Push('('); // Implicit opening parenthesis
  18.  
  19.             int pos = 0;
  20.             while (pos <= exp.Length)
  21.             {
  22.                 if (pos == exp.Length || exp[pos] == ')')
  23.                 {
  24.                     ProcessClosingParenthesis(vStack, opStack);
  25.                     pos++;
  26.                 }
  27.                 else if (exp[pos] >= '0' && exp[pos] <= '9')
  28.                 {
  29.                     pos = ProcessInputNumber(exp, pos, vStack);
  30.                 }
  31.                 else
  32.                 {
  33.                     ProcessInputOperator(exp[pos], vStack, opStack);
  34.                     pos++;
  35.                 }
  36.  
  37.             }
  38.  
  39.             return vStack.Pop(); // Result remains on values stacks
  40.  
  41.         }
  42.  
  43.         void ProcessClosingParenthesis(Stack<int> vStack,
  44.                                         Stack<char> opStack)
  45.         {
  46.  
  47.             while (opStack.Peek() != '(')
  48.                 ExecuteOperation(vStack, opStack);
  49.  
  50.             opStack.Pop(); // Remove the opening parenthesis
  51.  
  52.         }
  53.  
  54.         int ProcessInputNumber(char[] exp, int pos,
  55.                                 Stack<int> vStack)
  56.         {
  57.  
  58.             int value = 0;
  59.             while (pos < exp.Length &&
  60.                     exp[pos] >= '0' && exp[pos] <= '9')
  61.                 value = 10 * value + (int)(exp[pos++] - '0');
  62.  
  63.             vStack.Push(value);
  64.  
  65.             return pos;
  66.  
  67.         }
  68.  
  69.         void ProcessInputOperator(char op, Stack<int> vStack,
  70.                                     Stack<char> opStack)
  71.         {
  72.  
  73.             while (opStack.Count > 0 &&
  74.                     OperatorCausesEvaluation(op, opStack.Peek()))
  75.                 ExecuteOperation(vStack, opStack);
  76.  
  77.             opStack.Push(op);
  78.  
  79.         }
  80.  
  81.         bool OperatorCausesEvaluation(char op, char prevOp)
  82.         {
  83.  
  84.             bool evaluate = false;
  85.  
  86.             switch (op)
  87.             {
  88.                 case '+':
  89.                 case '-':
  90.                     evaluate = (prevOp != '(');
  91.                     break;
  92.                 case '*':
  93.                 case ' ':
  94.                     evaluate = (prevOp == '*' || prevOp == ' ');
  95.                     break;
  96.                 case ')':
  97.                     evaluate = true;
  98.                     break;
  99.             }
  100.  
  101.             return evaluate;
  102.  
  103.         }
  104.  
  105.         void ExecuteOperation(Stack<int> vStack,
  106.                                 Stack<char> opStack)
  107.         {
  108.  
  109.             int rightOperand = vStack.Pop();
  110.             int leftOperand = vStack.Pop();
  111.             char op = opStack.Pop();
  112.  
  113.             int result = 0;
  114.             switch (op)
  115.             {
  116.                 case '+':
  117.                     result = leftOperand + rightOperand;
  118.                     break;
  119.                 case '-':
  120.                     result = leftOperand - rightOperand;
  121.                     break;
  122.                 case '*':
  123.                     result = leftOperand * rightOperand;
  124.                     break;
  125.                 case ' ':
  126.                     result = leftOperand / rightOperand;
  127.                     break;
  128.             }
  129.  
  130.             vStack.Push(result);
  131.  
  132.         }
  133.     }
  134. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement