コード例 #1
0
        /// <summary>
        /// Parses and extracts a numeric value at the current position
        /// </summary>
        /// <param name="parser">TextParser object</param>
        /// <returns></returns>
        private string ParseNumberToken(TextParser parser)
        {
            bool hasDecimal = false;
            int  start      = parser.Position;

            while (char.IsDigit(parser.Peek()) || parser.Peek() == '.')
            {
                if (parser.Peek() == '.')
                {
                    if (hasDecimal)
                    {
                        throw new FormulaException(ErrMultipleDecimalPoints, parser.Position);
                    }
                    hasDecimal = true;
                }
                parser.MoveAhead();
            }
            // Extract token
            string token = parser.Extract(start, parser.Position);

            if (token == ".")
            {
                throw new FormulaException(ErrInvalidOperand, parser.Position - 1);
            }
            return(token);
        }
コード例 #2
0
        /// <summary>
        /// Parses and extracts a symbol at the current position
        /// </summary>
        /// <param name="parser">TextParser object</param>
        /// <returns></returns>
        private static string ParseSymbolToken(TextParser parser)
        {
            int start = parser.Position;

            while (char.IsLetterOrDigit(parser.Peek()) || parser.Peek() == '_')
            {
                parser.MoveAhead();
            }
            return(parser.Extract(start, parser.Position));
        }
コード例 #3
0
 /// <summary>
 /// Extracts and evaluates a function parameter and returns its value. If an
 /// exception occurs, it is caught and the column is adjusted to reflect the
 /// position in original string, and the exception is rethrown.
 /// </summary>
 /// <param name="parser">TextParser object</param>
 /// <param name="paramStart">Column where this parameter started</param>
 /// <returns></returns>
 private double EvaluateParameter(TextParser parser, int paramStart)
 {
     try
     {
         // Extract expression and evaluate it
         string expression = parser.Extract(paramStart, parser.Position);
         return(Execute(expression));
     }
     catch (FormulaException ex)
     {
         // Adjust column and rethrow exception
         ex.Column += paramStart;
         throw;
     }
 }
コード例 #4
0
        /// <summary>
        /// Evaluates each parameter of a function's parameter list and returns
        /// a list of those values. An empty list is returned if no parameters
        /// were found. It is assumed the current position is at the opening
        /// parenthesis of the argument list.
        /// </summary>
        /// <param name="parser">TextParser object</param>
        /// <returns></returns>
        private List <double> ParseParameters(TextParser parser)
        {
            // Move past open parenthesis
            parser.MoveAhead();

            // Look for function parameters
            var parameters = new List <double>();

            parser.MovePastWhitespace();
            if (parser.Peek() != ')')
            {
                // Parse function parameter list
                int paramStart = parser.Position;
                int pardepth   = 1;

                while (!parser.EndOfText)
                {
                    if (parser.Peek() == ':')
                    {
                        // assume current token and next token are cell references
                        var p1    = parser.Position;
                        var cell1 = parser.Extract(paramStart, parser.Position);
                        parser.MoveAhead();
                        var p2    = parser.Position;
                        var cell2 = ParseSymbolToken(parser);
                        paramStart = parser.Position;
                        parameters.AddRange(EvaluateCellReferences(cell1, cell2, p1, p2));
                    }
                    else if (parser.Peek() == ',')
                    {
                        // Note: Ignore commas inside parentheses. They could be
                        // from a parameter list for a function inside the parameters
                        if (pardepth == 1)
                        {
                            parameters.Add(EvaluateParameter(parser, paramStart));
                            paramStart = parser.Position + 1;
                        }
                    }

                    if (parser.Peek() == ')')
                    {
                        pardepth--;
                        if (pardepth == 0)
                        {
                            if (paramStart < parser.Position)
                            {
                                parameters.Add(EvaluateParameter(parser, paramStart));
                            }
                            break;
                        }
                    }
                    else if (parser.Peek() == '(')
                    {
                        pardepth++;
                    }
                    parser.MoveAhead();
                }
            }
            // Make sure we found a closing parenthesis
            if (parser.Peek() != ')')
            {
                throw new FormulaException(ErrClosingParenExpected, parser.Position);
            }
            // Move past closing parenthesis
            parser.MoveAhead();
            // Return parameter list
            return(parameters);
        }