aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIván Ávalos <avalos@disroot.org>2022-11-22 09:02:46 -0600
committerIván Ávalos <avalos@disroot.org>2022-11-22 09:02:46 -0600
commit032fe000cfc2b36dc9c1f00c734fada41133403e (patch)
treecc489901762fe26dbe1253f7a4f2dca55956f89a
parent86c099629fad439402a51f031e3cb5507bc92278 (diff)
downloadjavanol-032fe000cfc2b36dc9c1f00c734fada41133403e.tar.gz
javanol-032fe000cfc2b36dc9c1f00c734fada41133403e.tar.bz2
javanol-032fe000cfc2b36dc9c1f00c734fada41133403e.zip
Se implementa semáforo (fases de compilación)
-rw-r--r--compilador/lexer.py21
-rw-r--r--compilador/main.py49
-rw-r--r--compilador/parser.py10
-rw-r--r--compilador/tabla.py11
-rw-r--r--interfaz/main.py122
5 files changed, 161 insertions, 52 deletions
diff --git a/compilador/lexer.py b/compilador/lexer.py
index bc2b14a..8bb7c13 100644
--- a/compilador/lexer.py
+++ b/compilador/lexer.py
@@ -34,7 +34,7 @@ class Selector(Enum):
ENTERO = 5
class Lexer:
- def __init__(self, data, input_file):
+ def __init__(self, input_file: str):
self.tabla = TablaLex()
self.numlinea = 1
self.selector = Selector.NINGUNO
@@ -44,26 +44,23 @@ class Lexer:
self.recol_operador = ''
self.recol_ident = ''
self.recol_entero = ''
- self.data = data
- self.tabla_file = None
- if input_file:
- self.tabla_file = input_file + '.tab'
+ self.input_file = input_file
+ with open(input_file) as f:
+ self.data = f.read()
def inicio(self):
for l in self.data.splitlines():
for c in l + "\n":
r = self.procesar(c)
- if r == Control.ERROR: exit(1)
+ if r == Control.ERROR: return 1
while r != Control.SIGUIENTE:
r = self.procesar(c)
- if r == Control.ERROR: exit(1)
+ if r == Control.ERROR: return 1
self.numlinea += 1
- # Imprimir tabla de símbolos
- if self.tabla_file:
- self.tabla.exportar(self.tabla_file)
- Parser(self.tabla).inicio()
-
+ # Exportar tabla de símbolos
+ self.tabla.exportar(self.input_file + '.tab')
+ return 0
def procesar(self, c):
# if c != "\t" and c != "\n":
diff --git a/compilador/main.py b/compilador/main.py
index 186ca83..98e23c9 100644
--- a/compilador/main.py
+++ b/compilador/main.py
@@ -1,21 +1,30 @@
-import sys, getopt
+import sys, getopt, os, traceback
+from enum import Enum
from tkinter import *
from tkinter import ttk, filedialog
from lexer import *
+class Step(Enum):
+ LEXICO = 0
+ SINTACTICO = 1
+ SEMANTICO = 2
+
class Main:
input_file = None
output_file = None
output_table = False
+ step = None
def print_help (self, arg0):
print("Uso: % s -i entrada.es -o salida.es" % arg0)
- print(" % s -i entrada.es -o salida.es -t")
+ print(" % s -i entrada.es -o salida.es [-l|-p|-s] [-t]" % arg0)
print(" % s -h" % arg0)
def main(self, argv):
try:
- opts, args = getopt.getopt(argv[1:], "hi:o:t", ["input=", "output=", "table"])
+ opts, args = getopt.getopt(argv[1:], "hi:o:lpst", [
+ "input=", "output=", "lex", "parse", "semantic", "table"
+ ])
except getopt.GetoptError as err:
print(err)
print_help(argv[0]);
@@ -30,16 +39,40 @@ class Main:
self.output_file = a
elif o in ("-t", "--table"):
self.output_table = True
+ elif o in ("-l", "--lex"):
+ self.step = Step.LEXICO
+ elif o in ("-p", "--parse"):
+ self.step = Step.SINTACTICO
+ elif o in ("-s", "--semantic"):
+ self.step = Step.SEMANTICO
else:
assert False, "opción desconocida"
if self.input_file and self.output_file:
- with open(self.input_file) as f:
- data = f.read()
- if self.output_table:
- Lexer(data, self.input_file).inicio()
+ table_file = self.input_file + '.tab'
+ delete_tab = not self.step and not self.output_table and not os.path.exists(table_file)
+ try:
+ if self.step == Step.LEXICO:
+ sys.exit(Lexer(self.input_file).inicio())
+ elif self.step == Step.SINTACTICO:
+ sys.exit(Parser(self.input_file).inicio())
+ elif self.step == Step.SEMANTICO:
+ print("NOT IMPLEMENTED")
+ sys.exit(1)
else:
- Lexer(data, None).inicio()
+ if Lexer(self.input_file).inicio() != 0:
+ raise Exception("Error léxico")
+ if Parser(self.input_file).inicio() != 0:
+ raise Exception("Error sintáctico")
+ except Exception as e:
+ traceback.print_exception(type(e), e, e.__traceback__)
+ sys.exit(1)
+ # Borrar tabla de símbolos
+ if delete_tab:
+ os.remove(table_file)
+ else:
+ self.print_help(argv[0])
+ sys.exit(2)
if __name__ == "__main__":
Main().main(sys.argv)
diff --git a/compilador/parser.py b/compilador/parser.py
index 6c6d223..951b517 100644
--- a/compilador/parser.py
+++ b/compilador/parser.py
@@ -23,24 +23,26 @@ class Selector(Enum):
FUNCION = 7
class Parser:
- def __init__(self, tabla):
+ def __init__(self, input_file: str):
self.arbol = Arbol()
self.pila_selector = [
[Selector.NINGUNO, []] # selector, recolector
]
self.pila_arbol = [self.arbol.raiz]
self.expresion = None
- self.tabla = tabla
+ self.tabla = TablaLex()
+ self.tabla.importar(input_file + '.tab')
def inicio (self):
for t in self.tabla.tabla:
r = self.procesar(t)
- if r == Control.ERROR: exit(1)
+ if r == Control.ERROR: return 1
while r != Control.SIGUIENTE:
r = self.procesar(t)
- if r == Control.ERROR: exit(1)
+ if r == Control.ERROR: return 1
print(str(self.arbol))
+ return 0
def procesar (self, t: LexToken):
if len(self.pila_selector) == 0:
diff --git a/compilador/tabla.py b/compilador/tabla.py
index 637b9a6..ebe6225 100644
--- a/compilador/tabla.py
+++ b/compilador/tabla.py
@@ -70,7 +70,7 @@ class TablaLex:
data.append({
'tipo': t.tipo,
'nombre': t.nombre,
- 'valor': str(t.valor),
+ 'valor': t.valor,
'numlinea': t.numlinea
})
output = json.dumps(data)
@@ -80,6 +80,15 @@ class TablaLex:
f.truncate(0)
f.write(output)
+ def importar(self, input_file):
+ with open(input_file, 'r') as f:
+ data = json.loads(f.read())
+ for t in data:
+ self.insertar(LexToken(t['tipo'],
+ t['nombre'],
+ t['valor'],
+ t['numlinea']))
+
def __str__(self):
output = ""
for t in self.tabla:
diff --git a/interfaz/main.py b/interfaz/main.py
index d59241d..b6c5ac9 100644
--- a/interfaz/main.py
+++ b/interfaz/main.py
@@ -24,9 +24,9 @@ class Semaforo(Gtk.DrawingArea):
if color == self.Color.VERDE:
self.set_draw_func(self.dibujar_sem_verde, None)
elif color == self.Color.AMARILLO:
- self.set_draw_func(self.dibujar_sem_rojo, None)
- elif color == self.Color.ROJO:
self.set_draw_func(self.dibujar_sem_amarillo, None)
+ elif color == self.Color.ROJO:
+ self.set_draw_func(self.dibujar_sem_rojo, None)
else:
self.set_draw_func(self.dibujar_sem_ninguno, None)
@@ -100,6 +100,7 @@ class MainWindow(Gtk.ApplicationWindow):
self.save_button = Gtk.Button(label='Guardar')
self.save_button.set_icon_name('document-save-symbolic')
+ self.save_button.set_sensitive(False)
self.save_button.connect('clicked', self.guardar_archivo)
header.pack_start(self.save_button)
@@ -140,6 +141,7 @@ class MainWindow(Gtk.ApplicationWindow):
self.grid.attach(scrolled_win, 0, 0, 1, 1)
self.sourcebuf = GtkSource.Buffer()
+ self.sourcebuf.connect('changed', self.edito_codigo)
self.sourceview = GtkSource.View.new_with_buffer(self.sourcebuf)
self.sourceview.set_show_line_numbers(True)
self.sourceview.set_auto_indent(True)
@@ -227,14 +229,8 @@ class MainWindow(Gtk.ApplicationWindow):
notebook.append_page(semgrid, Gtk.Label.new('Semáforo'))
- def analisis_lexico(self, button):
- print("analisis_lexico(...)")
-
- def analisis_sintactico(self, button):
- print("analisis_sintactico(...)")
-
- def analisis_semantico(self, button):
- print("analisis_semantico(...)")
+ def edito_codigo(self, buffer):
+ self.reset_semaforos()
def abrir_archivo(self, button):
self.open_dialog = Gtk.FileChooserNative.new(
@@ -252,8 +248,10 @@ class MainWindow(Gtk.ApplicationWindow):
with open(self.input_file) as f:
data = f.read()
self.sourcebuf.set_text(data)
+ self.save_button.set_sensitive(True)
self.run_button.set_sensitive(True)
self.btn_lexico.set_sensitive(True)
+ self.sem_lexico.set_color(Semaforo.Color.AMARILLO)
def guardar_archivo(self, button):
if self.input_file:
@@ -284,30 +282,89 @@ Tecnológico Nacional de México en Celaya''')
self.about_dialog.set_logo_icon_name('applications-development')
self.about_dialog.show()
+ def analisis_lexico(self, button):
+ self.guardar_archivo(None)
+ self.limpiar_tabla()
+ self.reset_semaforos()
+ result = subprocess.run([
+ 'python', compilador_dir,
+ '-i', self.input_file,
+ '-o', self.output_file,
+ '-l'
+ ], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ output = result.stdout.decode('utf-8')
+ self.msgbuf.set_text(output)
+
+ if result.returncode == 0:
+ self.sem_lexico.set_color(Semaforo.Color.VERDE)
+ self.sem_sintactico.set_color(Semaforo.Color.AMARILLO)
+ self.btn_sintactico.set_sensitive(True)
+ self.llenar_tabla()
+ else:
+ self.sem_lexico.set_color(Semaforo.Color.ROJO)
+
+ def analisis_sintactico(self, button):
+ self.limpiar_tabla()
+ self.sem_semantico.set_color(Semaforo.Color.NINGUNO)
+ self.btn_semantico.set_sensitive(False)
+ result = subprocess.run([
+ 'python', compilador_dir,
+ '-i', self.input_file,
+ '-o', self.output_file,
+ '-p'
+ ], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ output = result.stdout.decode('utf-8')
+ self.msgbuf.set_text(output)
+
+ if result.returncode == 0:
+ self.sem_sintactico.set_color(Semaforo.Color.VERDE)
+ self.sem_semantico.set_color(Semaforo.Color.AMARILLO)
+ self.btn_semantico.set_sensitive(True)
+ self.llenar_tabla()
+ else:
+ self.sem_sintactico.set_color(Semaforo.Color.ROJO)
+ self.btn_sintactico.set_sensitive(False)
+
+ def analisis_semantico(self, button):
+ self.limpiar_tabla()
+ result = subprocess.run([
+ 'python', compilador_dir,
+ '-i', self.input_file,
+ '-o', self.output_file,
+ '-s'
+ ], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ output = result.stdout.decode('utf-8')
+ self.msgbuf.set_text(output)
+
+ if result.returncode == 0:
+ self.sem_semantico.set_color(Semaforo.Color.VERDE)
+ self.llenar_tabla()
+ else:
+ self.sem_semantico.set_color(Semaforo.Color.ROJO)
+
def correr(self, button):
self.guardar_archivo(None)
+ self.reset_semaforos()
self.limpiar_tabla()
- if self.input_file:
- result = subprocess.run([
- 'python', compilador_dir,
- '-i', self.input_file,
- '-o', self.output_file,
- '-t'
- ], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- output = result.stdout.decode('utf-8')
- self.msgbuf.set_text(output)
-
- if result.returncode == 0:
- # Tabla de símbolos
- with open(self.input_file + '.tab', 'r') as f:
- data = f.read()
- self.llenar_tabla(data)
+ result = subprocess.run([
+ 'python', compilador_dir,
+ '-i', self.input_file,
+ '-o', self.output_file,
+ '-t'
+ ], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ output = result.stdout.decode('utf-8')
+ self.msgbuf.set_text(output)
+
+ if result.returncode == 0:
+ self.llenar_tabla()
def limpiar_tabla(self):
for i in range(4):
self.tablagrid.remove_column(0)
- def llenar_tabla(self, data):
+ def llenar_tabla(self):
+ with open(self.input_file + '.tab', 'r') as f:
+ data = f.read()
tabla = json.loads(data)
label_linea = Gtk.Label.new(None)
label_linea.set_markup('<b>Línea</b>')
@@ -327,7 +384,18 @@ Tecnológico Nacional de México en Celaya''')
self.tablagrid.attach(Gtk.Label.new(t['tipo']), 1, row, 1, 1)
self.tablagrid.attach(Gtk.Label.new(t['nombre']), 2, row, 1, 1)
self.tablagrid.attach(Gtk.Label.new(str(t['valor'])), 3, row, 1, 1)
-
+
+ def reset_semaforos(self):
+ if self.input_file:
+ self.sem_lexico.set_color(Semaforo.Color.AMARILLO)
+ self.btn_lexico.set_sensitive(True)
+ else:
+ self.sem_lexico.set_color(Semaforo.Color.NINGUNO)
+ self.btn_lexico.set_sensitive(False)
+ self.sem_sintactico.set_color(Semaforo.Color.NINGUNO)
+ self.btn_sintactico.set_sensitive(False)
+ self.sem_semantico.set_color(Semaforo.Color.NINGUNO)
+ self.btn_semantico.set_sensitive(False)
def on_activate(app):
win = MainWindow()