Exemplo n.º 1
0
        /// <summary>
        /// Efectua a leitura de um polinómio.
        /// </summary>
        /// <param name="polynomialReader">A cadeia de carácteres que contém o polinómimo.</param>
        /// <param name="conversion">O conversor entre o tipo de coeficiente e um inteiro.</param>
        /// <param name="errors">A lista de errros encontrados.</param>
        /// <param name="resultPolynomial">O polinómio lido.</param>
        /// <returns>Verdadeiro caso a leitura seja bem sucedida e falso caso contrário.</returns>
        /// <exception cref="ArgumentNullException">Se o leitor de símbolos ou  conversor forem nulos.</exception>
        public bool TryParsePolynomial(
            MementoSymbolReader <InputReader, string, string> polynomialReader,
            IConversion <int, T> conversion,
            ILogStatus <string, EParseErrorLevel> errors,
            out Polynomial <T> resultPolynomial)
        {
            if (polynomialReader == null)
            {
                throw new ArgumentNullException("polynomialReader");
            }

            if (conversion == null)
            {
                throw new ArgumentNullException("conversion");
            }

            this.conversion  = conversion;
            resultPolynomial = default(Polynomial <T>);
            var expressionReader = new ExpressionReader <ParsePolynomialItem <T>, string, string>(
                new SimplePolynomialReader <T>(this.coeffParser, this.ring));

            expressionReader.RegisterBinaryOperator("plus", Add, 0);
            expressionReader.RegisterBinaryOperator("times", Multiply, 1);
            expressionReader.RegisterBinaryOperator("minus", Subtract, 0);
            expressionReader.RegisterBinaryOperator("hat", Power, 2);
            expressionReader.RegisterUnaryOperator("minus", Symmetric, 0);

            expressionReader.RegisterExpressionDelimiterTypes("left_parenthesis", "right_parenthesis");
            expressionReader.RegisterSequenceDelimiterTypes("left_parenthesis", "right_parenthesis");
            foreach (var kvp in this.externalDelimitersTypes)
            {
                foreach (var delimiter in kvp.Value)
                {
                    expressionReader.RegisterExternalDelimiterTypes(kvp.Key, delimiter);
                }
            }

            expressionReader.AddVoid("space");
            expressionReader.AddVoid("carriage_return");
            expressionReader.AddVoid("new_line");

            var innerErrors      = new LogStatus <string, EParseErrorLevel>();
            var expressionResult = expressionReader.Parse(polynomialReader, innerErrors);

            if (innerErrors.HasLogs(EParseErrorLevel.ERROR))
            {
                if (errors != null)
                {
                    foreach (var message in innerErrors.GetLogs(EParseErrorLevel.ERROR))
                    {
                        errors.AddLog(message, EParseErrorLevel.ERROR);
                    }
                }

                return(false);
            }
            else
            {
                if (expressionResult.ValueType == EParsePolynomialValueType.COEFFICIENT)
                {
                    resultPolynomial = new Polynomial <T>(expressionResult.Coeff, this.ring);
                    return(true);
                }
                else if (expressionResult.ValueType == EParsePolynomialValueType.INTEGER)
                {
                    if (typeof(T).IsAssignableFrom(typeof(int)))
                    {
                        resultPolynomial = new Polynomial <T>((T)(object)expressionResult.Degree, this.ring);
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }
                else if (expressionResult.ValueType == EParsePolynomialValueType.POLYNOMIAL)
                {
                    resultPolynomial = expressionResult.Polynomial;
                    return(true);
                }
                else
                {
                    if (errors != null)
                    {
                        errors.AddLog("Severe error.", EParseErrorLevel.ERROR);
                    }

                    return(false);
                }
            }
        }