Exemple #1
0
        private static Function CastOperator(Function function)
        {
            //Inicializar el operador a devolver
            Function operatorToReturn = new ConstantArithmetic(0);

            if (function is RelationFunctionArithmetic)
            {
                operatorToReturn = function as RelationFunctionArithmetic;
            }

            else if (function is RelationFunctionBoolean)
            {
                operatorToReturn = function as RelationFunctionBoolean;
            }

            else if (function is LocalFunction)
            {
                operatorToReturn = function as LocalFunction;
            }

            else if (function is SpecialOperator)
            {
                operatorToReturn = function as SpecialOperator;
            }

            return(operatorToReturn);
        }
Exemple #2
0
        //Convierte una expresion de notacion infijo a posfijo
        private static Queue <Function> ShuntingYard(List <Function> expression)
        {
            Stack <Function> stackOperators = new Stack <Function>();
            Queue <Function> queueOut       = new Queue <Function>();

            foreach (Function token in expression)
            {
                //Si es un numero poner en la cola de salida
                if (token is ConstantArithmetic || token is Literal || token is Identity || token is ConstantBoolean)
                {
                    queueOut.Enqueue(token);
                }

                else if (token is N_ary_Function)
                {
                    stackOperators.Push(token);
                }

                #region Si es una coma
                else if (token is Comma)
                {
                    if (stackOperators.Count != 0)
                    {
                        // Hasta que el token en el tope de la pila sea un paréntesis abierto
                        while (!(stackOperators.Peek() is OpenParenthesis))
                        {
                            // retirar (pop) a los operadores de la pila y colocarlos en la cola de salida.
                            queueOut.Enqueue(stackOperators.Pop());
                            if (stackOperators.Count == 0)
                            {
                                MSharpErrors.OnError("Los parentesis no estan balanceados");
                                return(null);
                            }
                        }
                    }

                    else
                    {
                        MSharpErrors.OnError("Incorrecta escritura de ecuacion");//("La pila de operadores esta vacia");
                        return(null);
                    }
                }
                #endregion

                //Si es parantesis abierto poner en la pila
                else if (token is OpenParenthesis)
                {
                    stackOperators.Push(token);
                }

                #region Si es Parentesis Cerrado
                else if (token is ClosedParenthesis)
                {
                    if (stackOperators.Count != 0)
                    {
                        // Hasta que el token en el tope de la pila sea un paréntesis abierto
                        while (!(stackOperators.Peek() is OpenParenthesis))
                        {
                            // retirar (pop) a los operadores de la pila y colocarlos en la cola de salida.
                            queueOut.Enqueue(stackOperators.Pop());
                            if (stackOperators.Count == 0)
                            {
                                MSharpErrors.OnError("Los parentesis no estan balanceados");
                                return(null);
                            }
                        }
                        // Retirar(pop) el paréntesis abierto de la pila
                        stackOperators.Pop();
                    }
                    else
                    {
                        MSharpErrors.OnError("Incorrecta escritura de ecuacion");//("La pila de operadores esta vacia");
                        return(null);
                    }


                    if (token is N_ary_Function)
                    {
                        queueOut.Enqueue(stackOperators.Pop());
                    }
                }
                #endregion

                #region Si es un operador
                else if (token is RelationFunctionArithmetic || token is RelationFunctionBoolean || token is LocalFunction)
                {
                    #region Inicializar Operador1
                    Function operator1 = new ConstantArithmetic(0);

                    operator1 = CastOperator(token);

                    #endregion

                    // Si hay elementos en la pila
                    if (stackOperators.Count != 0)
                    {
                        #region Inicializar Operador2
                        Function operator2 = new ConstantArithmetic(0);

                        //Asignar a operator2 el operador q esta en el tope de la pila
                        operator2 = CastOperator(stackOperators.Peek());

                        if (!(operator2 is OpenParenthesis))
                        {
                            Get_Precedence_Associatity(operator1, operator2);
                        }

                        #endregion

                        #region While
                        // mientras que haya un operador, operator2, en el tope de la pila y no sea el parentesis abierto
                        // y operator1 es asociativo izquierdo y su precedencia es menor o igual que la de operator2 o
                        // operator1 es asociativo derecho y su precedencia es menor que la de operator2
                        while (stackOperators.Count != 0 && !(operator2 is OpenParenthesis) &&
                               ((associativityOper1 && precedenceOper1 <= precedenceOper2) ||
                                (associativityOper1 == false && precedenceOper1 < precedenceOper2)))
                        {
                            // retirar de la pila el operador de su tope y ponerlo en la cola de salida;
                            queueOut.Enqueue(stackOperators.Pop());

                            if (stackOperators.Count != 0)
                            {
                                operator2 = CastOperator(stackOperators.Peek());
                            }
                            if (operator2 is OpenParenthesis)
                            {
                                break;
                            }
                            Get_Precedence_Associatity(operator1, operator2);
                        }
                        #endregion
                    }
                    // Poner a operator1 en el tope de la pila
                    stackOperators.Push(operator1);
                }
                #endregion

                else
                {
                    MSharpErrors.OnError("Operador no valido");
                    return(null);
                }
            }

            //Mientras todavía haya tokens de operadores en la pila:
            while (stackOperators.Count != 0)
            {
                Function operator1 = stackOperators.Peek();

                // Si el token del operador en el tope de la pila es un paréntesis,
                // entonces hay paréntesis sin la pareja correspondiente.
                if (operator1 is OpenParenthesis || operator1 is ClosedParenthesis)
                {
                    MSharpErrors.OnError("Hay paréntesis sin la pareja correspondiente.");
                    return(null);
                }


                queueOut.Enqueue(stackOperators.Pop());
            }

            return(queueOut);
        }
Exemple #3
0
        //Evalua en posfijo usando Notacion Polaca Inversa
        private static Function RPN(Queue <Function> expression_Postfix)
        {
            if (expression_Postfix != null)
            {
                Stack <Function> auxStack = new Stack <Function>();

                #region Recorrer cada token de la expresion
                foreach (Function token in expression_Postfix)
                {
                    //si es un operando
                    if (!(token is RelationFunctionArithmetic) && !(token is RelationFunctionBoolean) && !(token is LocalFunction))
                    {
                        auxStack.Push(token);
                    }

                    //si es un operador
                    else
                    {
                        //Inicializar variable
                        Function operator1 = new ConstantArithmetic(0);

                        if (token is RelationFunctionArithmetic)
                        {
                            operator1 = token as RelationFunctionArithmetic;
                        }

                        if (token is RelationFunctionBoolean)
                        {
                            operator1 = token as RelationFunctionBoolean;
                        }

                        if (token is LocalFunction)
                        {
                            operator1 = token as LocalFunction;
                        }

                        GetArityOperator(operator1);
                        //comprobar que existan la cantidad necesaria de operandos para trabajar con cierto operador
                        if (arityOper1 > auxStack.Count)
                        {
                            MSharpErrors.OnError(string.Format("Insuficientes operandos para el operador {0}", token.ToString()));
                            return(null);
                        }



                        else
                        {
                            //Inicializar Variable con cualquier valor
                            Function result = new ConstantArithmetic(0);

                            #region Sacar operandos de la pila e introducirlos en ella despues de operarlos
                            //Guardar en array los operandos a procesar
                            //Se crea array de tamaño de la aridad del operador
                            object[] parametersOperand = new object[arityOper1];

                            //Asignar los operandos
                            for (int i = parametersOperand.Length - 1; i >= 0; i--)
                            {
                                parametersOperand[i] = auxStack.Pop();
                            }

                            //Obtener el tipo de operador
                            Type typeOperator1 = operator1.GetType();

                            //
                            Type[] parameterConstructor = new Type[parametersOperand.Length];

                            if (token is RelationFunctionArithmetic)
                            {
                                for (int i = 0; i < parameterConstructor.Length; i++)
                                {
                                    parameterConstructor[i] = typeof(FunctionArithmetic);
                                }
                            }

                            else if (token is LocalFunction)
                            {
                                for (int i = 0; i < parameterConstructor.Length; i++)
                                {
                                    parameterConstructor[i] = typeof(LocalFunction);
                                }
                            }

                            else if (token is Relational)
                            {
                                for (int i = 0; i < parameterConstructor.Length; i++)
                                {
                                    parameterConstructor[i] = typeof(FunctionArithmetic);
                                }
                            }

                            //Es Operador Lógico
                            else
                            {
                                for (int i = 0; i < parameterConstructor.Length; i++)
                                {
                                    parameterConstructor[i] = typeof(FunctionBoolean);
                                }
                            }

                            ConstructorInfo info = typeOperator1.GetConstructor(parameterConstructor);

                            if (token is LocalFunction)
                            {
                                result = new LocalFunction(token.ToString(), parametersOperand[0] as FunctionArithmetic);
                            }

                            else if (token is RelationFunctionArithmetic)
                            {
                                result = (RelationFunctionArithmetic)info.Invoke(parametersOperand);
                            }

                            //Si es FunctionBoolean
                            else if (token is FunctionBoolean)
                            {
                                result = (RelationFunctionBoolean)info.Invoke(parametersOperand);
                            }

                            else
                            {
                                MSharpErrors.OnError("Compilation Error");
                                return(null);
                            }


                            #endregion
                            auxStack.Push(result);
                        }
                    }
                }
                #endregion

                //Si la pila contiene solo un elemento, entonces ese es el resultado de la expresion
                if (auxStack.Count == 1)
                {
                    Function toReturn = auxStack.Pop();
                    return(toReturn);
                }
            }

            MSharpErrors.OnError("Se ha introducido de manera incorrecta la expresion");
            return(null);
        }