Beispiel #1
0
        static void applyOperator(OpToken t, ref Stack <NumToken> nums)
        {
            if (t.type == OpType.LP || t.type == OpType.RP)
            {
                Console.WriteLine("Parenthesis mismatch");
                return;
            }
            try
            {
                double op2 = nums.Pop().value;
                double op1 = nums.Pop().value;
                switch (t.type)
                {
                //last param of NumToken doesn't matter for any of them because they are not parsed from the string
                case OpType.ADD:
                    nums.Push(new NumToken(op1 + op2, -1));
                    break;

                case OpType.SUB:
                    nums.Push(new NumToken(op1 - op2, -1));
                    break;

                case OpType.MUL:
                    nums.Push(new NumToken(op1 * op2, -1));
                    break;

                case OpType.DIV:
                    nums.Push(new NumToken(op1 / op2, -1));
                    break;

                case OpType.EXP:
                    nums.Push(new NumToken(Math.Pow(op1, op2), -1));
                    break;

                case OpType.MOD:
                    nums.Push(new NumToken(op1 % op2, -1));
                    break;

                case OpType.LSHIFT:
                    nums.Push(new NumToken((int)op1 << (int)op2, -1));
                    break;

                case OpType.RSHIFT:
                    nums.Push(new NumToken((int)op1 >> (int)op2, -1));
                    break;
                }
            }
            catch (Exception)
            {
                Console.WriteLine("Encountered exception, please check your syntax");
            }
        }
Beispiel #2
0
        static void Main(string[] args)
        {
            Console.WriteLine("Input an expression. Note that _ is the negative sign. Use of >> << is rounded.");
            string exp = Console.ReadLine();

            exp = exp.Replace(" ", "");                     //strip spaces
            Stack <NumToken> nums = new Stack <NumToken>(); //number stack
            Stack <OpToken>  ops  = new Stack <OpToken>();  //operator stack

            for (int i = 0; i < exp.Length;)                //increments of i will be determined based off whether it is a number or an operator
            {
                Token k = null;
                try
                {
                    k = getNextToken(exp, i);
                }
                catch (Exception)
                {
                    Console.WriteLine("Error parsing token.");
                    break;
                }
                if (k is NumToken)
                {
                    NumToken nt = (NumToken)k;
                    nums.Push(nt);
                    i += nt.length;
                }
                else if (k is OpToken)
                {
                    OpToken x = (OpToken)k;
                    OpToken y = ops.Count > 0 ? ops.Peek() : null;
                    if (y == null || x.type == OpType.LP) //if stack has nothing in it yet, or if the token is a (, push it on stack, no evaluation
                    {
                        ops.Push(x);
                    }
                    else
                    {
                        if (x.type == OpType.RP) //if the current token is a ), unwind the stack until a ( is encountered
                        {
                            OpToken alpha = null;
                            while ((alpha = ops.Pop()).type != OpType.LP)
                            {
                                applyOperator(alpha, ref nums);
                            }
                        }
                        else
                        {
                            //apply operator if the current token is <= in precedence than the one on the top of the stack (< if right associative)
                            //parenthesis must be the smallest number so no other token will cause it to be applied
                            while ((x.leftasso && x.precedence <= y.precedence) || (!x.leftasso && x.precedence < y.precedence))
                            {
                                ops.Pop(); //pop y off, we're applying it
                                applyOperator(y, ref nums);
                                if (ops.Count == 0)
                                {
                                    break;
                                }
                                y = ops.Peek(); //look at the next operator on stack in case it can be applied as well
                            }
                            ops.Push(x);
                        }
                    }
                    i += x.length;
                }
            }
            //unwind remaining operators
            while (ops.Count > 0)
            {
                OpToken y = ops.Pop();
                applyOperator(y, ref nums);
            }
            if (nums.Count > 0)
            {
                Console.WriteLine(exp + " = " + nums.Pop().value);
            }
            else
            {
                Console.WriteLine("No result.");
            }
            Console.WriteLine("Press any key to exit.");
            Console.ReadKey(false);
        }
Beispiel #3
0
 static void applyOperator(OpToken t, ref Stack<NumToken> nums)
 {
     if (t.type == OpType.LP || t.type == OpType.RP)
     {
         Console.WriteLine("Parenthesis mismatch");
         return;
     }
     try
     {
         double op2 = nums.Pop().value;
         double op1 = nums.Pop().value;
         switch (t.type)
         {
             //last param of NumToken doesn't matter for any of them because they are not parsed from the string
             case OpType.ADD:
                 nums.Push(new NumToken(op1 + op2, -1));
                 break;
             case OpType.SUB:
                 nums.Push(new NumToken(op1 - op2, -1));
                 break;
             case OpType.MUL:
                 nums.Push(new NumToken(op1 * op2, -1));
                 break;
             case OpType.DIV:
                 nums.Push(new NumToken(op1 / op2, -1));
                 break;
             case OpType.EXP:
                 nums.Push(new NumToken(Math.Pow(op1, op2), -1));
                 break;
             case OpType.MOD:
                 nums.Push(new NumToken(op1 % op2, -1));
                 break;
             case OpType.LSHIFT:
                 nums.Push(new NumToken((int)op1 << (int)op2, -1));
                 break;
             case OpType.RSHIFT:
                 nums.Push(new NumToken((int)op1 >> (int)op2, -1));
                 break;
         }
     }
     catch (Exception)
     {
         Console.WriteLine("Encountered exception, please check your syntax");
     }
 }