예제 #1
0
 private List<Token> tokenize(string formula)
 {
     formula = formula.Replace(" ","");
     List<Token> tokens = new List<Token>();
     Token currentToken = new Token();
     bool bypass = false;
     int position = -1;
     foreach (char c in formula)
     {
         position++;
         if (bypass)
         {
             bypass = false;
             continue;
         }
         if (isNumber(c))
         {
             if (!currentToken.isEmpty() && !currentToken.isNumber)
             {
                 tokens.Add(currentToken);
                 currentToken = new Token();
             }
             currentToken.isNumber = true;
             currentToken.numberValue += c;
         }
         else if (isOperator(c))
         {
             if (!currentToken.isEmpty())
             {
                 tokens.Add(currentToken);
                 currentToken = new Token();
             }
             currentToken.isOperator = true;
             currentToken.operatorValue = c;
         }
         else if (isParen(c))
         {
             if (!currentToken.isEmpty())
             {
                 tokens.Add(currentToken);
                 currentToken = new Token();
             }
             currentToken.isParen = true;
             currentToken.parenValue = c;
         }
         else if (c == 'E')
         {
             if (formula[position + 1] == '+')
             {
                 bypass = true;
                 if (!currentToken.isEmpty())
                 {
                     tokens.Add(currentToken);
                     currentToken = new Token();
                 }
                 currentToken.isOperator = true;
                 currentToken.operatorValue = 'e';
             }
             else
             {
                 throw new Exception("Scientific notation is E+ or e");
             }
         }
         else
         {
             throw new Exception("I don't know how to handle '" + c + "'");
         }
     }
     if (!currentToken.isEmpty()) { tokens.Add(currentToken); }
     return tokens;
 }
예제 #2
0
 private void ProcessParens(ref List<Token> tokens)
 {
     int posLParen = -1;
     do
     {
         posLParen = tokens.indexOfLParen();
         if (posLParen != -1)
         {
             int posRParen = tokens.indexOfRParen(posLParen);
             // remove this range from the array
             List<Token> subExpression = new List<Token>();
             for(int i = posLParen+1; i < posRParen; i++)
             {
                 subExpression.Add(tokens[i]);
             }
             tokens.RemoveRange(posLParen, (posRParen - posLParen + 1));
             double subExpressionValue = evaluateTokens(subExpression);
             Token t = new Token();
             t.isNumber = true;
             t.numberValue = subExpressionValue.ToString();
             tokens.Insert(posLParen, t);
         }
     }
     while (posLParen != -1);
     // shouldn't be any R parens left
 }
예제 #3
0
        private void ProcessUnaryMinus(ref List<Token> tokens)
        {
            int posOperator = 0;
            do
            {
                posOperator = tokens.indexOfNextOperator('-', posOperator);
                if (posOperator != -1)
                {
                    Token left = null;
                    Token right = null;
                    if (posOperator - 1 != -1) { left = tokens[posOperator - 1]; }
                    if (posOperator + 1 < tokens.Count) { right = tokens[posOperator + 1]; }

                    // special case, unary minus.  If there is nothing to the left of the minus, or there is a non token number, perform unary minus
                    if (left == null || (left != null && !left.isNumber && right.isNumber))
                    {
                        Token unt = new Token();
                        unt.isNumber = true;
                        unt.numberValue = (-1 * Convert.ToDouble(right.numberValue)).ToString();
                        // remove this range from the array
                        tokens.RemoveRange(posOperator, 2);
                        tokens.Insert(posOperator, unt);
                    }
                    posOperator++;
                }
            }
            while (posOperator != -1);
        }
예제 #4
0
        private void ProcessOperator(ref List<Token> tokens, char op)
        {
            int posOperator = -1;
            do
            {
                posOperator = tokens.indexOfOperator(op);
                if (posOperator != -1)
                {
                    Token left = null;
                    Token right = null;
                    if (posOperator - 1 != -1) { left = tokens[posOperator - 1]; }
                    if (posOperator + 1 < tokens.Count) { right = tokens[posOperator + 1]; }
                    if (right == null) { throw new Exception("Nothing to the right of the operator"); }
                    if (left == null) { throw new Exception("Nothing to the left of the operator"); }
                    if (!left.isNumber) { throw new Exception("Left side is not a number"); }
                    if (!right.isNumber) { throw new Exception("Right side is not a number"); }

                    Token t = new Token();
                    t.isNumber = true;
                    switch (tokens[posOperator].operatorValue)
                    {
                        case '^':
                            t.numberValue = Math.Pow(Convert.ToDouble(left.numberValue), Convert.ToDouble(right.numberValue)).ToString(); break;
                        case '/':
                            t.numberValue = (Convert.ToDouble(left.numberValue) / Convert.ToDouble(right.numberValue)).ToString(); break;
                        case '*':
                            t.numberValue = (Convert.ToDouble(left.numberValue) * Convert.ToDouble(right.numberValue)).ToString(); break;
                        case '%':
                            t.numberValue = (Convert.ToDouble(left.numberValue) % Convert.ToDouble(right.numberValue)).ToString(); break;
                        case '+':
                            t.numberValue = (Convert.ToDouble(left.numberValue) + Convert.ToDouble(right.numberValue)).ToString(); break;
                        case '-':
                            t.numberValue = (Convert.ToDouble(left.numberValue) - Convert.ToDouble(right.numberValue)).ToString(); break;
                        case 'e':
                            t.numberValue = (Convert.ToDouble(left.numberValue) * Math.Pow(10, Convert.ToDouble(right.numberValue))).ToString(); break;
                    }
                    // remove this range from the array
                    tokens.RemoveRange(posOperator - 1, 3);
                    tokens.Insert(posOperator - 1, t);
                }
            }
            while (posOperator != -1);
        }