コード例 #1
0
        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);
        }
コード例 #2
0
 /// <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);
     }
 }
コード例 #3
0
        /// <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 int Parse(
            ISymbol <string, string>[] symbolListToParse,
            ILogStatus <string, EParseErrorLevel> errorLogs)
        {
            var arrayReader = new ArraySymbolReader <string, string>(
                symbolListToParse,
                Utils.GetStringSymbolType(EStringSymbolReaderType.EOF));
            var value = this.expressionReader.Parse(arrayReader, errorLogs);

            return(value);
        }
コード例 #4
0
        /// <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 virtual ObjectType Parse(
            ISymbol <string, string>[] symbolListToParse,
            ILogStatus <string, EParseErrorLevel> errorLogs)
        {
            var arrayReader = new ArraySymbolReader <string, string>(
                symbolListToParse,
                Utils.GetStringSymbolType(EStringSymbolReaderType.EOF));
            var value = default(ObjectType);

            this.expressionReader.TryParsePolynomial(
                arrayReader,
                errorLogs,
                out value);
            return(value);
        }
コード例 #5
0
        /// <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);
                }
            }
        }
コード例 #6
0
ファイル: PolynomialParser.cs プロジェクト: serolmar/matutils
        /// <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 Polynomial <CoeffType> Parse(
            ISymbol <string, string>[] symbolListToParse,
            ILogStatus <string, EParseErrorLevel> errorLogs)
        {
            var arrayReader = new ArraySymbolReader <string, string>(
                symbolListToParse,
                Utils.GetStringSymbolType(EStringSymbolReaderType.EOF));
            var value = default(Polynomial <CoeffType>);

            this.polynomialReader.TryParsePolynomial(
                arrayReader,
                this.conversion,
                errorLogs,
                out value);
            return(value);
        }
コード例 #7
0
        /// <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);
            }
        }
コード例 #8
0
        /// <summary>
        /// Copia todos os erros registados do diário proporcionado.
        /// </summary>
        /// <param name="other">O diário do qual se pretende copiar os erros.</param>
        public void CopyFrom(ILogStatus <Log, Level> other)
        {
            if (other != null)
            {
                var otherEnum = other.GetLogs().GetEnumerator();
                if (otherEnum.MoveNext())
                {
                    // Início da cópia
                    var previousLevel = otherEnum.Current.Key;
                    var messageList   = default(List <Log>);
                    if (!this.logs.TryGetValue(previousLevel, out messageList))
                    {
                        messageList = new List <Log>();
                        this.logs.Add(previousLevel, messageList);
                    }

                    messageList.Add(otherEnum.Current.Value);

                    // Restantes elementos
                    while (otherEnum.MoveNext())
                    {
                        var currentLevel = otherEnum.Current.Key;
                        if (this.logs.Comparer.Equals(
                                previousLevel,
                                currentLevel))
                        {
                            messageList.Add(otherEnum.Current.Value);
                        }
                        else
                        {
                            // O nível poderá existir antes do início da cópia
                            if (!this.logs.TryGetValue(currentLevel, out messageList))
                            {
                                messageList = new List <Log>();
                                this.logs.Add(currentLevel, messageList);
                            }

                            messageList.Add(otherEnum.Current.Value);
                        }
                    }
                }
            }
        }
コード例 #9
0
        /// <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);
            }
        }
コード例 #10
0
            /// <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);
            }
コード例 #11
0
        /// <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));
            }
        }
コード例 #12
0
        /// <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));
            }
        }
コード例 #13
0
        /// <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 AMathematicsObject Parse(
            ISymbol <string, string>[] symbolListToParse,
            ILogStatus <string, EParseErrorLevel> errorLogs)
        {
            var valueReader  = new StringReader(symbolListToParse[0].SymbolValue);
            var symbolReader = new StringSymbolReader(valueReader, true);

            this.IgnoreVoids(symbolReader);

            var readed = symbolReader.Peek();

            if (readed.SymbolType == Utils.GetStringSymbolType(EStringSymbolReaderType.EOF))
            {
                return(new EmptyMathematicsObject());
            }
            else if (readed.SymbolType == Utils.GetStringSymbolType(EStringSymbolReaderType.LEFT_PARENTHESIS))
            {
            }
            else if (readed.SymbolType == Utils.GetStringSymbolType(EStringSymbolReaderType.LEFT_BRACKET))
            {
            }
            else if (readed.SymbolType == Utils.GetStringSymbolType(EStringSymbolReaderType.INTEGER))
            {
                return(new IntegerMathematicsObject()
                {
                    Value = int.Parse(symbolListToParse[0].SymbolValue)
                });
            }
            else if (readed.SymbolType == Utils.GetStringSymbolType(EStringSymbolReaderType.DOUBLE))
            {
                return(new DoubleMathematicsObject()
                {
                    Value = double.Parse(
                        symbolListToParse[0].SymbolValue,
                        CultureInfo.InvariantCulture.NumberFormat)
                });
            }
            else if (readed.SymbolType == Utils.GetStringSymbolType(EStringSymbolReaderType.STRING))
            {
                return(new NameMathematicsObject(symbolListToParse[0].SymbolValue, this.mediator));
            }
            else if (readed.SymbolType == Utils.GetStringSymbolType(EStringSymbolReaderType.DOUBLE_QUOTE))
            {
                return(new StringMathematicsObject()
                {
                    Value = symbolListToParse[0].SymbolValue
                });
            }
            else if (readed.SymbolType == "boolean")
            {
                return(new BooleanMathematicsObject()
                {
                    Value = bool.Parse(symbolListToParse[0].SymbolValue)
                });
            }
            else
            {
                return(null);
            }

            var lispStyleListParser = LispStyleList <AMathematicsObject> .GetParser(this);

            var rangeReader = new RangeNoConfigReader <AMathematicsObject, string, string>();
            var multidimensionalRangeParser = new MultiDimensionalRangeReader <AMathematicsObject, string, string>(rangeReader);
            var multidimensionalRange       = default(MultiDimensionalRange <AMathematicsObject>);
            var parsed = multidimensionalRangeParser.TryParseRange(
                symbolReader,
                this,
                out multidimensionalRange);

            throw new NotImplementedException();
        }
コード例 #14
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);
                }
            }
        }
コード例 #15
0
 /// <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 LispStyleList <R> Parse(
     ISymbol <string, string>[] symbolListToParse,
     ILogStatus <string, EParseErrorLevel> errorLogs)
 {
     throw new NotImplementedException();
 }
コード例 #16
0
        /// <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);
        }
コード例 #17
0
        /// <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);
        }
コード例 #18
0
        /// <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);
                }
            }
        }
コード例 #19
0
        /// <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);
        }