-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsemantic.py
More file actions
90 lines (73 loc) · 3.96 KB
/
semantic.py
File metadata and controls
90 lines (73 loc) · 3.96 KB
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
import lexer
class Variable:
def __init__(self, type):
self.type = type
class Operator:
def __init__(self, type, name, value=None):
self.type = type
self.name = name
self.value = value
class Semantic:
RETURN_BOOL = [">", ">=", "<", "<=", "=", "!=", "and", "or", "not"]
RETURN_NUM = ["+", "-", "*", "/"]
def __init__(self, operators):
self.operators: list[Operator] = operators
self.error = False
self.error_msg = "Semantic: OK"
self.variables: dict[Variable] = {}
def set_error(self, msg):
self.error = True
self.error_msg = "Semantic: " + msg
def check(self):
i = 0
while i < len(self.operators):
if self.operators[i].type == lexer.Lexer.DIM:
j = i + 1
while self.operators[j].name != "TYPE":
j += 1
vars_type = lexer.decrypt[self.operators[j].type]
for x in range(i + 1, j + 1, 2):
self.variables[self.operators[x].value] = Variable(vars_type)
elif self.operators[i].type == lexer.Lexer.ID and self.operators[i + 1].type == lexer.Lexer.ASSIGN:
if self.variables.get(self.operators[i].value) is None:
self.error = True
self.error_msg = "Undeclared variable " + self.operators[i].value
id_type = self.variables[self.operators[i].value].type
const_type = lexer.decrypt[self.operators[i + 2].type]
operation_return = lexer.decrypt[self.operators[i + 3].type]
if operation_return == ";" or operation_return == "to":
if const_type == "ID" and self.variables[self.operators[i].value].type != id_type:
print("ID SEMANTIC")
self.error = True
if self.variables.get(self.operators[i + 2].value) is None:
self.error_msg = "Undeclared variable " + self.operators[i+2].value
break
self.error_msg = ("Wrong type: " + self.operators[i].value + " is " +
id_type + " unable to assign " +
self.variables[self.operators[i + 2].value].type + " type")
break
elif const_type != "ID" and not ((id_type == "INT" or id_type == "FLOAT") and (const_type == "NUM"
or const_type == "REAL") or (id_type == "BOOL" and const_type == "BOOL_VAL")):
print("CONST SEMANTIC")
self.error = True
self.error_msg = ("Wrong type: " + self.operators[i].value + " is " +
id_type + " unable to assign " +
const_type + " type")
break
elif ((id_type == "INT" or id_type == "FLOAT") and operation_return not in
self.RETURN_NUM) or id_type == "BOOL" and operation_return not in self.RETURN_BOOL:
print(operation_return)
print("OPERATOR SEMANTIC")
self.error = True
if operation_return in self.RETURN_NUM:
self.error_msg = ("Wrong type: " + self.operators[i].value + " is " + id_type
+ " unable to assign number type")
else:
self.error_msg = ("Wrong type: " + self.operators[i].value + " is " + id_type
+ " unable to assign BOOL type")
break
elif self.operators[i].type == lexer.Lexer.ID:
if self.variables.get(self.operators[i].value) is None:
self.error = True
self.error_msg = "Undeclared variable " + self.operators[i].value
i += 1