next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: Generación de Código: Máquina Sup: Asignación de Direcciones Ant: Asignación de Direcciones Err: Si hallas una errata ...


Práctica: Cálculo de las Direcciones

Modifique el cálculo de las direcciones para la gramática de Tutu extendida con sentencias compuestas que fué presentada en la sección 4.10.2.

  1. Resuelva el problema de calcular las direcciones de las variables declaradas en los bloques. La memoria ocupada por dichas variables se libera al terminar el bloque. Por tanto la variable $global_address disminuye al final de cada bloque.
  2. En el código de la subrutina Address::Assignment::str

      sub str {
        my $str = shift;
        my $len = length($str);
        my $offset = length($data);
        $data .= $str;
        return ($offset, $len);
      }
    

    no se comprueba si la cadena $str ya está en $data. Es natural que si ya está no la insertemos de nuevo. Introduzca esa mejora. Para ello use la función pos, la cual devuelve el desplazamiento en $data donde quedó la última búsqueda $data =~ m/regexp/g. El siguiente ejemplo con el depurador le muestra como trabaja. Escriba perldoc -f pos para obtener mas información sobre la función pos. Vea un ejemplo de uso:

    DB<1> $str = "world"
    #              012345678901234567890123456789012
    DB<2> $data = "hello worldjust another statement"
    DB<3> $res = $data =~ m{$str}g
    DB<4> x pos($data) # la siguiente busqueda comienza en la 11
    0  11
    DB<5> $s = "hello"
    DB<6> $res = $data =~ m{$s}g
    DB<7> x pos($data) # No hay "hello" despues de world en $data
    0  undef
    DB<8> $res = $data =~ m{$str}g # Repetimos ...
    DB<9> x pos($data)
    0  11
    DB<10> pos($data) = 0  # Podemos reiniciar pos!
    DB<11> $res = $data =~ m{$s}g
    DB<12> x pos($data) # Ahora si se encuentra "hello"
    0  5
    

  3. Empaquete las cadenas asumiendo que cada carácter ocupa un octeto o byte. Una posible solución al problema de alineamiento que se produce es rellenar con ceros los bytes que faltan hasta completar la última palabra ocupada por la cadena. Por ejemplo, si la longitud de palabra de la máquina objeto es de 4 bytes, la palabra procesador se cargaría asi:

       0    |    1    |    2      
    0 1 2 3 | 4 5 6 7 | 8 9 10  11
    p r o c | e s a d | o r \0  \0
    

    Existen dos posibles formas de hacer esta empaquetado. Por ejemplo, si tenemos las cadenas lucas y pedro las podemos introducir en la cadena $data asi:

       0    |     1      |    2      |    3
    0 1 2 3 | 4  5  6  7 | 8 9 10 11 | 12 13 14 15
    l u c a | s \0 \0 \0 | p e  d  r |  o \0 \0 \0
    

    o bien:

       0    |    1    |    2     
    0 1 2 3 | 4 5 6 7 | 8 9 10 11
    l u c a | s p e d | r o \0 \0
    

    La segunda forma aunque compacta más tiene la desventaja de hacer luego mas lento el código para el direccionamiento de las cadenas, ya que no empiezan en frontera de palabra. Utilice el primer modo.

    Observe que este empaquetado introduce un efecto en lo que se considera un éxito en la búsqueda de una cadena $str en $data. ¿Que ocurre si $str aparece en $data como subcadena de una cadena previamente empaquetada ocupando una posición que no es frontera de palabra?

    Cuando rellene con \0 la cadena use el operador x (letra equis) para multiplicar número por cadena:

    DB<1> $x = "hola"x4
    DB<2> p $x
    holaholaholahola
    

    esto le evitará escribir un bucle.

  4. Mantega atributos distintos en el nodo STR para el desplazamiento y longitud de $str en $data (en caracteres) y su dirección y tamaño final en memoria (en palabras).


next up previous contents index PLPL moodlepserratamodulosperlmonksperldocapuntes LHPgoogleetsiiullpcgull
Sig: Generación de Código: Máquina Sup: Asignación de Direcciones Ant: Asignación de Direcciones Err: Si hallas una errata ...
Casiano Rodríguez León
2013-03-05