11# Definição da analise semântica
2- def analise_semantica (resultado_sintatico , debug = False ):
2+ def analise_semantica (tabela_de_classificação , debug = False ):
33 print ("\n Iniciando análise semântica...\n " )
44 tabela_variavies = {} # dicionário vazio
55 passa_reto = [ # lista de tokens que podem ser ignorados
@@ -34,140 +34,143 @@ def analise_semantica(resultado_sintatico, debug=False):
3434
3535 declara = False # controla a declaração de variáveis
3636
37- # vamos percorrer o resultado_sintatico
37+ # vamos percorrer a tabela_de_classificação
3838 # em busca de ['var','var'] que indica
3939 # a sessão de declaração de variáveis
4040 # que termina com ['inicio','inicio']
4141 # temos que buscar pelo terminal[0] = 'var'
4242 # e finalizar a busca com o terminal[0] = 'inicio'
4343
44- for posicao in range (len (resultado_sintatico )):
44+ for posicao in range (len (tabela_de_classificação )):
4545 # Se o debug estiver ativado, imprime o lexema e o token da posição atual
4646 if debug :
47- print (f"Analisando sintaxe de { resultado_sintatico [posicao ]} " )
47+ print (f"Analisando sintaxe de { tabela_de_classificação [posicao ]} " )
4848
4949 # Se o token da posição atual estiver na lista de tokens que devem ser ignorados, passa para a próxima posição
50- if resultado_sintatico [posicao ][1 ] in passa_reto :
50+ if tabela_de_classificação [posicao ][1 ] in passa_reto :
5151 continue
5252
53- if resultado_sintatico [posicao ][0 ] == 'var' : # declarações da variáveis
53+ if tabela_de_classificação [posicao ][0 ] == 'var' : # declarações da variáveis
5454 declara = True # inicia a etapa de declaração de variáveis
5555 continue # passa para a próxima posição
5656
57- elif resultado_sintatico [posicao ][0 ] == 'inicio' :
57+ elif tabela_de_classificação [posicao ][0 ] == 'inicio' :
5858 declara = False # finaliza a busca
5959 if debug :
6060 print ("\n Tabela de variáveis:\n " , tabela_variavies , "\n " )
6161 continue # passa para a próxima posição
6262
6363 # Quando lê um fimalgoritmo retorna
64- elif resultado_sintatico [posicao ][1 ] == 'fimalgoritmo' :
64+ elif tabela_de_classificação [posicao ][1 ] == 'fimalgoritmo' :
6565 return True , "Análise semântica concluída com sucesso." , tabela_variavies
6666
6767 # Quando lê uma variável
68- elif resultado_sintatico [posicao ][1 ] == 'var' :
68+ elif tabela_de_classificação [posicao ][1 ] == 'var' :
6969 # Se estiver na etapa de declaração de variáveis
7070 if declara : # se estiver declarando variável
71- tabela_variavies [resultado_sintatico [posicao ][0 ]] = resultado_sintatico [posicao + 1 ][0 ] # adiciona a variável e seu tipo na tabela
71+ tabela_variavies [tabela_de_classificação [posicao ][0 ]] = tabela_de_classificação [posicao + 1 ][0 ] # adiciona a variável e seu tipo na tabela
7272 posicao += 1 # pula para a próxima posição
7373 continue # passa para a próxima posição
7474 # Senão, salva o nome da variável e checa se está na tabela de variáveis
75- var = resultado_sintatico [posicao ][0 ]
75+ var = tabela_de_classificação [posicao ][0 ]
7676 if var in tabela_variavies :
7777 # Se o tipo da variável for lógico
7878 if tabela_variavies [var ] == 'logico' :
7979 # Se houver um leia antes, rejeita
80- if resultado_sintatico [posicao - 2 ][1 ] == 'leia' :
80+ if tabela_de_classificação [posicao - 2 ][1 ] == 'leia' :
8181 return False , f"Variável { var } é do tipo lógico e não pode ser lida."
82+ # Se houver um escreva antes, rejeita
83+ elif tabela_de_classificação [posicao - 2 ][1 ] == 'escreva' :
84+ return False , f"Variável { var } é do tipo lógico e não pode ser escrita."
8285 # Se houver um compara antes, testa se está comparando corretamente
83- elif resultado_sintatico [posicao - 1 ][1 ] == 'compara' :
86+ elif tabela_de_classificação [posicao - 1 ][1 ] == 'compara' :
8487 # Para o tipo lógico, só é permitido comparar igualdade ou diferença com outro lógico ou com verdadeiro ou falso
85- if resultado_sintatico [posicao - 1 ][0 ] == '==' or resultado_sintatico [posicao - 1 ][0 ] == '<>' :
86- if (resultado_sintatico [posicao - 2 ][1 ] == 'verdadeiro' or resultado_sintatico [posicao - 2 ][1 ] == 'falso' ) or tabela_variavies [resultado_sintatico [posicao - 2 ][0 ]] == 'logico' :
88+ if tabela_de_classificação [posicao - 1 ][0 ] == '==' or tabela_de_classificação [posicao - 1 ][0 ] == '<>' :
89+ if (tabela_de_classificação [posicao - 2 ][1 ] == 'verdadeiro' or tabela_de_classificação [posicao - 2 ][1 ] == 'falso' ) or tabela_variavies [tabela_de_classificação [posicao - 2 ][0 ]] == 'logico' :
8790 continue
8891 else :
89- return False , f"A variável { var } não pode ser comparada com { resultado_sintatico [posicao - 2 ][0 ]} . Ela só pode ser comparada com outra variável lógica ou com verdadeiro ou falso."
92+ return False , f"A variável { var } não pode ser comparada com { tabela_de_classificação [posicao - 2 ][0 ]} . Ela só pode ser comparada com outra variável lógica ou com verdadeiro ou falso."
9093 else :
91- return False , f"A variável { var } não pode ser comparada com o operador { resultado_sintatico [posicao - 1 ][0 ]} ."
94+ return False , f"A variável { var } não pode ser comparada com o operador { tabela_de_classificação [posicao - 1 ][0 ]} ."
9295 # Se o tipo da variável for numérico
9396 elif tabela_variavies [var ] == 'inteiro' or tabela_variavies [var ] == 'real' :
9497 # Caso especial para o tipo inteiro no comando para
95- if resultado_sintatico [posicao - 1 ][1 ] == 'para' :
98+ if tabela_de_classificação [posicao - 1 ][1 ] == 'para' :
9699 if tabela_variavies [var ] == 'inteiro' :
97100 # Testa se o intervalo é válido
98- if resultado_sintatico [posicao + 2 ][0 ] < resultado_sintatico [posicao + 4 ][0 ]:
101+ if tabela_de_classificação [posicao + 2 ][0 ] < tabela_de_classificação [posicao + 4 ][0 ]:
99102 continue
100103 else :
101- return False , f"A variável { var } não pôde ser inicializada com o intervalo especificado, pois o valor inicial { resultado_sintatico [posicao + 2 ][0 ]} é maior que o valor final { resultado_sintatico [posicao + 4 ][0 ]} ."
104+ return False , f"A variável { var } não pôde ser inicializada com o intervalo especificado, pois o valor inicial { tabela_de_classificação [posicao + 2 ][0 ]} é maior que o valor final { tabela_de_classificação [posicao + 4 ][0 ]} ."
102105 else :
103106 return False , f"A variável { var } não pode ser inicializada no comando para, pois não é do tipo inteiro."
104107 # Se houver um leia antes, aceita
105- if resultado_sintatico [posicao - 2 ][1 ] == 'leia' :
108+ if tabela_de_classificação [posicao - 2 ][1 ] == 'leia' :
106109 continue
107110 # Se houver um compara antes, testa se está comparando corretamente
108- elif resultado_sintatico [posicao - 1 ][1 ] == 'compara' :
111+ elif tabela_de_classificação [posicao - 1 ][1 ] == 'compara' :
109112 # Para o tipo numérico, é permitido comparar igualdade, diferença, maior, menor, maior ou igual e menor ou igual com outro numérico
110- if resultado_sintatico [posicao - 2 ][1 ] == 'valor' or (tabela_variavies [resultado_sintatico [posicao - 2 ][0 ]] == 'inteiro' or tabela_variavies [resultado_sintatico [posicao - 2 ][0 ]] == 'real' ):
113+ if tabela_de_classificação [posicao - 2 ][1 ] == 'valor' or (tabela_variavies [tabela_de_classificação [posicao - 2 ][0 ]] == 'inteiro' or tabela_variavies [tabela_de_classificação [posicao - 2 ][0 ]] == 'real' ):
111114 continue
112115 else :
113- return False , f"A variável { var } não pode ser comparada com { resultado_sintatico [posicao - 2 ][0 ]} . Ela só pode ser comparada com outra variável numérica ou com um valor."
116+ return False , f"A variável { var } não pode ser comparada com { tabela_de_classificação [posicao - 2 ][0 ]} . Ela só pode ser comparada com outra variável numérica ou com um valor."
114117 # Se o tipo da variável for mensagem
115118 elif tabela_variavies [var ] == 'caractere' :
116119 # Se houver um leia antes, aceita
117- if resultado_sintatico [posicao - 2 ][1 ] == 'leia' :
120+ if tabela_de_classificação [posicao - 2 ][1 ] == 'leia' :
118121 continue
119122 # Se houver um compara antes, rejeita
120- elif resultado_sintatico [posicao - 1 ][1 ] == 'compara' :
121- return False , f"A variável { var } é do tipo caractere e não pode ser comparada com { resultado_sintatico [posicao - 2 ][0 ]} ."
123+ elif tabela_de_classificação [posicao - 1 ][1 ] == 'compara' :
124+ return False , f"A variável { var } é do tipo caractere e não pode ser comparada com { tabela_de_classificação [posicao - 2 ][0 ]} ."
122125
123126 else :
124127 return False , f"Variável { var } não declarada."
125128
126129 # Quando lê um operador de atribuição
127- elif resultado_sintatico [posicao ][1 ] == 'atrib' :
130+ elif tabela_de_classificação [posicao ][1 ] == 'atrib' :
128131 # Salva o tipo da variável
129- tipo = tabela_variavies [resultado_sintatico [posicao - 1 ][0 ]]
132+ tipo = tabela_variavies [tabela_de_classificação [posicao - 1 ][0 ]]
130133 # Se o tipo da variável for lógica
131134 if tipo == 'logico' :
132135 # Para o tipo lógico, só é permitido atribuir verdadeiro, falso ou outro lógico
133- if resultado_sintatico [posicao + 1 ][1 ] == 'verdadeiro' or resultado_sintatico [posicao + 1 ][1 ] == 'falso' or tabela_variavies [resultado_sintatico [posicao + 1 ][0 ]] == 'logico' :
136+ if tabela_de_classificação [posicao + 1 ][1 ] == 'verdadeiro' or tabela_de_classificação [posicao + 1 ][1 ] == 'falso' or tabela_variavies [tabela_de_classificação [posicao + 1 ][0 ]] == 'logico' :
134137 continue
135138 else :
136- return False , f"A variável { resultado_sintatico [posicao - 1 ][0 ]} é do tipo lógico e não pode receber { resultado_sintatico [posicao + 1 ][0 ]} ."
139+ return False , f"A variável { tabela_de_classificação [posicao - 1 ][0 ]} é do tipo lógico e não pode receber { tabela_de_classificação [posicao + 1 ][0 ]} ."
137140 # Se o tipo da variável for numérico
138141 elif tipo == 'inteiro' or tipo == 'real' :
139142 # Para o tipo numérico, é permitido atribuir outro numérico, um valor ou uma expressão
140143 # Se for um valor ou uma variável numérica, aceita
141- if (resultado_sintatico [posicao + 1 ][1 ] == 'valor'
142- or (resultado_sintatico [posicao + 1 ][1 ] == 'var'
143- and (tabela_variavies [resultado_sintatico [posicao + 1 ][0 ]] == 'inteiro' or tabela_variavies [resultado_sintatico [posicao + 1 ][0 ]] == 'real' ))):
144+ if (tabela_de_classificação [posicao + 1 ][1 ] == 'valor'
145+ or (tabela_de_classificação [posicao + 1 ][1 ] == 'var'
146+ and (tabela_variavies [tabela_de_classificação [posicao + 1 ][0 ]] == 'inteiro' or tabela_variavies [tabela_de_classificação [posicao + 1 ][0 ]] == 'real' ))):
144147 continue
145148 # Se começar com um '(' é uma expressão, então testa se é válida
146- elif resultado_sintatico [posicao + 1 ][1 ] == '(' :
149+ elif tabela_de_classificação [posicao + 1 ][1 ] == '(' :
147150 valores = []
148151 pos_variaveis = posicao + 2
149- while resultado_sintatico [pos_variaveis ][1 ] != ')' :
150- if resultado_sintatico [pos_variaveis ][1 ] == 'var' :
151- valores .append (tabela_variavies [resultado_sintatico [pos_variaveis ][0 ]])
152- elif resultado_sintatico [pos_variaveis ][1 ] == 'valor' :
152+ while tabela_de_classificação [pos_variaveis ][1 ] != ')' :
153+ if tabela_de_classificação [pos_variaveis ][1 ] == 'var' :
154+ valores .append (tabela_variavies [tabela_de_classificação [pos_variaveis ][0 ]])
155+ elif tabela_de_classificação [pos_variaveis ][1 ] == 'valor' :
153156 valores .append ('valor' )
154157 pos_variaveis += 1
155158 if any (x in valores for x in ['logico' , 'caractere' ]):
156- return False , f"A variável { resultado_sintatico [posicao - 1 ][0 ]} é do tipo numérico e não pode receber uma expressão com variáveis lógicas ou de caractere."
159+ return False , f"A variável { tabela_de_classificação [posicao - 1 ][0 ]} é do tipo numérico e não pode receber uma expressão com variáveis lógicas ou de caractere."
157160 # Se a expressão for válida, aceita
158161 else :
159162 continue
160163 else :
161- return False , f"A variável { resultado_sintatico [posicao - 1 ][0 ]} é do tipo numérico e só pode receber um valor, uma variável numérica ou uma expressão numérica."
164+ return False , f"A variável { tabela_de_classificação [posicao - 1 ][0 ]} é do tipo numérico e só pode receber um valor, uma variável numérica ou uma expressão numérica."
162165 # Se o tipo da variável for mensagem
163166 elif tipo == 'caractere' :
164167 # Para o tipo mensagem, é permitido atribuir outra mensagem ou uma variável de mensagem
165- if (resultado_sintatico [posicao + 1 ][1 ] == 'msg'
166- or (resultado_sintatico [posicao + 1 ][1 ] == 'var'
167- and tabela_variavies [resultado_sintatico [posicao + 1 ][0 ]] == 'caractere' )):
168+ if (tabela_de_classificação [posicao + 1 ][1 ] == 'msg'
169+ or (tabela_de_classificação [posicao + 1 ][1 ] == 'var'
170+ and tabela_variavies [tabela_de_classificação [posicao + 1 ][0 ]] == 'caractere' )):
168171 continue
169172 else :
170- return False , f"A variável { resultado_sintatico [posicao - 1 ][0 ]} é do tipo mensagem e só pode receber uma mensagem ou uma variável de caractere."
173+ return False , f"A variável { tabela_de_classificação [posicao - 1 ][0 ]} é do tipo mensagem e só pode receber uma mensagem ou uma variável de caractere."
171174
172175 # Se não houver erros, retorna True
173176 return True , "Análise semântica concluída com sucesso." , tabela_variavies
0 commit comments