Пример #1
0
        private int EvaluateInput(string input)
        {
            CalculatorLexer lexer = new CalculatorLexer(new AntlrInputStream(input));

            lexer.RemoveErrorListeners();
            lexer.AddErrorListener(new ThrowingErrorListener <int>());

            CalculatorParser parser = new CalculatorParser(new CommonTokenStream(lexer));

            parser.RemoveErrorListeners();
            parser.AddErrorListener(new ThrowingErrorListener <IToken>());

            return(new CalculatorVisitor().Visit(parser.expression()));
        }
Пример #2
0
        public static double Evaluate(string expression)
        {
            var lexer = new CalculatorLexer(new AntlrInputStream(expression));

            lexer.RemoveErrorListeners();
            lexer.AddErrorListener(new ThrowExceptionErrorListener());

            var tokens = new CommonTokenStream(lexer);
            var parser = new CalculatorParser(tokens);

            var tree = parser.compileUnit();

            var visitor = new ExcelVisitor();

            return(visitor.Visit(tree));
        }
Пример #3
0
        /// <summary>
        ///     This will attempt to recalculate if an error was encountered. Will try to skip whitespaces
        ///     and comments so to prevent number literals and function qualifiers not being identified.
        /// </summary>
        /// <param name="formula"></param>
        /// <param name="secondRun"></param>
        /// <returns></returns>
        private static CalculationResult CalculateResult(string formula, bool secondRun)
        {
            if (string.IsNullOrWhiteSpace(formula))
            {
                return(new CalculationResult
                {
                    IsValid = true,
                    Result = 0
                });
            }
            var inputStream = new AntlrInputStream(formula);
            var lexer       = new CalculatorLexer(inputStream);
            var tokenStream = new CommonTokenStream(lexer);
            var parser      = new CalculatorParser(tokenStream);

            // Removing default error listeners due to noise in debug
            lexer.RemoveErrorListeners();
            parser.RemoveErrorListeners();
            // But adding the custom one
            var customErrorListener = new CalculatorErrorListener();

            parser.AddErrorListener(customErrorListener);
            var visitor = new CalculatorVisitor();
            var calculatorExpression = parser.calculator().expression();
            var result        = visitor.Visit(calculatorExpression);
            var isValid       = customErrorListener.IsValid;
            var errorLocation = customErrorListener.ErrorLocation;
            var errorMessage  = customErrorListener.ErrorMessage;

            if (double.IsInfinity(result))
            {
                isValid = false;
            }

            if (!isValid && !secondRun)
            {
                var cleanedFormula = string.Empty;
                var tokenList      = tokenStream.GetTokens().ToList();
                for (var i = 0; i < tokenList.Count - 1; i++)
                {
                    cleanedFormula += tokenList[i].Text;
                }
                var originalErrorLocation = errorLocation;
                var retriedResult         = CalculateResult(cleanedFormula, true);
                if (!retriedResult.IsValid)
                {
                    retriedResult.ErrorPosition = originalErrorLocation;
                    retriedResult.ErrorMessage  = errorMessage;
                }
                return(retriedResult);
            }
            return(new CalculationResult
            {
                IsValid = isValid,
                Result = isValid || double.IsInfinity(result)
                    ? result
                    : double.NaN,
                ErrorPosition = errorLocation,
                ErrorMessage = isValid ? null : errorMessage
            });
        }