-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLexAsgard.py
175 lines (123 loc) · 3.72 KB
/
LexAsgard.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
import ply.lex as lex
import re
# Diccionario para las palabras reservadas, donde tenemos como llaves las que están en el código y como valores las resultantes de la especificación
reserved = {
"using": "TkUsing",
"begin": "TkBegin",
"end": "TkEnd",
"of": "TkOf",
"type": "TkType",
"from": "TkFrom",
"to": "TkTo",
"repeat": "TkRepeat",
"if": "TkIf",
"then": "TkThen",
"otherwise": "TkOtherwise",
"done": "TkDone",
"print": "TkPrint",
"while": "TkWhile",
"read": "TkRead",
"with": "TkWith",
"integer": "TkInteger",
"boolean": "TkBoolean",
"canvas": "TkCanvas",
"true": "TkTrue",
"false": "TkFalse"
}
tokens = (
# Separadores , ; ( )
"TkComa", "TkPuntoYComa", "TkParAbre", "TkParCierra",
# Operadores Aritméticos + - * / %
"TkMas", "TkMenos", "TkMult", "TkDiv", "TkMod",
# Operadores Booleanos /\ \/ ^
"TkConjuncion", "TkDisjuncion", "TkNegacion",
# Operadores relacionales < <= > >= = !=
"TkMenor", "TkMenorIgual", "TkMayor", "TkMayorIgual", "TkIgual", "TkDesigual",
# Operadores de Lienzo : | $ '
"TkConcatHorizontal", "TkConcatVertical", "TkRotacion", "TkTransposicion",
# Operador de asignación :=
"TkAsignacion",
# Identificadores
"TkIdent", "TkNumLit", "TkCanvasLit",
)
tokens += tuple(reserved.values())
# Lista de tokens para imprimir al final
tokens_salida = []
# Lista para almacenar los tokens y valores de cada error
errores = []
def t_TkIdent(t):
r'[a-zA-Z][a-zA-Z0-9]*'
t.type = reserved.get(t.value, 'TkIdent') # Buscamos las palabras reservadas
return t
def t_TkCanvasLit(t):
r'<empty>|<[\\\|\/\.\_]>'
return t
t_TkNumLit = r'[0-9]+'
def t_Comentario(t):
r'\{\-(.|\n)*?\-\}'
# Debemos buscar los saltos de línea en la expresión
saltos_de_linea = len([m.start() for m in re.finditer('\n', t.value)])
# Los añadimos al lexer
t.lexer.lineno += saltos_de_linea
pass
# Definimos las demás reglas para los tokens sencillos
# Separadores
t_TkComa = r','
t_TkPuntoYComa = r'\;'
t_TkParAbre = r'\('
t_TkParCierra = r'\)'
# Operadores Aritméticos
t_TkMas = r'\+'
t_TkMenos = r'\-'
t_TkMult = r'\*'
t_TkDiv = r'\/'
t_TkMod = r'\%'
# Operadores Lógicos
t_TkConjuncion = r'\/\\'
t_TkDisjuncion = r'\\\/'
t_TkNegacion = r'\^'
# Operadores Relacionales
t_TkMenor = r'\<'
t_TkMenorIgual = r'\<='
t_TkMayor = r'\>'
t_TkMayorIgual = r'\>='
t_TkIgual = r'\='
t_TkDesigual = r'\/='
# Operadores de Canvas
t_TkConcatHorizontal = r'\:'
t_TkConcatVertical = r'\|'
t_TkRotacion = r'\$'
t_TkTransposicion = r'\''
# Operador Asignación
t_TkAsignacion = r'\:='
# Ignoramos los espacios, los tabuladores y los saltos de línea
t_ignore = ' \t'
# Calculamos cada línea
def t_nuevalinea(t):
r'\n+'
t.lexer.lineno += len(t.value)
# Regla para manejar los errores, almacenandolos en una lista
def t_error(t):
errores.append(t)
t.lexer.skip(1)
# Creamos el lexer, silenciando los warnings
lexer = lex.lex(errorlog=lex.NullLogger())
# Funcion para generar tokens
def token_gen(lexer, tokens_salida, errores):
# Primeramente, creamos los tokens
while True:
# Creamos el token
tok = lexer.token()
if not tok:
break # No hay más input para crear tokens
# Dependiendo de su tipo, lo almacenamos en errores o en la salida normal
if tok.type == "error":
errores.append(tok)
else:
tokens_salida.append(tok)
# Función para calcular el número de columna
# input es el texto ingresado
# token es la instancia del token a buscar
def find_column(input, token):
comienzo = input.rfind('\n', 0, token.lexpos) + 1
return (token.lexpos - comienzo) + 1