Exemplo n.º 1
0
        public override void CheckSemantic(Scope scope, List<Error> errors)
        {
            SizeExp.CheckSemantic(scope, errors);
            if (!SizeExp.ReturnType.MatchWith(IntType.IntInstance))
            {
                errors.Add(new Error(SizeExp,"La expresión para definir la longitud de un array debe ser de tipo 'int' y se encontró una expresión de tipo '{0}'", SizeExp.ReturnType));
                HasError = true;
            }
            InitialValueExp.CheckSemantic(scope, errors);
            TigerType myTypeDec = scope.GetType(TypeName);
            if (myTypeDec == null)
            {
                errors.Add(new Error(GetChild(0),"El tipo '{0}' no existe en el ámbito actual", TypeName));
                HasError = true;
                ReturnType = UndefinedType.UndefinedInstance;
            }
            else if (!(myTypeDec is ArrayType))
            {
                errors.Add(new Error(GetChild(0), "El tipo de una expresión de creación de 'array' debe ser de un tipo definido como 'array' y se encontró '{0}'", TypeName));
                HasError = true;
                ReturnType = UndefinedType.UndefinedInstance;
            }
            else if (!InitialValueExp.ReturnType.MatchWith(((ArrayType)myTypeDec).ElementsType))
            {

                errors.Add(new Error(InitialValueExp, "En una expresión de instanciación de un array, el tipo de los elementos del 'array' debe coincidir con la expresión de inicialización y se encontraron expresiones con los tipos '{0}' y '{1}'", ((ArrayType)myTypeDec).ElementsType, InitialValueExp.ReturnType));
                HasError = true;
                ReturnType = UndefinedType.UndefinedInstance;
            }
            else
                ReturnType = myTypeDec;
        }
        public override void CheckSemantic(Scope scope, List<Error> errors)
        {
            //la comprobacion de si hay algun campo repetido se hace en el RecordDecNode

            RelatedType = scope.GetType(TypeName);
            if (RelatedType == null)
            {
                errors.Add(new Error(GetChild(1),"El tipo '{0}' no está definido en el ámbito actual", TypeName));
                HasError = true;
                RelatedType = UndefinedType.UndefinedInstance;
            }
        }
Exemplo n.º 3
0
 public override void CheckSemantic(Scope scope, List<Error> errors)
 {
     //es añadido al scope en el CheckSemantic del TypeDeclarationSecuence si no esta redefinido incorrectamente
     TigerType elementsType = scope.GetType(ElementsTypeName);
     if (elementsType == null)
     {
         errors.Add(new Error(GetChild(1), "El tipo '{0}' no está definido en el ámbito actual", ElementsTypeName));
         HasError = true;
         RelatedType = new ArrayType(UndefinedType.UndefinedInstance, ElementsTypeName);
     }
     else
         RelatedType = new ArrayType(elementsType, ElementsTypeName);
 }
Exemplo n.º 4
0
        public override void CheckSemantic(Scope scope, List<Error> errors)
        {
            //es añadido al scope en el CheckSemantic del TypeDeclarationSecuence si no esta redefinido incorrectamente
            if (TypeName.CompareTo("int") == 0 || TypeName.CompareTo("string") == 0)
                errors.Add(new Error(GetChild(0), "El tipo '{0}' está definido en la Biblioteca Estándar de Tiger y no puede ser redefinido", TypeName));

            RelatedType = scope.GetType(BaseTypeName);
            if (RelatedType == null)
            {
                errors.Add(new Error(GetChild(1), "El tipo '{0}' no está definido en el ámbito actual", BaseTypeName));
                HasError = true;
                RelatedType = UndefinedType.UndefinedInstance;
            }
        }
Exemplo n.º 5
0
        public override void CheckSemantic(Scope scope, List<Error> errors)
        {
            TigerType type = scope.GetType(TypeName);
            if (type == null)
            {
                errors.Add(new Error(GetChild(0), "El tipo '{0}' no está definido en el ámbito atual", TypeName));
                HasError = true;
                ReturnType = UndefinedType.UndefinedInstance;
                return;
            }

            RecordType recordType = type as RecordType;
            if (recordType == null)
            {
                errors.Add(new Error(GetChild(0), "El tipo de una expresión de creación de 'record' debe ser de un tipo definido como 'record' y se encontró '{0}'", TypeName));
                HasError = true;
                ReturnType = UndefinedType.UndefinedInstance;
                return;
            }

            ReturnType = recordType;
            for (int i = 0; i < Fields.Count; i++)
            {
                FieldExpPair member = Fields[i];
                member.CheckSemantic(scope, errors);
                string realName;
                RecordVariableDecNode memberDec = recordType.GetField(i,out realName);
                if (realName == null)
                {
                    errors.Add(
                        new Error(member.GetChild(0),"El tipo definido como 'record' '{0}' no tiene definido un campo no. {1}", TypeName,(i + 1)));
                    HasError = true;
                }
                else if (realName.CompareTo(member.Name) != 0)
                {
                    errors.Add(
                        new Error(member.GetChild(0),"El campo no. {0} del tipo definido como 'record' '{1}' no se declaró con el nombre '{2}' sino con el nombre '{3}'",
                                  (i + 1), TypeName, member.Name, realName));
                    HasError = true;
                }
                else if (!member.Exp.ReturnType.MatchWith(memberDec.RelatedType))
                {
                    errors.Add(
                        new Error(member.Exp,
                            "En una expresión de creación de un 'record' el tipo de cada campo debe coincidir con el tipo de su expresión de inicialización y en el campo '{0}' se encontraron los tipos '{1}' y '{2}'", member.Name, memberDec.RelatedType, member.Exp.ReturnType));
                    HasError = true;
                }
            }
        }
Exemplo n.º 6
0
 public override void CheckSemantic(Scope scope, List<Error> errors)
 {
     InitialExp.CheckSemantic(scope, errors);
     //se pone por defecto con error y de tipo indefinido para factorizar
     HasError = true;
     RelatedType = UndefinedType.UndefinedInstance;
     if (TypeName != null) //se conoce el tipo de la variable
     {
         TigerType formalType = scope.GetType(TypeName);
         if (formalType == null) //el tipo formal no esta definido
             errors.Add(new Error(GetChild(2),"El tipo '{0}' no ha sido definido en el ámbito actual", TypeName));
         else
             if (!InitialExp.ReturnType.MatchWith(formalType)) //el tipo real no coincide con el formal
             {
                 errors.Add(new Error(InitialExp, "En una declaración el tipo de variable debe coincidir con el tipo de la expresión de inicialización y se encontró el tipo '{0}' y una expresión de tipo '{1}'", formalType, InitialExp.ReturnType));
                 RelatedType = formalType; // En C# si se declara 'string a = 5' se asume que 'a' es de tipo 'string' aunque no machee
             }
             else //si entra aqui es que no hay error
             {
                 HasError = false;
                 RelatedType = formalType;
             }
     }
     else //se debe inferir el tipo de la variable
     {
         if (InitialExp.ReturnType == NillType.NillInstance)
             errors.Add(new Error(InitialExp,"No es posible inferir el tipo de la variable '{0}' debido a que la expresión de inicialización es de tipo 'nil'",VariableName));
         else if (InitialExp.ReturnType.MatchWith(VoidType.VoidInstance))
             errors.Add(new Error(InitialExp,"No es posible inferir el tipo de la variable debido a que la expresión de inicialización es de tipo 'void'"));
         else //si entra aqui es que no hay error
         {
             HasError = false;
             RelatedType = InitialExp.ReturnType;
         }
     }
     DeclarationNode varDeclaretions = scope.GetFunVar(VariableName, false);
     if (varDeclaretions != null)
     {
         if (varDeclaretions is VariableDecNode)
             errors.Add(new Error(GetChild(0),"No es posible definir una variable con el nombre '{0}' debido a que existe otra variable con igual nombre dentro del mismo 'let'",VariableName));
         else
             errors.Add(new Error(GetChild(0),"No es posible definir una variable con el nombre '{0}' debido a que existe una función con igual nombre dentro del mismo 'let'", VariableName));
         HasError = true;
     }
     else
         scope.AddFunVar(VariableName, this);
 }
        public override void CheckSemantic(Scope scope, List<Error> errors)
        {
            #region declaracion de variables utilizadas
            HashSet<string> typesNames = new HashSet<string>();
            var graphNodes = new Dictionary<string, TypeDecNode>();
            List<RecordDecNode> firstsRecordDecs = new List<RecordDecNode>();
            List<TypeDecNode> redefinedDecs = new List<TypeDecNode>();
            Dictionary<string, List<string>> reverseGraph;
            Dictionary<string, List<string>> graph;
            #endregion

            #region detectar redefiniciones y almacenar para procesarlas, añadir records no repetidos al scope, detectar nodos del grafo
            foreach (TypeDecNode typeDec in Declarations)
                if (scope.GetType(typeDec.TypeName,false) != null || !typesNames.Add(typeDec.TypeName))//detectar redefiniciones y almacenar para procesarlos al final
                {
                    errors.Add(new Error(typeDec.GetChild(0),"No es posible definir un tipo con el nombre '{0}' debido a que existe otro tipo con igual nombre dentro de un mismo 'let'", typeDec.TypeName));
                    HasError = true;
                    if (typeDec is RecordDecNode)
                        typeDec.RelatedType = new RecordType(typeDec.TypeName);
                    redefinedDecs.Add(typeDec);
                }
                else if (typeDec is RecordDecNode)//poner el tipo y añadir al scope
                {
                    firstsRecordDecs.Add((RecordDecNode)typeDec);
                    typeDec.RelatedType = new RecordType(typeDec.TypeName);
                    scope.AddType(typeDec.TypeName, typeDec.RelatedType);
                }
                else //es alias o array
                    graphNodes.Add(typeDec.TypeName, typeDec); //añadir el nodo al grafo
            #endregion

            #region añadir las aristas al grafo y al reverso del grafo a partir de los nodos del grafo
            CreateGraph(graphNodes, out graph, out reverseGraph);
            #endregion

            #region detectar nodos que pertenecen a ciclos usando SCC y procesarlos
            List<List<string>> scc = SCC(graph, reverseGraph);

            foreach (var component in scc)
                //si la componente tiene mas de un nodo || tiene un nodo con una referencia a si mismo (los nodos tienen siempre 0 o 1 referenecia)
                if (component.Count > 1 || (graph[component[0]].Count == 1 && graph[component[0]][0].CompareTo(component[0]) == 0)) //todos los nodos de la componente son invalidos
                    foreach (string s in component)
                    {
                        TypeDecNode node = graphNodes[s];
                        graphNodes.Remove(s); //eliminar s del grafo para convertirlo en un DAG
                        //reportar error
                        errors.Add(new Error(node.GetChild(0),"El tipo '{0}' está definido en función de si mismo",s));
                        //procesar los nodos invalidos
                        if (node is AliasDecNode)//alias -> RelatedType = Undef
                            node.RelatedType = UndefinedType.UndefinedInstance;
                        if (node is ArrayDecNode)//array -> RelatedType = new Array(Undef)
                            node.RelatedType = new ArrayType(UndefinedType.UndefinedInstance, node.TypeName);
                        scope.AddType(s,node.RelatedType);
                    }

            #endregion

            #region hallar el subgrafo que es un DAG y hacer order topologico invertido
            CreateGraph(graphNodes, out graph, out reverseGraph, false); //el reverso no es necesario en este caso
            List<string> order = ReversedTopologicalSort(graph);
            #endregion

            #region chequear semantica de los nodos en el orden topologico invertido y añadirlos al scope
            foreach (string s in order)
            {
                var node = graphNodes[s];
                node.CheckSemantic(scope, errors);
                scope.AddType(s,node.RelatedType);
            }

            #endregion

            #region chequear semantica de los records
            foreach (var recordDec in firstsRecordDecs)
                recordDec.CheckSemantic(scope, errors); //ya se añadieron al scope
            #endregion

            #region chequear semantica de los repetidos
            foreach (var redefinedDec in redefinedDecs)
                redefinedDec.CheckSemantic(scope, errors); //no se añaden al scope pq estan repetidos
            #endregion
        }
        public override void CheckSemantic(Scope scope, List<Error> errors)
        {
            foreach (FunctionDecNode funcDec in Declarations)
            {
                #region determinar el tipo de retorno
                if (funcDec.ReturnTypeName == null) // es un procedure
                    funcDec.RelatedType = VoidType.VoidInstance;
                else // es una function
                {
                    TigerType funType = scope.GetType(funcDec.ReturnTypeName);
                    if (funType == null)
                    {
                        errors.Add(
                            new Error(funcDec.GetChild(0),
                                "El tipo '{0}' no está definido en el ámbito actual", funcDec.ReturnTypeName));
                        HasError = true;
                        funcDec.RelatedType = UndefinedType.UndefinedInstance;
                    }
                    else
                        funcDec.RelatedType = funType;
                }

                #endregion

                #region determinar el tipo de cada parametro
                foreach (FunctionVariableDecNode paramDecl in funcDec.Arguments)
                {
                    TigerType paramType = scope.GetType(paramDecl.TypeName);
                    if (paramType == null)
                    {
                        paramDecl.RelatedType = UndefinedType.UndefinedInstance;
                        HasError = true;
                        errors.Add(new Error(paramDecl.GetChild(0),"El tipo '{0}' no está definido en el ámbito actual", paramDecl.TypeName));
                    }
                    else
                        paramDecl.RelatedType = paramType;
                }
                #endregion

                #region añadir la funcion al scope si no esta repetida

                DeclarationNode funDeclarations = scope.GetFunVar(funcDec.Name, false);
                if (funDeclarations != null)
                {
                    if (funDeclarations is FunctionDecNode)
                        errors.Add(new Error(funcDec.GetChild(0),"No es posible definir una función con el nombre '{0}' debido a que existe otra función con igual nombre dentro de un mismo 'let'", funcDec.Name));
                    else
                        errors.Add(new Error(funcDec.GetChild(0), "No es posible definir una función con el nombre '{0}' debido a que existe una variable con igual nombre dentro de un mismo 'let'", funcDec.Name));
                    HasError = true;
                }
                else if (BuiltInFunctions.Functions.Contains(funcDec.Name))
                {
                    errors.Add(new Error(funcDec.GetChild(0),"La función '{0}' está definida en la Biblioteca Estándar de Tiger y no puede ser redefinida", funcDec.Name));
                    HasError = true;
                }
                else
                    scope.AddFunVar(funcDec.Name, funcDec);
                #endregion
            }
            foreach (FunctionDecNode funcDecl in Declarations)
                funcDecl.CheckSemantic(scope, errors);
        }