public object VisitTypeAST([NotNull] TypeASTContext context)
        {
            IdentASTContext ident = (IdentASTContext)Visit(context.ident());

            if (ident != null)
            {
                if (types.Contains(ident.GetText()))
                {
                    if (context.SQUAREBL() != null)
                    {
                        if (types.Contains(ident.GetText() + "[]"))
                        {
                            return(ident.GetText() + "[]");
                        }
                        InsertError(ident.IDENT().Symbol, "No se pueden declarar arreglos de tipo" + ident.IDENT().GetText() + " porque no es un tipo simple");
                    }
                    else
                    {
                        return(ident.GetText());
                    }
                }
                else
                {
                    InsertError(ident.IDENT().Symbol, "El tipo " + ident.IDENT().GetText() + " no existe");
                }
            }
            return(null);
        }
        public object VisitMethodDeclAST([NotNull] MethodDeclASTContext context)
        {
            string type = "void";

            if (context.type() != null)
            {
                type = (string)Visit(context.type());
            }

            IdentASTContext ident = (IdentASTContext)Visit(context.ident());

            if (ident != null)
            {
                if (!ExistIdent(ident.IDENT().Symbol.Text, true))
                {
                    MethodIdentifier identifier = new MethodIdentifier(ident.IDENT().Symbol.Text, ident.IDENT().Symbol, identificationTable.getLevel(), type,
                                                                       context, (FormParsASTContext)context.formPars());

                    identificationTable.Insert(identifier);

                    identificationTable.OpenLevel(); // Para los parámetros ya existe un scope nuevo
                    if (context.formPars() != null)
                    {
                        Visit(context.formPars()); //Cuando se visitan los parámetros y se encuentra un error, ellos lo reportan
                    }
                    if (context.varDecl() != null)
                    {
                        context.varDecl().ToList().ForEach(varDecl => Visit(varDecl));
                    }

                    if (context.block() != null)
                    {
                        List <Pair <string, IToken> > returnedTypes = Visit(context.block()) as List <Pair <string, IToken> >;
                        returnedTypes.ForEach(returned => {
                            if (returned.a != null && (!returned.a.Equals(type) && (type == "void" || returned.a != "none")))
                            {
                                InsertError(returned.b, $"El tipo de retorno del método {identifier.Id} es {type}, pero se retorna {(returned.a == "none" ? "null" : returned.a)}");
                            }
                        });
                    }

                    identificationTable.CloseLevel();
                }
                else
                {
                    InsertError(ident.IDENT().Symbol, "El identificador " + ident.IDENT().Symbol.Text + " ya fue declarado en este scope");
                }
            }


            return(null);
        }
 public object VisitIdentAST([NotNull] IdentASTContext context)
 {
     if (context.IDENT() != null)
     {
         Identifier identifier = identificationTable.Find(context.IDENT().Symbol.Text, false);
         if (identifier != null)
         {
             context.decl = identifier.Declaration;
         }
         return(context);
     }
     return(null);
 }
        public object VisitConstDeclAST([NotNull] ConstDeclASTContext context)
        {
            string type = (string)Visit(context.type());

            if (type != null)
            {
                if (type != "int" && type != "char")
                {
                    InsertError(context.Start,
                                "Los tipo para una constante solo pueden ser int o char");
                    return(null);
                }
                IdentASTContext ident = (IdentASTContext)Visit(context.ident());
                if (ident != null)
                {
                    if (!ExistIdent(ident.IDENT().Symbol.Text, true))
                    {
                        Identifier identifier = new ConstIdentifier(ident.IDENT().GetText(), ident.IDENT().Symbol, identificationTable.getLevel(), type, context);
                        identificationTable.Insert(identifier);



                        if ((context.NUM() != null &&
                             ((context.NUM().GetText().Split('.').Length > 1 && type != "float") ||
                              (context.NUM().GetText().Split('.').Length == 1 && type != "int")))
                            ||
                            (context.STRING() != null && type != "string") ||
                            (context.CHARCONST() != null && type != "char"))
                        {
                            InsertError(context.EQUAL().Symbol,
                                        "El tipo para la constante " + ident.GetText() + " no coincide con el tipo de " + context.GetText().Split('=').Last());
                        }
                    }
                    else
                    {
                        InsertError(ident.IDENT().Symbol, "El identificador " + ident.IDENT().Symbol.Text + " ya fue declarado en este scope");
                    }
                }
            }
            return(null);
        }
        public object VisitClassDeclAST([NotNull] ClassDeclASTContext context)
        {
            IdentASTContext ident = (IdentASTContext)Visit(context.ident());

            if (ident != null)
            {
                if (!ExistIdent(ident.GetText(), true))
                {
                    List <VarDeclASTContext> varDecls = new List <VarDeclASTContext>(context.varDecl().ToList().Cast <VarDeclASTContext>());
                    varDecls.ForEach(varDecl => Visit(varDecl));
                    ClassIdentifier classIdentifier = new ClassIdentifier(ident.IDENT().GetText(), ident.IDENT().Symbol, identificationTable.getLevel(), types[0], context, varDecls);

                    identificationTable.Insert(classIdentifier);
                    types.Add(ident.GetText());
                }
                else
                {
                    InsertError(ident.IDENT().Symbol, "El identificador " + ident.IDENT().Symbol.Text + " ya fue declarado en este scope");
                }
            }
            return(null);
        }
        public object VisitDesignatorAST([NotNull] DesignatorASTContext context)
        {
            if (ExistIdent(context.ident()[0].GetText(), false))
            {
                Identifier identifier = identificationTable.Find(context.ident()[0].GetText(), false);
                if (context.ident().Length == 1 && context.SQUAREBL().Length == 0 && context.DOT().Length == 0)
                {
                    Visit(context.ident()[0]);
                    return(identifier);
                }
                else if (identifier is ArrayIdentifier || identifier is InstanceIdentifier)
                {
                    Visit(context.ident()[0]);
                    bool       arrayFound        = false;
                    bool       error             = false;
                    Identifier currentIdentifier = identifier;

                    context.GetRuleContexts <ParserRuleContext>().Skip(1).ToList().ForEach(r => {
                        if (error)
                        {
                            return;
                        }

                        if (arrayFound)
                        {
                            InsertError(r.Start, "No se puede acceder a arreglos o propiedades de un elemento de un arreglo porque solo son de tipos simples");
                            error = true;
                            return;
                        }
                        if (r is ExprASTContext)
                        {
                            arrayFound          = true;
                            ExprASTContext expr = r as ExprASTContext;

                            string type = Visit(expr) as string;

                            if (type == "int")
                            {
                                if (!(currentIdentifier is ArrayIdentifier))
                                {
                                    InsertError(r.Start, $"El identificador {currentIdentifier.Id} no es un arreglo");
                                    error = true;
                                    return;
                                }
                                else
                                {
                                    currentIdentifier = (currentIdentifier as ArrayIdentifier).Identifiers[0];
                                }
                            }
                            else
                            {
                                InsertError(expr.Start, "Solo se permiten números enteros cuando se accede a una posición del arreglo");
                                error = true;
                                return;
                            }
                        }
                        else if (r is IdentASTContext)
                        {
                            IdentASTContext ident = r as IdentASTContext;
                            if (currentIdentifier is InstanceIdentifier)
                            {
                                currentIdentifier = (currentIdentifier as InstanceIdentifier).Identifiers.Find(i => ident.GetText() == i.Id);
                                if (currentIdentifier == null)
                                {
                                    InsertError(ident.Start, $"El identificador {ident.IDENT().Symbol.Text} no existe en la instancia");
                                    error = true;
                                    return;
                                }
                            }
                            else
                            {
                                InsertError(ident.Start, $"El identificador {currentIdentifier.Id} no es una instancia de una clase");
                                error = true;
                                return;
                            }
                        }
                    });
                    if (!error)
                    {
                        return(currentIdentifier);
                    }
                }
                else
                {
                    InsertError(context.Start, "No se puede acceder a posiciones o propiedades de un identificador que no es una clase ni un arreglo");
                }
            }
            else
            {
                InsertError(context.ident()[0].Start, $"El identificador {context.ident()[0].GetText()} no ha sido declarado");
            }
            return(null);
        }
Exemple #7
0
 public object VisitIdentAST([NotNull] IdentASTContext context)
 {
     return(null);
 }