TECNOLOGIA DE LA INFORMACION Y MULTIMEDIA 15 MAYO.pptx
Documentación Compilador Golang
1. TECNOLÓGICO NACIONAL DE MÉXICO
INSTITUTO TECNOLÓGICO DE VERACRUZ.
MATERIA:
Lenguajes Autómatas II
LENGUAJE Y HORARIO
LENGUAJE GO GRUPO 12:00-13:00 hrs
ALUMNOS:
Juárez Castillo Andrés
Marcial Parra Israel
Pérez Rendon Arturo
CATEDRÁTICO:
LIC. Martha Martínez Moreno
3. Índice
Introducción..........................................................................................................................................................................................1
Analizador Léxico ...............................................................................................................................................................................2
Introducción...................................................................................................................................................................................2
Etapa de análisis...........................................................................................................................................................................2
Tokens del lenguaje GO.............................................................................................................................................................2
Analizador Sintáctico ........................................................................................................................................................................7
Introducción...................................................................................................................................................................................7
Gramática del lenguaje GO.......................................................................................................................................................7
Resultado del análisis sintáctico ........................................................................................................................................12
Analizador semántico ....................................................................................................................................................................15
Introducción................................................................................................................................................................................15
Semántico del lenguaje GO....................................................................................................................................................15
Resultados del análisis semántico.....................................................................................................................................20
Error # 1........................................................................................................................................................................................20
Error # 2........................................................................................................................................................................................20
Error # 3........................................................................................................................................................................................21
Error # 4........................................................................................................................................................................................22
Error # 5........................................................................................................................................................................................23
Error # 6........................................................................................................................................................................................24
Error # 7........................................................................................................................................................................................24
Error # 8........................................................................................................................................................................................25
Error # 9........................................................................................................................................................................................26
Generación de Código Intermedio............................................................................................................................................28
Introducción................................................................................................................................................................................28
Declarando variables en GO, Ensamblador y Jasmin ................................................................................................28
GO.....................................................................................................................................................................................................28
Ensamblador...............................................................................................................................................................................29
Jasmin.............................................................................................................................................................................................30
Optimización de Código ................................................................................................................................................................30
Optimización en GO..................................................................................................................................................................31
Partes optimizadas...................................................................................................................................................................31
Diferencia de líneas..................................................................................................................................................................33
Prueba de códigos.....................................................................................................................................................................33
Comentario Extra......................................................................................................................................................................35
Generación de Código Objeto y Archivo Ejecutable..........................................................................................................36
Introducción................................................................................................................................................................................36
4. Código objeto y archivo ejecutable en GO......................................................................................................................36
Conclusiones ......................................................................................................................................................................................39
Bibliografía .........................................................................................................................................................................................43
Índice de ilustraciones
Ilustración 1 Variables con sintaxis correcta ......................................................................................................................13
Ilustración 2 Error sintáctico al no corresponder con la estructura gramatical .................................................14
Ilustración 3 Variable declarada dos veces..........................................................................................................................20
Ilustración 4 Error de variable declarada dos veces........................................................................................................20
Ilustración 5 Declaración de variable sin tipo ....................................................................................................................21
Ilustración 6 Error al cambiar el tipo a variable declarada ..........................................................................................21
Ilustración 7 Declaración de variables sin utilizar............................................................................................................22
Ilustración 8 Error de variables no utilizadas.....................................................................................................................22
Ilustración 9 Suma de variables de distinto tipo ...............................................................................................................23
Ilustración 10 Error de variables de distinto tipo.............................................................................................................23
Ilustración 11 Intercambio de valores entre variables...................................................................................................23
Ilustración 12 Error de tipo de variable ya asignado ......................................................................................................23
Ilustración 13 Variables inexistentes o no declaradas....................................................................................................24
Ilustración 14 Error de variables no declaradas................................................................................................................24
Ilustración 15 Declaración de arreglos ..................................................................................................................................25
Ilustración 16 Error al acceder a una posición no declarada.......................................................................................25
Ilustración 17 Declaración de ciclo if......................................................................................................................................25
Ilustración 18 Error de compatibilidad de variables.......................................................................................................25
Ilustración 19 Declaración de ciclo for...................................................................................................................................26
Ilustración 20 Error de tipos diferentes................................................................................................................................26
Ilustración 21 Ejemplo con booleanos ...................................................................................................................................27
Ilustración 22 Resultados de booleanos................................................................................................................................27
Ilustración 23 Función potencia usando un ciclo..............................................................................................................32
Ilustración 24 Utilizando una función que realiza la potencia ....................................................................................32
Ilustración 25 Sin optimizar. 268 líneas de código...........................................................................................................33
Ilustración 26 Optimizado. 199 líneas de código...............................................................................................................33
Ilustración 27 Menú calculadora sin optimizar..................................................................................................................33
Ilustración 28 Función potencia y tiempo de ejecución.................................................................................................34
Ilustración 29 Menú calculadora optimizada......................................................................................................................34
Ilustración 30 Función potencia y tiempo de ejecución.................................................................................................34
Ilustración 31 Tamaño sin optimizar......................................................................................................................................35
Ilustración 32 Tamaño con optimización..............................................................................................................................35
Ilustración 33 Ejecutable de calculadora sin optimizar con tiempo de ejecución..............................................37
Ilustración 34 Tamaño de ejecutable de calculadora sin optimizar..........................................................................37
Ilustración 35 Ejecutable de calculadora optimizada con tiempo de ejecución ..................................................38
Ilustración 36 Tamaño de ejecutable de calculadora optimizada..............................................................................38
Ilustración 37 Comando para generar archivo ejecutable ............................................................................................38
5. 1
Introducción
Go es un lenguaje de programación concurrente y compilado inspirado en
la sintaxis de C. Ha sido desarrollado por Google y sus diseñadores
iniciales son Robert Griesemer, Rob Pike y Ken Thompson. Actualmente
está disponible en formato binario para los sistemas
operativos Windows, GNU/Linux, FreeBSD y Mac OS X, pudiendo también
ser instalado en estos y en otros sistemas con el código fuente. Go es un
lenguaje de programación compilado, concurrente, imperativo,
estructurado, orientado a objetos —de una manera bastante especial— y
con recolector de basura que de momento está soportado en diferentes
tipos de sistemas UNIX, incluidos Linux, FreeBSD y Mac OS X. También está
disponible en Plan 9 puesto que parte del compilador está basado en un
trabajo previo sobre el sistema operativo Inferno. Las arquitecturas
soportadas son i386, amd64 y ARM.
6. 2
Analizador Léxico
Introducción
Un analizador léxico o analizador lexicográfico (en inglés scanner) es la
primera fase de un compilador consistente en un programa que recibe
como entrada el código fuente de otro programa (secuencia de caracteres)
y produce una salida compuesta de tokens (componentes léxicos) o
símbolos. Estos tokens sirven para una posterior etapa del proceso de
traducción, siendo la entrada para el analizador sintáctico (en
inglés parser).
La especificación de un lenguaje de programación a menudo incluye un
conjunto de reglas que definen el léxico. Estas reglas consisten
comúnmente en expresiones regulares que indican el conjunto de posibles
secuencias de caracteres que definen un token o lexema.
En algunos lenguajes de programación es necesario establecer patrones
para caracteres especiales (como el espacio en blanco) que la gramática
pueda reconocer sin que constituya un token en sí.
Etapa de análisis
Esta etapa está basada usualmente en una máquina de estados finitos. Esta
máquina contiene la información de las posibles secuencias de caracteres
que puede conformar cualquier token que sea parte del lenguaje (las
instancias individuales de estas secuencias de caracteres son
denominados lexemas). Por ejemplo, un token de naturaleza entero puede
contener cualquier secuencia de caracteres numéricos.
Tokens del lenguaje GO
TOKEN : //PALABRAS RESERVADAS
{
<PR_Pkg: "package">
{System.out.println("PR_Pkg," + image);}
|
<PR_Mn: "main">
{System.out.println("PR_Mn," + image);}
|
11. 7
Analizador Sintáctico
Introducción
Un analizador sintáctico (o parser) es un programa informático que
analiza una cadena de símbolos de acuerdo con las reglas de una gramática
formal. El término proviene del latín pars, que significa parte (del
discurso). Usualmente hace parte de un compilador, en cuyo caso,
transforma una entrada en un árbol de sintáctico de derivación.
El análisis sintáctico convierte el texto de entrada en otras estructuras
(comúnmente árboles), que son más útiles para el posterior análisis y
capturan la jerarquía implícita de la entrada. Un analizador léxico
crea tokens de una secuencia de caracteres de entrada y son
estos tokens los que son procesados por el analizador sintáctico para
construir la estructura de datos, por ejemplo, un árbol de análisis o árboles
de sintaxis abstracta.
El análisis sintáctico también es un estado inicial del análisis de frases de
lenguaje natural. Es usado para generar diagramas de lenguajes que usan
flexión gramatical, como los idiomas romances o el latín. Los lenguajes
habitualmente reconocidos por los analizadores sintácticos son
los lenguajes libres de contexto. Cabe notar que existe una justificación
formal que establece que los lenguajes libres de contexto son aquellos
reconocibles por un autómata de pila, de modo que todo analizador
sintáctico que reconozca un lenguaje libre de contexto es equivalente en
capacidad computacional a un autómata de pila.
Los analizadores sintácticos fueron extensivamente estudiados durante
los años 1970, detectándose numerosos patrones de funcionamiento en
ellos, cosa que permitió la creación de programas generadores de
analizadores sintácticos a partir de una especificación de la sintaxis del
lenguaje en forma Backus-Naur por ejemplo, tales como yacc, GNU
bison y javaCC.
Gramática del lenguaje GO
Gramática para iniciar un programa
void prog():
{semantico.limpiarTabla();}
{
15. 11
//System.out.println(e.toString());
do {
t = getNextToken();
}while (t.kind !=D_LlaveD && t!=null && t.kind != EOF);
}
}
Gramática del Ciclo for
void CicloFOR():
{}
{
try{
<PR_For><Variable><OC_Asignar><Number><OC_PuntCom>(((<Number>(<OC_Mayor>|<OC_MayorI>
|<OC_Menor>|<OC_MenorI>)<Number>)<OC_PuntCom><OC_Increm><Variable>)|((<Constante>(<OC_
Mayor>|<OC_MayorI>|<OC_Menor>|<OC_MenorI>)<Constante>)<OC_PuntCom><OC_Increm><Constan
te>)|((<Variable>(<OC_Mayor>|<OC_MayorI>|<OC_Menor>|<OC_MenorI>)<Variable>)<OC_PuntCom>
<OC_Increm><Variable>))<D_LlaveI>(sentencia())+<D_LlaveD> }
catch (ParseException e) {
Token t;
JOptionPane.showMessageDialog(null,e.toString(),"ERROR SINTACTICO",
JOptionPane.ERROR_MESSAGE);
//System.out.println(e.toString());
do {
t = getNextToken();
}while (t.kind != D_LlaveD && t!=null && t.kind != EOF);
}
}
Gramática para asignar punto y coma
void PuntoComa():
{}
{
try
{
<OC_PuntCom>
} catch (ParseException e) {
Token t;
JOptionPane.showMessageDialog(null,e.toString(),"ERROR SINTACTICO",
JOptionPane.ERROR_MESSAGE);
//System.out.println(e.toString());
do {
t = getNextToken();
}while (t.kind != OC_PuntCom && t!=null && t.kind != EOF);
}
}
16. 12
Resultado del análisis sintáctico
La parte sintáctica de un compilador se encarga de validar la relación
jerárquica que se tienen al formar una oración, o en este caso una línea de
código.
El código utilizado es parte del compilador que se desarrolló en la materia
Lenguajes y Autómatas 2
Ejemplo:
Para entender esto mejor veamos un pedazo de código
Esta función nos permite la creación de variables, utilizando un clásico try-
catch, como ya sabemos la función try nos permite manejar una excepción
y si esta se cumple ejecuta el catch.
En este caso mediante una E.R. indicamos el acomodo que debe llevarse a
cabo para generar una variable, y si este no se cumple, en el catch
indicamos que nos rebote una pantalla de error, veámoslo en ejecución.
La manera correcta de declarar una variable en nuestro lenguaje es la
siguiente:
[palabra reservada VAR] [Nombre de la variable] [Tipo de variable] [punto
y coma]
17. 13
Var variable1 int;
Ilustración 1 Variables con sintaxis correcta
Ahora bien, en este caso las variables hablando sintácticamente, están bien
declaradas en la caja de texto del lado izquierdo, lo que imprime son los
tokens junto a su nombre de variable declarado en el analizador. Entonces
¿Dónde entraría los errores sintácticos? Solo hace falta cambiar de lugar o
no escribir correctamente una línea de código
18. 14
Ilustración 2 Error sintáctico al no corresponder con la estructura gramatical
Como en este caso al quitar un punto y coma. El mensaje de error nos
indica la línea, columna y el valor que esperaba.
19. 15
Analizador semántico
Introducción
La semántica corresponde al significado asociado a las estructuras
formales (sintaxis) del lenguaje.
La fase de análisis semántico de un procesador de lenguaje es aquélla que
computa la información adicional necesaria para el procesamiento de un
lenguaje, una vez que la estructura sintáctica de un programa haya sido
obtenida. Es por tanto la fase posterior a la de análisis sintáctico y la última
dentro del proceso de síntesis de un lenguaje de programación.
El objetivo principal del analizador semántico de un procesador de
lenguaje es asegurarse de que el programa analizado satisfaga las reglas
requeridas por la especificación del lenguaje, para garantizar su correcta
ejecución. El tipo y dimensión de análisis semántico requerido varía
enormemente de un lenguaje a otro.
Semántico del lenguaje GO
En la realización del lenguaje se optó por colocar la funcionalidad del
analizador semántico en la gramática del lenguaje
void prog():
{semantico.limpiarTabla();}
{
try{ <PR_Pkg><PR_Mn>(imp())+
<PR_Funcion><PR_Mn><D_ParentI><D_ParentD><D_LlaveI>(sentencia())+<D_LlaveD>(funcion())*}
catch (ParseException e) {
Token t;
JOptionPane.showMessageDialog(null,e.toString(),"ERROR SINTACTICO",
JOptionPane.ERROR_MESSAGE);
//System.out.println(e.toString());
do {
t = getNextToken();
}while (t.kind != OC_PuntCom && t!=null && t.kind != EOF);
}
}
void imp():
{}
{
try{ <PR_imp><OC_Comilla><PR_fmt><OC_Comilla>PuntoComa() }
catch (ParseException e) {
23. 19
} catch (ParseException e) {
Token t;
JOptionPane.showMessageDialog(null,e.toString(),"ERROR SINTACTICO",
JOptionPane.ERROR_MESSAGE);
//System.out.println(e.toString());
do {
t = getNextToken();
}while (t.kind != OC_PuntCom && t!=null && t.kind != EOF);
}
}
Se realizó una clase especial que guarda los tokens para ser comparados a
la hora de realizar el análisis
public static void guardarvariable(Token tk){
if(tabla.get(tk.image)!=null){
if(tabla.get(tk.image)!=null){
aa.setText(aa.getText() + "Variabe "+tk.image+" duplicada en la linea:"+tk.beginLine+ "n");
}
else{
aa.setText(aa.getText()+"");
}
}
else{
tabla.put(tk.image, tk.kind);
// aa.setText(aa.getText()+null);
//aa.setText(aa.getText()+"La variaable "+tk.image+" ha sido declarada");
}
do{
aa.setText(aa.getText());
}while(tabla.get(tk.image)==null);
}//LLAVE DEL TOKEN
public static void variableInex(Token tk){
try{ int x = tabla.get(tk.image);
}catch(Exception e){
System.err.print("nError, la variable "+ tk.image +" no existe, Linea:"+tk.beginLine);
aa.setText(aa.getText() + "Error, la variable "+ tk.image +" no existe, Linea:"+tk.beginLine+ "n");
// JOptionPane.showMessageDialog(null,"Error, la variable "+ tk.image +" no existe,
Linea:"+tk.beginLine,"ERROR SEMANTICO", JOptionPane.ERROR_MESSAGE);
}
}
24. 20
Resultados del análisis semántico
Error # 1
Como en cualquier otro lenguaje la duplicidad de las variables siempre
será un error semántico, a pesar de que Go si diferencia las letras
mayúsculas de las minúsculas, escribirlas exactamente igual (como se
muestra en la sig. imagen):
Ilustración 3 Variable declarada dos veces
Nos dirá un error como el siguiente, donde nos indica que la variable ya
había sido declarada anteriormente
Ilustración 4 Error de variable declarada dos veces
Error # 2
Para este segundo error ocupare la declaración de las variables. La forma
correcta de declarar una variable es la siguiente: var AX7 string (escribir
la palabra “var” seguido del nombre de la variable y por último el tipo de
la variable, pero, aunque Go es un lenguaje de tipado estático nos permite
el duck typing, este nos permite declarar variables sin el tipo ya que el
compilador se encarga que dependiendo el valor que ingresemos decidirá
el tipo de variable que es. Ejemplo:
25. 21
Ilustración 5 Declaración de variable sin tipo
Como se observa en la imagen está la forma clásica de declarar la variable
y la nueva forma, pero por obvias razones para cualquier persona podría
decir “ como esta variable no tiene un tipo en específico podría estar
cambiando el tipo de variable que es “ pero no es así, en el primer valor
que asignes a esta variable, el compilador asignara que tipo es, por lo cual
si después decides intentara cambiar este valor como por ejemplo en la
imagen vemos que la variable novia inicia teniendo una cadena de
caracteres para después asignarle un valor entero, nos arrojara un error
Ilustración 6 Error al cambiar el tipo a variable declarada
Diciéndonos que no podemos usar valor entero ya que anteriormente esa
variable había sido asignada como tipo string
Error # 3
En cualquier otro lenguaje de programación el no utilizar una variable
únicamente nos genera un pequeño warning (Advertencia) indicándonos
que esta no está siendo utilizada, pero en Go no es este caso, si se declaran
variables (Ejemplo):
26. 22
Ilustración 7 Declaración de variables sin utilizar
Y estas no son utilizadas de ninguna manera, el compilador nos mandara
el siguiente error:
Ilustración 8 Error de variables no utilizadas
Que las variables han sido declaradas, pero no están siendo utilizadas. Esto
es muy bueno ya que nos permite no despreciar espacios en memoria.
Error # 4
Las operaciones aritméticas, en este caso Go realmente es especial ya que,
a comparación de cualquier otro lenguaje, solo nos permite las
operaciones si las variables son del mismo tipo, por consiguiente, si
nosotros intentamos como sumar 2 tipos diferentes. Ejemplo:
27. 23
Ilustración 9 Suma de variables de distinto tipo
Que intentemos sumar un tipo entero con uno flotante, nos dirá el
siguiente error:
Ilustración 10 Error de variables de distinto tipo
Que los valores enteros y flotantes no son compatibles
Error # 5
Go nos permite intercambiar los valores entre diferentes variables, pero
como en el anterior error, únicamente es posible esto si los tipos son los
mismos.
Ilustración 11 Intercambio de valores entre variables
Si intentamos intercambiar valores enteros y de cadenas de caracteres
entre las variables
Ilustración 12 Error de tipo de variable ya asignado
Nos dirá que no es posible darle ese valor por el tipo que ya se les había
asignado
28. 24
Error # 6
Utilizar variables inexistentes o no declaradas:
Ilustración 13 Variables inexistentes o no declaradas
En el 1er caso (donde esta subrayado de rojo) se está mandando a llamar
una variable no declarada, y en el 2do (amarillo) se está mandando a
llamar una variable, pero no se encuentra dentro de el mismo método
Ilustración 14 Error de variables no declaradas
En ambos casos las marca error como indefinidas una por no existir y la
otra que se encuentra en un método distinto
Error # 7
Los arreglos cuando se declaras es algo fundamentar definir de cuantas
posiciones será este, como se muestra en la siguiente imagen:
29. 25
Ilustración 15 Declaración de arreglos
En este caso se ha declarado un arreglo de 3 posiciones, pero que sucederá
si intentamos acceder a la 4ta posición.
Ilustración 16 Error al acceder a una posición no declarada
Nos dirá un error donde marca que este arreglo solo está hecho para 3
posiciones.
Error # 8
El funcionamiento de la sentencia if es similar a la de cualquier otro
lenguaje de programación, sin embargo, como ya es costumbre
únicamente puede comparar variables del mismo tipo.
Ilustración 17 Declaración de ciclo if
Por consiguiente, si intentamos en un ciclo if comparar 2 tipos diferentes.
Ilustración 18 Error de compatibilidad de variables
30. 26
Nos dirá el mismo error que las variables no son compatibles
Error # 9
Si de algo carece el lenguaje Go es de las estructuras de control, ya que solo
posee las sentencias IF y FOR.
En Go hay 3 formas de hacer un for, pero ocuparemos la forma clásica, que
contiene la inicialización de una variable, una condición y su incremento
Ilustración 19 Declaración de ciclo for
Como de costumbre se va a comparar en la condición valores de diferentes
tipos.
Ilustración 20 Error de tipos diferentes
Dándonos como resultado el mismo error de los tipos no compatibles.
Funcionamiento del tipo Booleano # 10
A diferencia de otros lenguajes, Go no consideran como 0 y 1 los valores
para true y false.
A continuación, un pequeño código sobre el tipo bool
31. 27
Ilustración 21 Ejemplo con booleanos
Primeramente, asignamos una comparación sencilla a la variable
booleana, y después asignamos una operación lógica, en este caso and
Ilustración 22 Resultados de booleanos
El primer resultado es false ya que la comparación nos dice que 3 es mayor
que 5 lo cual es falso.
En la 2da el resultado es true ya que la tabla de verdad del operador lógico
and nos dice que sí y solo si ambas condiciones se cumplen esta será
verdadera, en este caso 5 es menor que 6 y 3 mayor que 1
32. 28
Generación de Código Intermedio
Introducción
Después de los análisis sintáctico y semántico, algunos compiladores
generan una representación intermedia explícita del programa fuente.
Se puede considerar esta representación intermedia como un programa
para una máquina abstracta. Esta representación intermedia debe tener
dos propiedades importantes; debe ser fácil de producir y fácil de traducir
al programa objeto.
La representación intermedia puede tener diversas formas.
Declarando variables en GO, Ensamblador y Jasmin
GO
package main
import "fmt"
/*###############Declaraciones###############
*/
fmt.Println("Sintaxis: var nombre+de+la+variable tipo+de+variable")
func main() {
var a int = 5
//var a float64 = 2.00
var b int = 6
var A float64 = 2.00
var c string ="Karla Diaz<3"
fmt.Println(a,b,c)
fmt.Println(A)
}
Finalidad del código: Declarar variables y mandarlas a imprimir
33. 29
Ensamblador
Las variables en ensamblador no se manejan desde el punto de vista en
“tipos”. Ya que no hay char, string , int, etc. como en otros lenguajes.
Se clasifican por la longitud en bytes o el rango de valores que manejen
Sintaxis para definir una variable es:
.data
Nomb+variable directiva+de+tamaño [Longitud] [inicializacion]
DIRECTIVAS DE TAMAÑO
DB = Definir un byte = 1 BYTE
DW = Una palabra = 2 BYTES
DD= Doble palabra =4 BYTES
DF= Palabra larga= 6 BYTES
DQ= Palabra cuádruple = 8BYTES
DT = Diez bytes =10 BYTES
EQU = Es una palabra reservada
CODIGO EJEMPLO:
.MODEL small
.STACK 256
.DATA
; nombre tipo inicialización
Etiq1 DB 0083h
Etiq2 DB 0002h
Etiq3 DW 0FFFFh
Etiq4 DW 1234h
Etiq5 DD 12345678h
.CODE
Main PROC
MOV AX,Etiq1 ; dividendo
MOV BL,Etiq2 ; divisor
DIV BL ; AL = 41h, AH = 01h
Main ENDP
END main
Finalidad del código: Declarar variables y hacer una división
34. 30
Jasmin
Todos los movimientos que hace jasmin es mediante la pila. Y es por eso
que para asignar una variable es necesario tener datos en ella.
Para meter datos en la pila la sintaxis es la siguiente:
Utilizamos la instrucción LCD
lcd 34.56
lcd 23
lcd vendría siendo el push del lenguaje ensamblador
Para asignar estos datos a una variable lo haremos con la instrucción store
[tipo de variable]storeˍ[Numero de variable]
CODIGO EJEMPLO:
.class public NoJad.j
.super java/lang/Object
;
; standard initializer
.method public <init>()V
aload_0
invokenonvirtual java/lang/Object/<init>()V
return
.end method
.method public static main([Ljava/lang/String;)V
.limit stack 2
.limit locals 2
lcd 34.56 ; primer valor en la pila
lcd 23 ; ultimo valor
istoreˍ0 ; saca el ultimo valor(en este caso 23) y lo asigna a la variable 0
fstore ˍ1; saca el ultimo valor (34.56) y la pila se queda vacía
.end method
Finalidad del código: Añadir valores a la pila y declarar variables
Optimización de Código
35. 31
La optimización de código es el conjunto de fases de un compilador que
transforman un fragmento de código en otro fragmento con
un comportamiento equivalente y que se ejecuta de forma más eficiente,
es decir, usando menos recursos de cálculo como memoria o tiempo de
ejecución.
Optimización en GO
A continuación, se dará una breve explicación comparando dos códigos de
hechos en el lenguaje GO. Uno de estos estará desmejorado y el otro
optimizado. Ambos códigos que simulan una calculadora con las
operaciones más básicas.
Partes optimizadas
Antes que nada, es muy importante mencionar que la calculadora está
hecha en consola, ya que no hay mucha información sobre GO, así mismo
el número de líneas de código son realmente mínimas
Para optimizar el código es necesario eliminar variables innecesarias (en
GO no entra al caso ya que el lenguaje por si mismo no te deja compilar el
código si declaras variables y no las utilizas, algo que se agradece),
métodos, pedazos de código si sentido alguno etc.
Un ejemplo de la optimización vendría siendo como la siguiente:
36. 32
Ilustración 23 Función potencia usando un ciclo
En la función de la potencia de la calculadora sin optimizar desde el punto
que se declara variables hasta que se manda a imprimir (212-227) toma
15 líneas de código, en la cuales hay 4 variables y un ciclo for, el cual sirve
para calcular las potencias manual mente
Mientras que en la calculadora optimizada:
Ilustración 24 Utilizando una función que realiza la potencia
Toma 9 líneas de código (160-169) única mente hay 2 variables y no se
utiliza algún método manual para calcular las potencias, se utiliza una
función de la librería math perteneciente a GO
37. 33
Diferencia de líneas
Código sin optimizar:
Ilustración 25 Sin optimizar. 268 líneas de código
Código optimizado:
Ilustración 26 Optimizado. 199 líneas de código
Prueba de códigos
La forma en la que funciona las calculadoras es la siguiente, se tiene un
menú de entrada con 6 opciones, sumar, restar, multiplicar, dividir,
potencia y raíz cuadrada.
Deberemos digitar el número correspondiente a la operación deseada e
insertar los datos.
Calculadora sin optimizar
Para correr un código de go escribiremos el comando “go run
nombreDelArchivo.go”
Ilustración 27 Menú calculadora sin optimizar
Pondremos la opción 5 que es la potencia y metemos los valores para que
haga la operación
38. 34
Ilustración 28 Función potencia y tiempo de ejecución
Nos da el resultado de la operación, el tiempo que tardamos dentro del
programa y el tiempo de ejecución que es lo que nos importa, en este caso
tardo .65 ns
Calculadora optimizada
Haremos exactamente lo mismo con la calculadora optimizada
Ilustración 29 Menú calculadora optimizada
Introducimos los mismos datos
Ilustración 30 Función potencia y tiempo de ejecución
39. 35
Y como era de esperarse realmente hay un cambio, mínimo, pero lo hay
El tiempo de ejecución es de .61 ns contra los .65 de la calculadora
desmejorada
Tamaño de los archivos
Calculadora sin optimizar:
Ilustración 31 Tamaño sin optimizar
Calculadora optimizada:
Ilustración 32 Tamaño con optimización
El tamaño de los archivos es apenas notable debido a que el número de
líneas de código son mínimas.
Comentario Extra
Al momento de realizar la generación del código objeto el compilador
puede generar el archivo ejecutable sin necesidad de herramientas
especiales, eso se abarcará en la siguiente fase
40. 36
Generación de Código Objeto y Archivo Ejecutable
Introducción
La fase final de un compilador es la generación de código objeto, que por
lo general consiste en código de máquina relocalizable o código
ensamblador. Las posiciones de memoria se seleccionan para cada una de
las variables usadas por el programa. Después, cada una de las
instrucciones intermedias se traduce a una secuencia de instrucciones de
máquina que ejecuta la misma tarea. Un aspecto decisivo es la asignación
de variables a registros.
El generador de código objeto puede considerarse como la penúltima fase
de un compilador, la cual se encarga de tomar como entrada el código
intermedio generado por el front-end, y producir código objeto de la
arquitectura target para luego entrar en la fase de optimización de código.
Toma como entrada de representación intermedia el programa fuente y
produce como salida un programa objeto equivalente.
Código objeto y archivo ejecutable en GO
Algo muy ventajoso de GO es que puede crear archivos ejecutables, para
así portarlos a otras computadoras y poder ejecutarlos sin necesidad de
tener los archivos de GO.
En la fase de optimización de código se pudo observar la generación de
código objeto y su optimización, y en esta fase mencionaremos la
generación del archivo ejecutable y como se refleja la optimización en el
mismo.
Calculadora sin optimizar
41. 37
Ilustración 33 Ejecutable de calculadora sin optimizar con tiempo de ejecución
Tamaño:
Ilustración 34 Tamaño de ejecutable de calculadora sin optimizar
Calculadora optimizada
42. 38
Ilustración 35 Ejecutable de calculadora optimizada con tiempo de ejecución
Tamaño:
Ilustración 36 Tamaño de ejecutable de calculadora optimizada
Todo esto es generado con el comando “go build NombreDelArchivo.go”
Ilustración 37 Comando para generar archivo ejecutable
43. 39
Conclusiones
GO es un lenguaje de programación muy ligero y el hecho que sea open
source solo beneficiará a aquellos que apenas empiecen a conocer el
lenguaje, a futuro se espera que pueda llegar al nivel de C, Java o Python,
ya que es un lenguaje que posee características de esos 3 lenguajes.
Es un nuevo lenguaje de programación para sistemas lanzado por la
todopoderosa Google en noviembre del 2009. Aunque empezó a ser
desarrollado en septiembre del 2007 por Robert Griesemer, Rob Pike y
Ken Thompson.
Go es un lenguaje de programación compilado, concurrente, imperativo,
estructurado, no orientado a objetos —de una manera bastante especial—
y con recolector de basura que de momento está soportado en diferentes
tipos de sistemas UNIX, incluidos Linux, FreeBSD y Mac OS X. También está
disponible en Plan 9 puesto que parte del compilador está basado en un
trabajo previo sobre el sistema operativo Inferno. Las arquitecturas
soportadas son i386, amd64 y ARM. Existe un port no oficial a Microsoft
Windows, pero es bastante inestable. Actualmente se está trabajando para
llevarlo al sistema operativo de Microsoft.
Desde que Go fue anunciado, se generó un inmenso hype a su alrededor.
No faltaron los que se apresuraron a bautizarlo como el próximo C —ha
habido muchos próximos C que se quedaron en promesas— la diferencia
principal al probar Go en serio es que te deja una sensación muy placentera
que indica que realmente esta vez si podría haber algo de cierto detrás de
esa afirmación.
Después de programar con él algo más complejo que un “Hello World!“
deja una agradable sensación y rápidamente se detectan los siguientes
elementos en el lenguaje que revelan que detrás de toda la espantajería de
fanboyismo y hype hay sustancia:
Go usa una sintaxis parecida a C por lo que los programadores que hayan
usado dicho lenguaje se sienten muy cómodos con él
Go usa tipado estático (estatically typed) y es tan eficiente como C
44. 40
Go tiene muchas de las características y facilidad de lenguajes dinámicos
como Python
Aún siendo un lenguaje diseñado para la programación de sistemas,
provee de un recolector de basura, reflexión y otras capacidades de alto
nivel que lo convierten en un lenguaje muy potente
Go no está orientado a objetos porque no existe jerarquía de tipos pero
implementa interfaces
Características
Go, al igual que C y C++, es un lenguaje compilado, obviamente, comparte
características con otros lenguajes compilados, pero lo cierto es que tiene
algunas características únicas, veamos algunas
Concurrente
Es un lenguaje concurrente que soporta canales de comunicación basados
en el lenguaje CSP de Sir Charles Antony Richard Hoare —del que ya hablé
en mi primer artículo en Genbeta Dev pues es el creador del algoritmo de
ordenación QuickSort y ganador del Turing en 1980—. La concurrencia en
Go es diferente a los criterios de programación basados en bloqueos como
pthreads.
Recolector de basura
Como la mayoría de los lenguajes modernos, Go implementa un recolector
de basura. El recolector de basura de Go está siendo Re implementado para
elevar al máximo la eficiencia y reducir la latencia todo lo posible.
Simplicidad
Los lenguajes más utilizados como C++, Java o C# son más pesados y
voluminosos. La sencillez es la característica principal de Go, su sintaxis es
clara y concisa. Mientras que C es tristemente célebre por la complejidad
de la sintaxis de sus declaraciones, Go utiliza inferencia implícita de tipos
pudiéndose de esta manera evitar la declaración explícita de variables. La
declaración de variables es simple y conveniente, y difiere de la de C.
Duck Typing (Tipificación dinámica)
45. 41
Go admite la tipificación dinámica de datos también conocida como duck
Typing presente en multitud de lenguajes dinámicos como por ejemplo
JavaScript, Ruby o Python. Un struct puede implementar una interfaz de
forma automática, lo cual es una característica potente y novedosa.
Goroutines
No son ni threads, ni co-rutinas ni procesos. La comunicación entre
goroutines se realiza a través de una característica del lenguaje llamada
canales —basada en CSP—, que es mucho más seguro y fácil de usar que
los sistemas predominantes basados en bloqueos de threads o
características modernas de Java
Excepciones
Go no tiene excepciones. Los creadores del lenguaje dan varios motivos
para que esto sea así. Uno de ellos es que añadir una capa de excepciones
añade una complejidad innecesaria al lenguaje y al entorno de ejecución.
Por definición deberían de ser excepcionales, pero al final se acaban
usando como controladores del flujo de la aplicación y dejan de tener nada
de excepcional. Según los creadores, las excepciones tienen que ser
realmente excepcionales y el uso que se le da mayoritariamente no justifica
su existencia.
Innovación
Durante muchos años, los desarrolladores hemos tenido que elegir entre
lenguajes de programación de tipado estático compilados, por regla
general, bastante complejos pero que proveen grandes características
relacionadas con la optimización y el rendimiento y lenguajes de tipado
dinámico interpretados con características de mucho más alto nivel que
hacían su aprendizaje, uso y sintaxis más sencilla y por tanto divertido
programar en ellos, eso si, sacrificando rendimiento y control.
Go mezcla lo mejor de ambos mundos y nos aporta una sintaxis sencilla,
clara y divertida junto a la potencia que nos ofrece un lenguaje
fuertemente tipado y compilado incorporando además características de
alto nivel que facilitan el uso del lenguaje por los desarrolladores.
Diferencias principales con C
46. 42
Aunque su sintaxis es similar, Go difiere mucho de C, veamos algunos
ejemplos
Declaraciones al revés
En Go las declaraciones se realizan al revés desde la perspectiva de C (o
C++ o Java). La idea principal en C es que se declara una variable como una
expresión que denota su tipo. Según los creadores, aunque la idea detrás
de la declaración de tipos en C es buena, los tipos y las expresiones
gramaticales no se mezclan demasiado bien y el resultado puede ser
confuso. Go sin embargo, separa la expresión y la sintaxis de tipo lo cual
simplifica las cosas (el prefijo * para los punteros es la excepción que
confirma la regla). Una declaración típica en C sería:
int* i, j;
47. 43
Bibliografía
chrisdotgo. (2015). GitHub - chrisdotgo/golang-go-ejemplos: Mini proyectos en golang (GO). Recuperado
el 2017, de https://github.com/chrisdotgo/golang-go-ejemplos
Google. (2004). The Go Programming Language. Recuperado el 2017, de https://golang.org/
Gyga8k. (2016). Curso-Go-de-0-a-100/main.go at master Gyga8k/Curso-Go-de-0-a-100 GitHub.
Recuperado el 2017, de https://github.com/Gyga8K/Curso-Go-de-0-a-
100/blob/master/16_Ejercicio_1/main.go
Hernández Ramirez, J. I., Nava Cano, A., & Vázquez Gonzáles, R. (2010). Programación de Sistemas:
UNIDAD V.- ANALISIS SEMANTICO. Recuperado el 2017, de http://programacion-de-
sistemas.blogspot.com/2010/04/unidad-v-analisis-semantico.html
mmcgrana. (2012). Go con ejemplos. Recuperado el 2017, de http://www.goconejemplos.com/
Pérez Pérez, I., & Monroy Cedillo, J. J. (s.f.). Autómatas y Compiladores: Apuntes Digitales. Universidad
Autónoma del Estado de Hidalgo. Obtenido de
http://cidecame.uaeh.edu.mx/lcc/mapa/PROYECTO/libro32/autocontenido/autocon/135_ge
nerador_de_cdigo_intermedio.html
Pérez Pérez, I., & Monroy Cedillo, J. J. (s.f.). Autómatas y Compiladores: Apuntes Digitales. Universidad
Autónoma del Estado de Hidalgo. Obtenido de
http://cidecame.uaeh.edu.mx/lcc/mapa/PROYECTO/libro32/autocontenido/autocon/137_ge
nerador_de__cdigo_objeto.html
robert. (2016). Optimización de código: un código más eficiente | Informática ++. Recuperado el 2017, de
http://informatica.blogs.uoc.edu/2016/05/02/optimizacion-de-codigo-un-codigo-mas-
eficiente/
V. Aho, A., S. Lam, M., Sethi, R., & D. Ullman, J. (1998). Compiladores: Principios, técnicas y herramientas
(2da ed.). Pearson.