Example #1
0
        private void declaracion(TablaSimbolo tabla, ParseNode raiz, string ambito)
        {
            pila_ambito.Push(ambito);//nuevo
            string tipo_dato;

            tipo_dato = raiz.childNodes[0].ToString();
            Nodo resultado = null;

            if (raiz.childNodes.Count > 2)//de la forma <tipodato><id><asignacion>
            {
                //asignacion es de la forma <condicion> solo tiene un hijo
                resultado = calculo(raiz.childNodes[2].izq()); //<declaracion>-><asignacion>-><condicion>
                if ("<error>".Equals(resultado.Tipo))          //si hay un error semantico en el calculo
                {
                    resultado = null;                          //calculo ya se encarga de agregar el error
                }
            }
            //revisamos los ids para agregarlos
            ParseNode ids = raiz.childNodes[1];
            Simbolo   nuevo;

            foreach (ParseNode hijo in ids.childNodes)
            {
                nuevo = new Simbolo(tipo_dato, hijo.ToString(), ambito, hijo.Fila, hijo.Columna); //genero un nuevo simbolo
                addError(nuevo.asignar(resultado));                                               //si tuviese un error en la asignacion, lo agrega, si no hay no hace nada la funcion adderror
                if (!tabla.add(nuevo))                                                            //si no se logra agregar(por eso el !)
                {
                    addError(new ParseNode(nuevo.Fila, nuevo.Columna, "La variable:" + hijo.ToString() + " ya fue declarada", "<error>"));
                }
            }
        }
Example #2
0
        private void add(ParseNode raiz, string ambito, string tipo_dato, Nodo resultado)
        {
            Simbolo nuevo;

            foreach (ParseNode hijo in raiz.childNodes)
            {
                nuevo = new Simbolo(tipo_dato, hijo.ToString(), ambito, hijo.Fila, hijo.Columna); //genero un nuevo simbolo
                addError(nuevo.asignar(resultado));                                               //si tuviese un error en la asignacion, lo agrega, si no hay no hace nada la funcion adderror
                if (!tabla_global.add(nuevo))                                                     //si no se logra agregar(por eso el !)
                {
                    addError(new ParseNode(nuevo.Fila, nuevo.Columna, "La variable:" + hijo.ToString() + " ya fue declarada", "<error>"));
                }
            }
        }
Example #3
0
        private Nodo para(ParseNode raiz, string ambito)
        {
            if (raiz.childNodes.Count < 7) //no tiene sentencia
            {
                pila_subambito.Pop();      //nuevo
                return(null);
            }
            Nodo retorno = null;
            //los hijos de for son de la forma: para Double id E <condicion> <op> <sentenciaw>, sentencia es opcional
            string  nombre  = raiz.childNodes[2].ToString();                                                              //el nombre de la variable para la condicion
            Simbolo i       = new Simbolo("Double", nombre, ambito, raiz.childNodes[2].Fila, raiz.childNodes[2].Columna); //genero un nuevo simbolo
            Nodo    valor_i = calculo(raiz.childNodes[3]);

            if ("<error>".Equals(valor_i.Tipo) || "String".Equals(valor_i.Tipo))
            {
                pila_subambito.Pop();         //nuevo
                return(null);                 //si hay error dejo de revisar el for
            }
            i.asignar(valor_i);               //no deberia haber problema con el type casting
            TablaSimbolo aux = tabla_local;   //se guarda la tabla actual

            tabla_local = new TablaSimbolo(); //pasamos a una tabla para if
            tabla_local.cambiarAmbito(aux);   //pasamos los valores de aux a local
            if (!tabla_local.add(i))          //si la variable de reconocimiento ya existe
            {
                pila_subambito.Pop();         //nuevo
                addError(new Nodo(i.Fila, i.Columna, "La variable:" + i.Identificador + " ya fue definida en este ambito", "<error>"));
                return(null);
            }
            Nodo resultado = calculo(raiz.childNodes[4]); //calculo la condicion

            if ("<error>".Equals(resultado.Tipo))         //verifico que la condicion si sea un booleano
            {
                pila_subambito.Pop();                     //nuevo
                return(null);                             //dejo de revisar
            }
            if (!"Bool".Equals(resultado.Tipo))
            {
                pila_subambito.Pop();//nuevo
                addError(new Nodo(raiz.Fila, raiz.Columna, "La condicion del mientras no retorna un booleano", "<error>"));
                return(null);
            }
            while (MyMath.toBool(resultado.ToString()))
            {
                retorno = ejecutar(raiz.childNodes[6]);
                if (retorno != null)
                {
                    if ("<DETENER>".Equals(retorno.Tipo))
                    {
                        break;//detengo el while
                    }
                    if ("<CONTINUAR>".Equals(retorno.Tipo))
                    {
                        retorno = null;//ya adentro se encarga de saltar el resto de sentencias asi que solo regreso retorno a ser null
                    }
                    if ("<RETORNO>".Equals(retorno.Tipo))
                    {
                        break;
                    }
                }
                if ("+".Equals(raiz.childNodes[5].izq().ToString()))   //++
                {
                    tabla_local.mas_menos(nombre, tabla_global, true); //funcion extra que hice para facilitar el ++/--
                }
                else//--
                {
                    tabla_local.mas_menos(nombre, tabla_global, false);
                }
                resultado = calculo(raiz.childNodes[4]); //recalculamos la condicion
            }
            tabla_local = aux;                           //recuperamos la tabla local
            if (retorno != null && "<DETENER>".Equals(retorno.Tipo))
            {
                retorno = null;
            }
            pila_subambito.Pop();//nuevo
            return(retorno);
        }