public Nullable <double> Parse( ISymbol <string, string>[] symbolListToParse, ILogStatus <string, EParseErrorLevel> errorLogs) { var value = default(Nullable <double>); if (errorLogs == null) { throw new ArgumentNullException("errorLogs"); } else if (symbolListToParse == null || symbolListToParse.Length > 0) { errorLogs.AddLog("No symbol was provided.", EParseErrorLevel.ERROR); } else { var innerError = new LogStatus <string, EParseErrorLevel>(); value = this.doubleParser.Parse(symbolListToParse, innerError); foreach (var kvp in innerError.GetLogs()) { errorLogs.AddLog(kvp.Value, kvp.Key); } } return(value); }
/// <summary> /// Realiza a leitura. /// </summary> /// <remarks> /// Se a leitura não for bem-sucedida, os erros de leitura serão registados no diário /// e será retornado o objecto por defeito. /// </remarks> /// <param name="symbolListToParse">O vector de símbolos a ser lido.</param> /// <param name="errorLogs">O objecto que irá manter o registo do diário da leitura.</param> /// <returns>O valor lido.</returns> public double Parse( ISymbol <string, SymbType>[] symbolListToParse, ILogStatus <string, EParseErrorLevel> errorLogs) { if (errorLogs == null) { throw new ArgumentNullException("errorLogs"); } else { var value = default(double); if (symbolListToParse == null) { errorLogs.AddLog( "Null values for double aren't allowed.", EParseErrorLevel.ERROR); } else if (symbolListToParse.Length == 0) { errorLogs.AddLog( "No symbol value was provided for reading.", EParseErrorLevel.ERROR); } else { var resultBuilder = new StringBuilder(); for (int i = 0; i < symbolListToParse.Length; ++i) { resultBuilder.Append(symbolListToParse[i].SymbolValue); } if (!double.TryParse( resultBuilder.ToString(), this.numberStyles, this.formatProvider, out value)) { errorLogs.AddLog( string.Format("Invalid double symbol value: {0}", resultBuilder.ToString()), EParseErrorLevel.ERROR); } } return(value); } }
/// <summary> /// Copia mensagens entre diários. /// </summary> /// <param name="source">O diário de origem.</param> /// <param name="destination">O diário de destino.</param> private void CopyErrors( ILogStatus <string, EParseErrorLevel> source, ILogStatus <string, EParseErrorLevel> destination) { foreach (var kvp in source.GetLogs()) { destination.AddLog(kvp.Value, kvp.Key); } }
/// <summary> /// Realiza a leitura. /// </summary> /// <remarks> /// Se a leitura não for bem-sucedida, os erros de leitura serão registados no diário /// e será retornado o objecto por defeito. /// </remarks> /// <param name="symbolListToParse">O vector de símbolos a ser lido.</param> /// <param name="errorLogs">O objecto que irá manter o registo do diário da leitura.</param> /// <returns>O valor lido.</returns> public decimal Parse( ISymbol <string, SymbType>[] symbolListToParse, ILogStatus <string, EParseErrorLevel> errorLogs) { if (errorLogs == null) { throw new ArgumentNullException("errorLogs"); } else { var value = default(decimal); if (symbolListToParse == null) { errorLogs.AddLog( "Null values for integer aren't allowed.", EParseErrorLevel.ERROR); } else if (symbolListToParse.Length == 0) { errorLogs.AddLog( "No symbol was provided for reading.", EParseErrorLevel.ERROR); } else { var firstSymbol = symbolListToParse[0]; if (!decimal.TryParse( firstSymbol.SymbolValue, this.numberStyles, this.formatProvider, out value)) { errorLogs.AddLog( string.Format("Invalid integer symbol: {0}", firstSymbol.SymbolValue), EParseErrorLevel.ERROR); } } return(value); } }
/// <summary> /// Tenta ler a matriz a partir de um leitor de símbolos estabelecendo um valor por defeito. /// </summary> /// <param name="reader">O leitor de símbolos.</param> /// <param name="parser">O interpretador da matriz.</param> /// <param name="errors">Os erros da leitura.</param> /// <param name="defaultValue">O valor por defeito.</param> /// <param name="matrixFactory">A função responsável pela criação de matrizes.</param> /// <param name="matrix">Estabelece a matriz lida.</param> /// <returns>Verdadeiro caso a operação seja bem sucedida e falso caso contrário.</returns> public bool TryParseMatrix( IMementoSymbolReader <SymbValue, SymbType> reader, IParse <T, SymbValue, SymbType> parser, ILogStatus <string, EParseErrorLevel> errors, T defaultValue, Func <int, int, T, M> matrixFactory, out M matrix) { if (matrixFactory == null) { throw new ArgumentNullException("matrixFactory"); } else { matrix = default(M); this.rangeReader.ReadRangeValues(reader, parser); if (this.rangeReader.HasErrors) { if (errors != null) { foreach (var message in this.rangeReader.ErrorMessages) { errors.AddLog(message, EParseErrorLevel.ERROR); } } return(false); } else { var lines = -1; var columns = -1; var configurationEnumerator = this.rangeReader.Configuration.GetEnumerator(); if (configurationEnumerator.MoveNext()) { lines = configurationEnumerator.Current; if (configurationEnumerator.MoveNext()) { columns = configurationEnumerator.Current; } } matrix = matrixFactory.Invoke(lines, columns, defaultValue); this.SetupResultMatrix(matrix, new int[] { lines, columns }, this.rangeReader.Elements); return(true); } } }
/// <summary> /// Realiza a leitura. /// </summary> /// <remarks> /// Se a leitura não for bem-sucedida, os erros de leitura serão registados no diário /// e será retornado o objecto por defeito. /// </remarks> /// <param name="symbolListToParse">O vector de símbolos a ser lido.</param> /// <param name="errorLogs">O objecto que irá manter o registo do diário da leitura.</param> /// <returns>O valor lido.</returns> public Fraction <T> Parse( ISymbol <string, string>[] symbolListToParse, ILogStatus <string, EParseErrorLevel> errorLogs) { var innerErrors = new LogStatus <string, EParseErrorLevel>(); var parsedElement = this.elementParser.Parse(symbolListToParse, innerErrors); foreach (var kvp in innerErrors.GetLogs()) { errorLogs.AddLog(kvp.Value, kvp.Key); } if (innerErrors.HasLogs(EParseErrorLevel.ERROR)) { return(default(Fraction <T>)); } else { return(new Fraction <T>(parsedElement, this.domain.MultiplicativeUnity, this.domain)); } }
/// <summary> /// Realiza a leitura. /// </summary> /// <remarks> /// Se a leitura não for bem-sucedida, os erros de leitura serão registados no diário /// e será retornado o objecto por defeito. /// </remarks> /// <param name="symbolListToParse">O vector de símbolos a ser lido.</param> /// <param name="errorLogs">O objecto que irá manter o registo do diário da leitura.</param> /// <returns>O valor lido.</returns> public Fraction <ElementType> Parse( ISymbol <string, string>[] symbolListToParse, ILogStatus <string, EParseErrorLevel> errorLogs) { var innerErrorLog = new LogStatus <string, EParseErrorLevel>(); var parsed = this.elementParser.Parse(symbolListToParse, innerErrorLog); if (innerErrorLog.HasLogs(EParseErrorLevel.ERROR)) { foreach (var message in innerErrorLog.GetLogs(EParseErrorLevel.ERROR)) { errorLogs.AddLog(message, EParseErrorLevel.ERROR); } return(default(Fraction <ElementType>)); } else { return(new Fraction <ElementType>(parsed, this.domain.MultiplicativeUnity, this.domain)); } }
/// <summary> /// Realiza a leitura. /// </summary> /// <remarks> /// Se a leitura não for bem-sucedida, os erros de leitura serão registados no diário /// e será retornado o objecto por defeito. /// </remarks> /// <param name="symbolListToParse">O vector de símbolos a ser lido.</param> /// <param name="errorLogs">O objecto que irá manter o registo do diário da leitura.</param> /// <returns>O valor lido.</returns> public HashSet <ObjectType> Parse( ISymbol <string, ESymbolSetType>[] symbolListToParse, ILogStatus <string, EParseErrorLevel> errorLogs) { var value = default(HashSet <ObjectType>); var innerError = new LogStatus <string, EParseErrorLevel>(); var parsedObject = this.elementsParser.Parse(symbolListToParse, innerError); if (!innerError.HasLogs(EParseErrorLevel.ERROR)) { value = new HashSet <ObjectType>(); value.Add(parsedObject); } foreach (var kvp in innerError.GetLogs()) { errorLogs.AddLog(kvp.Value, kvp.Key); } return(value); }
/// <summary> /// Tenta fazer a leitura da expressão. /// </summary> /// <param name="reader">O leitor de símbolos.</param> /// <param name="errors">A lista que irá receber os erros.</param> /// <param name="element">O elemento lido.</param> /// <returns>Verdadeiro caso a leitura seja bem-sucedida e falso caso contrário.</returns> public bool TryParsePolynomial( MementoSymbolReader <InputReader, string, string> reader, ILogStatus <string, EParseErrorLevel> errors, out ObjectType element) { if (reader == null) { throw new ArgumentNullException("reader"); } else { var expressionReader = new ExpressionReader <ObjectType, string, string>( this.objectParser); 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.RegisterBinaryOperator("over", Divide, 1); if (this.expressionDelimiterTypes.Any()) { foreach (var expressionDelimiterKvp in this.expressionDelimiterTypes) { foreach (var closeDelimiter in expressionDelimiterKvp.Value) { expressionReader.RegisterExpressionDelimiterTypes( expressionDelimiterKvp.Key, closeDelimiter); } } } else { 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("blancks"); expressionReader.AddVoid("space"); expressionReader.AddVoid("carriage_return"); expressionReader.AddVoid("new_line"); var innerErrors = new LogStatus <string, EParseErrorLevel>(); element = expressionReader.Parse(reader, innerErrors); foreach (var kvp in innerErrors.GetLogs()) { errors.AddLog(kvp.Value, kvp.Key); } if (innerErrors.HasLogs(EParseErrorLevel.ERROR)) { return(false); } else { return(true); } } }
/// <summary> /// Realiza a leitura. /// </summary> /// <remarks> /// Se a leitura não for bem-sucedida, os erros de leitura serão registados no diário /// e será retornado o objecto por defeito. /// </remarks> /// <param name="symbolListToParse">O vector de símbolos a ser lido.</param> /// <param name="errorLogs">O objecto que irá manter o registo do diário da leitura.</param> /// <returns>O valor lido.</returns> public ParsePolynomialItem <CoeffType> Parse( ISymbol <string, string>[] symbolListToParse, ILogStatus <string, EParseErrorLevel> errorLogs) { var pol = default(ParsePolynomialItem <CoeffType>); var innerError = new LogStatus <string, EParseErrorLevel>(); var parsedCoeff = this.coeffParser.Parse(symbolListToParse, innerError); if (innerError.HasLogs(EParseErrorLevel.ERROR)) { if (symbolListToParse.Length == 1) { var stringValue = symbolListToParse[0].SymbolValue; if (string.IsNullOrWhiteSpace(stringValue)) { errorLogs.AddLog( "Variable name can't be empty.", EParseErrorLevel.ERROR); } else if (char.IsLetter(stringValue[0])) { pol = new ParsePolynomialItem <CoeffType>(); pol.Polynomial = new Polynomial <CoeffType>(this.coeffRing.MultiplicativeUnity, stringValue, this.coeffRing); } else { var degreeError = new LogStatus <string, EParseErrorLevel>(); var integerValue = this.integerParser.Parse(symbolListToParse, degreeError); if (!degreeError.HasLogs(EParseErrorLevel.ERROR)) { pol = new ParsePolynomialItem <CoeffType>(); pol.Degree = integerValue; } this.CopyErrors(degreeError, errorLogs); } } else { var degreeError = new LogStatus <string, EParseErrorLevel>(); var integerValue = this.integerParser.Parse(symbolListToParse, degreeError); if (!degreeError.HasLogs(EParseErrorLevel.ERROR)) { pol = new ParsePolynomialItem <CoeffType>(); pol.Degree = integerValue; } this.CopyErrors(degreeError, errorLogs); } } else { pol = new ParsePolynomialItem <CoeffType>(); pol.Coeff = parsedCoeff; // Poderão existir avisos this.CopyErrors(innerError, errorLogs); } return(pol); }
/// <summary> /// Realiza a leitura. /// </summary> /// <remarks> /// Se a leitura não for bem-sucedida, os erros de leitura serão registados no diário /// e será retornado o objecto por defeito. /// </remarks> /// <param name="symbolListToParse">O vector de símbolos a ser lido.</param> /// <param name="errorLogs">O objecto que irá manter o registo do diário da leitura.</param> /// <returns>O valor lido.</returns> public ParseUnivarPolynomNormalFormItem <CoeffType> Parse( ISymbol <string, string>[] symbolListToParse, ILogStatus <string, EParseErrorLevel> errorLogs) { var pol = default(ParseUnivarPolynomNormalFormItem <CoeffType>); if (symbolListToParse.Length == 1) { var stringValue = symbolListToParse[0].SymbolValue; if (string.IsNullOrWhiteSpace(stringValue)) { errorLogs.AddLog( "The variable name can't be null nor empty.", EParseErrorLevel.ERROR); } else if (char.IsLetter(stringValue[0])) { if (stringValue == this.variableName) { pol = new ParseUnivarPolynomNormalFormItem <CoeffType>(); pol.Polynomial = new UnivariatePolynomialNormalForm <CoeffType>( this.coeffRing.MultiplicativeUnity, 1, stringValue, this.coeffRing); } else { var coeffError = new LogStatus <string, EParseErrorLevel>(); var parsedCoeff = this.coeffParser.Parse(symbolListToParse, coeffError); if (!coeffError.HasLogs(EParseErrorLevel.ERROR)) { pol = new ParseUnivarPolynomNormalFormItem <CoeffType>(); pol.Coeff = parsedCoeff; } // Poderão existir avisos. this.CopyLogs(coeffError, errorLogs); } } else { var coeffError = new LogStatus <string, EParseErrorLevel>(); var parsedCoeff = this.coeffParser.Parse(symbolListToParse, coeffError); if (coeffError.HasLogs(EParseErrorLevel.ERROR)) { var degreeError = new LogStatus <string, EParseErrorLevel>(); var integerValue = this.integerParser.Parse(symbolListToParse, degreeError); if (degreeError.HasLogs(EParseErrorLevel.ERROR)) { this.CopyLogs(coeffError, errorLogs); } else { pol = new ParseUnivarPolynomNormalFormItem <CoeffType>(); pol.Degree = integerValue; // Poderão existir avisos this.CopyLogs(degreeError, errorLogs); } } else { pol = new ParseUnivarPolynomNormalFormItem <CoeffType>(); pol.Coeff = parsedCoeff; // Poderão existir avisos. this.CopyLogs(coeffError, errorLogs); } } } else { var coeffError = new LogStatus <string, EParseErrorLevel>(); var parsedCoeff = this.coeffParser.Parse(symbolListToParse, coeffError); if (coeffError.HasLogs(EParseErrorLevel.ERROR)) { var degreeError = new LogStatus <string, EParseErrorLevel>(); var integerValue = this.integerParser.Parse(symbolListToParse, degreeError); if (degreeError.HasLogs(EParseErrorLevel.ERROR)) { this.CopyLogs(coeffError, errorLogs); } else { pol = new ParseUnivarPolynomNormalFormItem <CoeffType>(); pol.Degree = integerValue; // Poderão existir avisos this.CopyLogs(degreeError, errorLogs); } } else { pol = new ParseUnivarPolynomNormalFormItem <CoeffType>(); pol.Coeff = parsedCoeff; // Poderão existir avisos. this.CopyLogs(coeffError, errorLogs); } } return(pol); }
/// <summary> /// Realiza a leitura. /// </summary> /// <remarks> /// Se a leitura não for bem-sucedida, os erros de leitura serão registados no diário /// e será retornado o objecto por defeito. /// </remarks> /// <param name="symbolListToParse">O vector de símbolos a ser lido.</param> /// <param name="errorLogs">O objecto que irá manter o registo do diário da leitura.</param> /// <returns>O valor lido.</returns> public HashSet <ObjectType> Parse( ISymbol <string, ESymbolSetType>[] symbolListToParse, ILogStatus <string, EParseErrorLevel> errorLogs) { var value = default(HashSet <ObjectType>); var openSymbol = -1; for (int i = 0; i < symbolListToParse.Length; ++i) { var currentSymbol = symbolListToParse[i]; if (currentSymbol.SymbolType == ESymbolSetType.LBRACE) { openSymbol = i; i = symbolListToParse.Length; } else if (currentSymbol.SymbolType != ESymbolSetType.SPACE && currentSymbol.SymbolType != ESymbolSetType.CHANGE_LINE) { i = symbolListToParse.Length; } } if (openSymbol == -1) { errorLogs.AddLog( "Found no open symbol.", EParseErrorLevel.ERROR); } else { var closeSymbol = -1; for (int i = symbolListToParse.Length - 1; i > openSymbol; --i) { var currentSymbol = symbolListToParse[i]; if (currentSymbol.SymbolType == ESymbolSetType.RBRACE) { closeSymbol = i; i = openSymbol; } else if (currentSymbol.SymbolType != ESymbolSetType.SPACE && currentSymbol.SymbolType != ESymbolSetType.CHANGE_LINE) { i = openSymbol; } } if (closeSymbol == -1) { errorLogs.AddLog( "Found no close symbol.", EParseErrorLevel.ERROR); } else { var elementsNumber = closeSymbol - openSymbol - 1; var elementsArray = new ISymbol <string, ESymbolSetType> [elementsNumber]; Array.Copy(symbolListToParse, openSymbol + 1, elementsArray, 0, elementsNumber); var arraySymbolReader = new ArraySymbolReader <string, ESymbolSetType>(elementsArray, ESymbolSetType.EOF); value = this.expressionReader.Parse(arraySymbolReader, errorLogs); } } return(value); }
/// <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); } } }