public void Visit(ProgNode node)
        {
            if (!SemanticAlgorithm.CheckTopology(node.classes, errors))
            {
                return;
            }

            node.classes.ForEach(cclass => scope.AddType(cclass.type.Text, new TypeInfo(cclass.type.Text, scope.GetType(cclass.Inherit.Text), cclass)));

            int idMain = -1;

            for (int i = 0; i < node.classes.Count; ++i)
            {
                if (node.classes[i].type.Text == "Main")
                {
                    idMain = i;
                }
            }

            if (idMain == -1)
            {
                errors.Add(ErrorSemantic.NotFoundClassMain());
                return;
            }

            bool mainOK = false;

            foreach (var item in node.classes[idMain].features)
            {
                if (item is MethodNode)
                {
                    var method = item as MethodNode;
                    if (method.id.text == "main" && method.paramsFormal.Count == 0)
                    {
                        mainOK = true;
                    }
                }
            }

            if (!mainOK)
            {
                errors.Add(ErrorSemantic.NotFoundMethodmain(node.classes[idMain]));
            }

            foreach (var cclass in node.classes)
            {
                if (!scope.IsDefinedType(cclass.Inherit.Text, out TypeInfo type))
                {
                    errors.Add(ErrorSemantic.NotDeclaredType(cclass.Inherit));
                    return;
                }
                if (new List <string> {
                    "Bool", "Int", "String"
                }.Contains(type.Text))
                {
                    errors.Add(ErrorSemantic.NotInheritsOf(cclass, type));
                    return;
                }
                cclass.Accept(this);
            }
        }