/// <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); } } }