/// <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> /// Estado da leitura do valor - estado 4. /// </summary> /// <param name="reader">O leitor de símbolos.</param> /// <returns>O próximo estado.</returns> private IState <string, string> ValueState(ISymbolReader <string, string> reader) { this.IgnoreVoids(reader); var readed = reader.Get(); if (reader.IsAtEOF()) { throw new OdmpProblemException("Unexpected end of file."); } this.currentReadingValues.Clear(); if (this.elementsDelimiterTypes.ContainsKey(readed.SymbolType)) { this.ProcessDelimiteres(readed, reader); } else if (readed.SymbolType == "left_parenthesis") { this.ProcessInnerParenthesis(readed, reader); } else { this.currentReadingValues.Add(readed); } var error = new LogStatus <string, EParseErrorLevel>(); var value = this.objectElementsReader.Parse(this.currentReadingValues.ToArray(), error); if (error.HasLogs(EParseErrorLevel.ERROR)) { throw new OdmpProblemException(string.Format("Can't parse value {0}.", readed.SymbolValue)); } this.SetValueInMatrixSet(this.componentCoord, this.lineCoord, this.columnCoord, value); this.coordState = 0; return(this.states[2]); }
/// <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> /// Estado de leitura das coordenadas - estado 3. /// </summary> /// <param name="reader">O leitor de símbolos.</param> /// <returns>O próximo estado.</returns> private IState <string, string> InsideParenthesisState(ISymbolReader <string, string> reader) { this.IgnoreVoids(reader); var readed = reader.Get(); if (reader.IsAtEOF()) { throw new OdmpProblemException("Unexpected end of file."); } this.currentReadingValues.Clear(); if (readed.SymbolType == "right_parenthesis") { if (this.coordState != 3) { throw new OdmpProblemException(string.Format( "Wrong number, {0}, of coordinates. Expecting 3.", this.coordState)); } this.coordState = 0; return(this.states[4]); } else if (readed.SymbolType == "left_parenthesis") { this.ProcessInnerParenthesis(readed, reader); } else if (this.elementsDelimiterTypes.ContainsKey(readed.SymbolType)) { this.ProcessDelimiteres(readed, reader); } else { this.currentReadingValues.Add(readed); } var error = new LogStatus <string, EParseErrorLevel>(); switch (this.coordState) { case 0: this.componentCoord = this.componentElementsReader.Parse(this.currentReadingValues.ToArray(), error); if (error.HasLogs(EParseErrorLevel.ERROR)) { throw new OdmpProblemException(string.Format("Can't parse component coordinate: {0}.", readed.SymbolValue)); } break; case 1: this.lineCoord = this.lineElementsReader.Parse(this.currentReadingValues.ToArray(), error); if (error.HasLogs(EParseErrorLevel.ERROR)) { throw new OdmpProblemException(string.Format("Can't parse line coordinate: {0}.", readed.SymbolValue)); } break; case 2: this.columnCoord = this.columnElementsReader.Parse(this.currentReadingValues.ToArray(), error); if (error.HasLogs(EParseErrorLevel.ERROR)) { throw new OdmpProblemException(string.Format("Can't parse column coordinate: {0}.", readed.SymbolValue)); } break; default: throw new OdmpProblemException("An internal error has occured."); } ++this.coordState; return(this.states[3]); }
/// <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> /// 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); } } }