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); }
public object VisitIdentAST([NotNull] IdentASTContext context) { return(null); }