Hola a todos, bueno, les cuento, como parte de un trabajo en la universidad, tuve que crear un "compilador", o por lo menos avanzarlo, sin utilizar flex, lex, bison, yacc y todo eso, desde 0 totalmente. Pues bueno, quería compartirles el código.
El compilador no tiene mucho, pero algo es algo
Tiene su analizador léxico, analizador sintáctico, unas pequeñas comprobaciones de tipos de datos y demás..., el compilador crea correctamente su propio árbol sintáctico para el código fuente dado, que ya es un avance, y para ver si funcionaba la lectura del árbol sintáctico, hice un poco de generación de código intermedio para las expresiones aritméticas básicas, genera código P y pseudocódigo ensamblador (un código artesanal que hace movimientos con registros con nombres de tipo R[0-9]), pero solo para expresiones aritméticas sencillas.
Quiero compartirlos con ustedes y si quieren unirse a mi, adelante, son bienvenidos, ya que creanme que para mi no ha sido nada fácil, me ha resultado bastante complejo esto, y eso que aún no llego plenamente a la generación de código. En fin.
El "compilador" está hecho en Java, con la ayuda de NetBeans. ¿por qué en Java? porque tenía que hacer esto lo más pronto posible, en menos de 3 meses :s y en periodo escolar, por lo que no tenía mucho tiempo de dedicarle tiempo exclusivamente a esto :s, Java provee un fácil manejo con Strings, además de estructuras de datos que no iba a tener que armas desde 0, como las listas y las tablas de dispersión, además que es con lo que más se llevan mis compañeros.
Bueno, les comento un poco cómo se estructura el lenguaje, algunos ejemplos:
Código:
inicio miPrimerProgramaEnGLHBR
entero x = 3;
leer(x)
fin;
El código debe empezar por inicio ID sentencias fin;, siempre.
Código:
inicio Hello_Shit
entero x = 123;
inc(x, 2 * 3)
fin;
Código:
inicio X
entero x = 1;
write(x);
repetir
x = x + 5;
x = x - 4
hasta x == 10
fin;
Código:
inicio X
entero z = 1234 + 234 + 56 + 78;
infinito hacer
z = z + 12
porsiempre
fin;
El compilador procesa las operaciones aritméticas (obviamente las operaciones aritméticas se hacen checando precedencia de operadores) y hace el cálculo, por ejemplo esto:
Código:
inicio X
entero x = (3 * 69 - (5 * 85 - 14))
fin;
Y el código que se genera:
Código P:
Código:
;Código P para las sentencias enteras sencilla para el programa final.glhbr
ldc 3
ldc 69
mpi
ldc 5
ldc 85
mpi
ldc 14
sbi
sbi
Y el pseudocódigo ensamblador:
Código:
; Código ensamblador para el programa "final.glhbr"
MOV R0,#3 ; Cargamos 3
MOV R1,#69 ; Cargamos 69
MUL R0,R1 ; Multiplicamos
MOV R1,#5 ; Cargamos 5
MOV R2,#85 ; Cargamos 85
MUL R1,R2 ; Multiplicamos
MOV R2,#14 ; Cargamos 14
SUB R1,R2 ; Restamos
SUB R0,R1 ; Restamos
MOV x,R0 ; fin de la sentencia de asignación
; Rutina para mostrar el resultado de x
; R = -204.0
Todo esto recorriendo el nodo de árbol sintáctico correspondiente a una operación aritmética en postorden y luego la evaluación por medio de una pila.
Quizá alguien que sepa assembly pueda ayudar a traducir el pseudocódigo ensamblador a assembly real.
Son algunos de los usos, por supuesto, como ya les he dicho, no se ejecuta nada, porque no hay generación de código.... y para eso pido su ayuda, si alguno quiere unirse y aportar ideas, bienvenido! así aprendemos todos.
Bueno, les dejo el link el link y una captura:
El proyecto está en github por si quieren ver ahí los cambios que he hecho:
https://github.com/leogtzr/glhbr
Saludos.