private bool SyntacticAnalysis(List <Expression> instruction) { //Comprobar que exista solo un elemento luego del include if (instruction.Count != 1) { MSharpErrors.OnError("Despues de include solo puede existir un nombre de modulo"); return(false); } //Comprobar que sea tipo Text if (!(instruction[0] is Text)) { MSharpErrors.OnError("Compilation Error. Nombre de modulo invalido"); return(false); } //Comprobar que no sea una variable de texto y si solo un string ("Example") if ((instruction[0] as Text).isOnlyText == false) { MSharpErrors.OnError("Compilation Error. include recibe una cadena de texto y no un literal tipo string"); return(false); } return(LoadFile((instruction[0] as Text).Value)); }
/// <summary> /// Representa un analisis sintactico de la expresion /// </summary> /// <returns>True si la expresion esta bien escrita, false en caso contrario.</returns> private bool SyntacticAnalysis(List <Expression> instruction) { //Tiene que haber al menos tres tokens (<name> = value) if (instruction.Count < 3) { MSharpErrors.OnError("Compilation Error. Comando set tiene minimo 3 token"); return(false); } //Si no es un literal lo que viene luego del let if (!(instruction[0] is Literal) && !(instruction[0] is Text)) { MSharpErrors.OnError("Incorrecto nombre en la declaracion de literal"); return(false); } //Toda intruccion set posee el operador igual luego del nombre del tipo que se quiere cambiar. if (!(instruction[1] is Assign)) { MSharpErrors.OnError("= expected"); return(false); } return(true); }
public override float Evaluate(float x) { if (!(_function is IDerivate)) { MSharpErrors.OnError(string.Format("Compilation Error. Funcion no derivable")); return(0); } return((_function as IDerivate).Derive.Evaluate(x)); }
private static bool AnalizeVariable(string name) { if (name == null) { MSharpErrors.OnError(string.Format("La variable {0} no ha sido declarada", name)); return(false); } return(true); }
//public static /// <summary> /// Representa un analisis sintactico de la expresion /// </summary> /// <returns>True si la expresion esta bien escrita, false en caso contrario.</returns> private bool SyntacticAnalysis(List <Expression> instruction) { if (!(instruction.Count >= 6)) { MSharpErrors.OnError("Compilation Error. Incorrecta declaracion de funcion"); return(false); } //Verificar que es un tipo variable lo que viene luego del def. En este caso seria el nombre de la funcion. if (!(instruction[0] is LocalFunction)) { MSharpErrors.OnError("Incorrecto nombre en la declaracion de la funcion."); return(false); } //Nombre con que fue declarada la funcion name = instruction[0].ToString(); if (!(instruction[1] is OpenParenthesis)) { MSharpErrors.OnError("( expected"); return(false); } //Verificar que es un tipo variable lo que viene luego del parentesis abierto. En este caso seria el termino independiente de la funcion. if (!(instruction[2] is Literal)) { MSharpErrors.OnError("Incorrecto nombre de termino independiente de la funcion."); return(false); } //Termino independiente de la funcion parameter = instruction[2].ToString(); if (!(instruction[3] is ClosedParenthesis)) { MSharpErrors.OnError(") expected"); return(false); } if (!(instruction[4] is Assign)) { MSharpErrors.OnError("= expected"); return(false); } //Para trabajar solo con el miembro a la derecha del = instruction.RemoveRange(0, 5); //Identificar el termino independiente en la funcion. No confundir con las variables locales!!! RecognizeParameter(instruction, parameter); return(true); }
/// <summary> /// Representa un analisis sintactico de la expresion /// </summary> /// <returns>True si la expresion esta bien escrita, false en caso contrario.</returns> private bool SyntacticAnalysis(List <Expression> instruction) { if (instruction.Count == 0) { MSharpErrors.OnError("Comando print tiene que tener alguna instruccion a mostrar"); return(false); } RecognizeText(instruction); return(true); }
/// <summary> /// Constructor de funcion local /// </summary> /// <param name="name">Representa el nombre de la funcion</param> /// <param name="fparam">Representa la funcion en la que se desea evaluar dicha funcion</param> public LocalFunction(string name, FunctionArithmetic fparam) { _existFunction = true; _name = name; _function = fparam; if (!Memory.DataFunction.ContainsKey(name)) { _existFunction = false; MSharpErrors.OnError(string.Format("La funcion {0} no ha sido declarada", _name)); } }
internal static void SaveText(string nameVariable, string text) { if (AnalizeText(nameVariable, text) == false) { return; } if (ExistName(nameVariable)) { MSharpErrors.OnError(string.Format("Existe ya otro tipo con el nombre {0}", nameVariable)); return; } Memory.DataText.Add(nameVariable, text); }
private static bool DerivateList() { for (int i = 0; i < _listBody.Count; i++) { if (!(_listBody[i] is IDerivate)) { MSharpErrors.OnError("La funcion no es derivable"); return(false); } _listBody[i] = (_listBody[i] as IDerivate).Derive; } return(true); }
internal static void SaveFunction(string name, FunctionArithmetic function) { if (AnalizeFunction(name, function) == false) { return; } if (ExistName(name)) { MSharpErrors.OnError(string.Format("Existe ya otro tipo con el nombre {0}", name)); return; } Memory.DataFunction.Add(name, function); }
internal static void SaveVariable(string name, float number) { if (AnalizeVariable(name) == false) { return; } if (ExistName(name)) { MSharpErrors.OnError(string.Format("Existe ya otro tipo con el nombre {0}", name)); return; } Memory.DataVariable.Add(name, number); }
internal static string GetText(string name) { if (AnalizeVariable(name) == false) { return(null); } if (!DataText.ContainsKey(name)) { MSharpErrors.OnError(string.Format("La variable {0} no ha sido declarada", name)); return(null); } return(DataText[name]); }
internal static void ChangeText(string name, string text) { if (AnalizeText(name, text) == false) { return; } if (!DataText.ContainsKey(name)) { MSharpErrors.OnError(string.Format("El Literal {0} no ha sido declarado", name)); return; } Memory.DataText[name] = text; }
private static bool AnalizeFunction(string name, FunctionArithmetic function) { if (name == null || function == null) { if (name == null) { MSharpErrors.OnError(string.Format("Compilation Error. Nombre de variable no puede ser null", name)); } else { MSharpErrors.OnError(string.Format("Compilation Error. La funcion {0} no puede ser null", name)); } return(false); } return(true); }
private static bool AnalizeText(string nameVariable, string text) { if (nameVariable == null || text == null) { if (nameVariable == null) { MSharpErrors.OnError(string.Format("Compilation Error. Nombre de Literal {0} no puede ser null", nameVariable)); } else { MSharpErrors.OnError(string.Format("Compilation Error. El texto: {0} no puede ser null", text)); } return(false); } return(true); }
internal static FunctionArithmetic GetFunction(string name) { if (name == null) { MSharpErrors.OnError(string.Format("El nombre de funcion {0} no puede ser null", name)); return(null); } if (!DataFunction.ContainsKey(name)) { MSharpErrors.OnError(string.Format("La funcion {0} no ha sido declarada", name)); return(null); } return(DataFunction[name]); }
/// <summary> /// Representa un analisis sintactico de la expresion /// </summary> /// <returns>True si la expresion esta bien escrita, false en caso contrario.</returns> private bool SyntacticAnalysis(List <Expression> instruction) { if (instruction.Count != 1) { MSharpErrors.OnError("Incorrecta sintaxis de read"); return(false); } if (!(instruction[0] is Literal)) { MSharpErrors.OnError("Solo se aplica read a los literales"); return(false); } _name = instruction[0].ToString(); return(true); }
/// <summary> /// Representa un analisis sintactico de la expresion /// </summary> /// <returns>True si la expresion esta bien escrita, false en caso contrario.</returns> private bool SyntacticAnalysis(List <Expression> instruction) { if (instruction.Count == 0) { MSharpErrors.OnError("Se esperaba una funcion a graficar"); return(false); } //Identificar Literales for (int i = 0; i < instruction.Count; i++) { if (instruction[i] is Literal && !Memory.ExistName(instruction[i].ToString())) { instruction[i] = new Identity(); } } return(true); }
//Metodo que carga el modulo guardado private bool LoadFile(string fileName) { //Se crea un objeto de la Clase FileInfo, pasándole como parámetro el nombre del archivo //sobre el cual queremos trabajar FileInfo moduleInfo = new FileInfo(fileName); //Verificar q exista el fichero if (!moduleInfo.Exists) { MSharpErrors.OnError(string.Format("No existe el modulo {0}", fileName)); return(false); } //Cargar en un RichTextBox el fichero fileName guardado en formato RTF RichTextBox rtbLoadFile = new RichTextBox(); rtbLoadFile.LoadFile(fileName); allCode = rtbLoadFile.Text; return(true); }
internal static float GetVariable(string name) { if (AnalizeVariable(name) == false) { return(0); } if (name == null) { MSharpErrors.OnError(string.Format("Compilation Error. Nombre de variable no puede ser null", name)); return(0); } if (!DataVariable.ContainsKey(name)) { MSharpErrors.OnError(string.Format("La variable {0} no ha sido declarada", name)); return(0); } return(DataVariable[name]); }
public static void ChangeVariable(string name, float number) { if (AnalizeVariable(name) == false) { return; } if (name == null) { MSharpErrors.OnError(string.Format("Compilation Error. Nombre de variable no puede ser null", name)); return; } if (!DataVariable.ContainsKey(name)) { MSharpErrors.OnError(string.Format("La variable {0} no ha sido declarado", name)); return; } Memory.DataVariable[name] = number; }
/// <summary> /// Halla la derivada de una funcion condicional /// </summary> /// <param name="listBody">Posee los tramos de la funcion</param> /// <param name="listCondition">Condiciones</param> /// <returns>Una funcion condicional que fue resultado de la derivada</returns> public static ConditionalFunction GetDerivate(List <FunctionArithmetic> listBody, List <FunctionBoolean> listCondition) { Reset(); _listBody = listBody; _listCondition = listCondition; //Significa que termina en else -> ultima condicion true si no ocurre ninguna otra if (_listBody.Count - _listCondition.Count == 1) { _listCondition.Add(new ConstantBoolean(true)); } if (DerivateList()) { return(Create_Function(0)); } MSharpErrors.OnError("Error. La funcion no tiene derivada"); return(null); }
//Ejecuta cada codigo dependiendo del keyword que se este analizando private bool ExecuteKeyWord(List <Expression> instruction) { if (!_isInclude) { _lineError++; } //Todas las lineas de codigo tienen que comenzar por un tipo keyword if (instruction[0] is IExecutable == false) { MSharpErrors.OnError(string.Format("{0} no es un comando valido", instruction[0].ToString())); return(false); } //Si ya hubo algun error no ejecutar el codigo siguienteb if (_haveError == true) { return(false); } (instruction[0] as IExecutable).Execute(instruction); return(true); }
//Metodo que asigna a las listas miembros de la clase, las funciones aritmeticas y las //funciones booleanas(proposiciones) de la condicional private static bool Create_List(List <Expression> expression) { List <Function> function = new List <Function>(); for (int i = 0; i < expression.Count; i++) { if (expression[i] is If) { Function tempFunction1 = Converter_ShuntingYard.FetchFunction(function); if (!(tempFunction1 is FunctionArithmetic)) { MSharpErrors.OnError("Incorrecta expresion"); return(false); } FunctionArithmetic tempFunction = tempFunction1 as FunctionArithmetic; _listBody.Add(tempFunction); function.Clear(); } else if (expression[i] is Else) { Function tempFunction1 = Converter_ShuntingYard.FetchFunction(function); if (!(tempFunction1 is FunctionBoolean)) { MSharpErrors.OnError("Incorrecta expresion"); return(false); } FunctionBoolean tempFunction = tempFunction1 as FunctionBoolean; _listCondition.Add(tempFunction); function.Clear(); } else { if (!(expression[i] is Function)) { MSharpErrors.OnError("Incorrecta expresion"); return(false); } function.Add(expression[i] as Function); } } //Formar funcion que quedó Function lastFunction = Converter_ShuntingYard.FetchFunction(function); if (!(lastFunction is FunctionArithmetic) && !(lastFunction is FunctionBoolean)) { MSharpErrors.OnError("Incorrecta expresion"); return(false); } if (lastFunction is FunctionArithmetic) { _listBody.Add(lastFunction as FunctionArithmetic); } else { _listCondition.Add(lastFunction as FunctionBoolean); } if (_listBody.Count < _listCondition.Count == true) { MSharpErrors.OnError("Incorrecta funcion"); return(false); } //Significa que termina en else -> ultima condicion true si no ocurre ninguna otra if (_listBody.Count - _listCondition.Count == 1) { _listCondition.Add(new ConstantBoolean(true)); } return(true); }
//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); }
//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); }
/// <summary> /// Analiza e interpreta los token /// </summary> /// <param name="tokens"> Tokens a interpretar</param> /// <returns>Una lista con objetos del lenguaje M#</returns> public static List <Expression> Analize(IEnumerable <Token> tokens) { List <Expression> toReturn = new List <Expression>(); foreach (var item in tokens) { if (item.Text == "(" && toReturn.Count != 0) { if (toReturn[toReturn.Count - 1] is Literal) { toReturn[toReturn.Count - 1] = new LocalFunction(toReturn[toReturn.Count - 1].ToString()); } } if (item.Type == TokenKind.Unknown) { MSharpErrors.OnError(string.Format("{0} es un simbolo desconocido", item.Text)); } else if ((item.Text == "+" || item.Text == "-") && isOKPosicion_OperatorUnary_Sign(toReturn)) { toReturn.Add(Memory.MSharpTypes[item.Text + "unary"]); } else if (item.Text == "=" && isOKPosicion_Operator_RelationalComposite(toReturn)) { Expression lastToken = toReturn[toReturn.Count - 1]; toReturn[toReturn.Count - 1] = (Memory.MSharpTypes[lastToken.ToString() + "="]); } else if (item.Type == TokenKind.Symbol || item.Type == TokenKind.Keyword) { toReturn.Add(Memory.MSharpTypes[item.Text]); } else if (item.Type == TokenKind.Number) { //float floatNumber = float.Parse(item.Text);//Change_Dot_by_Comma(item.Text)); toReturn.Add(new ConstantArithmetic(float.Parse(item.Text))); } else if (item.Type == TokenKind.Text) { if (toReturn.Count > 2) { if (toReturn[toReturn.Count - 2] is Literal) { toReturn[toReturn.Count - 2] = new Text(toReturn[toReturn.Count - 2].ToString(), item.Text); } } toReturn.Add(new Text(item.Text, true)); } else if (item.Type == TokenKind.Identifier) { toReturn.Add(new Literal(item.Text)); } } return(toReturn); }