def copy(self): tmp = Stack() while not self.liquids.isEmpty(): liquid: Liquid = self.liquids.pop() tmp.push(liquid) new_tube = Tube(self.name, self.sx, self.sy, self.width, self.height, self.height_per_volume, self.capacity) while not tmp.isEmpty(): liquid: Liquid = tmp.pop() new_tube.addLiquid(liquid.getColor()) self.liquids.push(liquid) return new_tube
class Tube: def __init__(self, name, sx, sy, width, height, height_per_volume, liquid_capacity) -> None: self.name = name self.sx = sx self.sy = sy self.width = width self.height = height self.height_per_volume = height_per_volume self.capacity = liquid_capacity self.liquids = Stack() self.colors = {} def draw(self, win: GraphWin): Text(Point(self.sx + (self.width // 2), self.sy + (self.width // 2)), self.name).draw(win) Line(Point(self.sx, self.sy), Point(self.sx, self.sy - self.height)).draw(win) Line(Point(self.sx + self.width, self.sy), Point(self.sx + self.width, self.sy - self.height)).draw(win) Line(Point(self.sx, self.sy - self.height), Point(self.sx + self.width, self.sy - self.height)).draw(win) tmp_liquids = Stack() while not self.liquids.isEmpty(): liquid: Liquid = self.liquids.pop() liquid.draw(win) tmp_liquids.push(liquid) self.liquids = tmp_liquids.reverse() def undraw(self): tmp_liquids = Stack() while not self.liquids.isEmpty(): liquid: Liquid = self.liquids.pop() liquid.undraw() tmp_liquids.push(liquid) self.liquids = tmp_liquids.reverse() def getNumLiquids(self): return self.liquids.getSize() def getName(self): return self.name def getTopLiquid(self): if self.liquids.isEmpty(): return None return self.liquids.top() def isFull(self): return self.getNumLiquids() == self.capacity def canAddLiquid(self, liquid): liquids_match = self.liquids.isEmpty() or self.liquids.top( ).isColorMatch(liquid) has_room = not self.isFull() return liquids_match and has_room def addLiquid(self, color): sx = self.sx sy = self.sy - self.height + \ self.height_per_volume * (self.getNumLiquids()) liquid = Liquid(sx, sy, self.width, self.height_per_volume, color) self.liquids.push(liquid) if color not in self.colors: self.colors[color] = 0 self.colors[color] += 1 def removeLiquid(self): if not self.liquids.isEmpty(): liquid = self.liquids.pop() self.colors[liquid.getColor()] -= 1 return liquid def copy(self): tmp = Stack() while not self.liquids.isEmpty(): liquid: Liquid = self.liquids.pop() tmp.push(liquid) new_tube = Tube(self.name, self.sx, self.sy, self.width, self.height, self.height_per_volume, self.capacity) while not tmp.isEmpty(): liquid: Liquid = tmp.pop() new_tube.addLiquid(liquid.getColor()) self.liquids.push(liquid) return new_tube def isSorted(self): still_has = set(c for c in self.colors if self.colors[c] > 0) return len(still_has) == 1 def getNumUnsorted(self): still_has = set(c for c in self.colors if self.colors[c] > 0) result = len(still_has) return result if result > 0 else 0 def getNumAlternating(self): alt = 0 tmp = Stack() prev_color = None while not self.liquids.isEmpty(): liquid = self.liquids.pop() color = liquid.getColor() if not color == prev_color and prev_color is not None: alt += 1 prev_color = color tmp.push(liquid) self.liquids = tmp.reverse() return alt def getNumGroups(self): groups = [0] g_idx = 0 tmp = Stack() prev_color = None while not self.liquids.isEmpty(): liquid = self.liquids.pop() color = liquid.getColor() if not color == prev_color and prev_color is not None: groups.append(0) g_idx += 1 groups[g_idx] += 1 prev_color = color tmp.push(liquid) self.liquids = tmp.reverse() return len([x for x in groups if x > 0]) def __str__(self) -> str: tmp = Stack() result = "" while not self.liquids.isEmpty(): liquid = self.liquids.pop() result += liquid.getColor() + " -> " tmp.push(liquid) self.liquids = tmp.reverse() return result
class SyntaxAnalyser: def __init__(self, tokens, ls): self.__tokens = tokens self.__syntax_table_values = { 0: 'BeginFun <LISTA_COMANDOS> EndFun', 1: '<COMANDO> TK_PERIOD <LISTA_COMANDOS>', 2: '#', 3: '<INPUT>', 4: 'grabInput TK_ID <KEY>', 5: '<KEY>', 6: 'TK_COMMA TK_ID <INPUT>', 7: '#', 8: '<ANT_VAR> TK_ID <DPS_VAR>', 9: 'TK_ATRIB <EXP>', 10: '#', 11: 'funny', 12: '#', 13: '<DISPLAY>', 14: 'showMeTheCode <DISPLAY_F>', 15: 'TK_ID', 16: '<STRING>', 17: 'TK_STRING', 18: 'if <EXPR_BOOL> then <LISTA_COMANDOS> <ELSE> end', 19: 'else <LISTA_COMANDOS>', 20: '#', 21: 'funLoopWhile <EXPR_BOOL> do <LISTA_COMANDOS> endFunLoop', 22: '<OPERAN> <EXP_F>', 23: 'TK_OPEN_P <EXP> TK_CLOSE_P <EXP_F>', 24: 'TK_OP_AR <EXP>', 25: '#', 26: '<OPER>', 27: '<OPERAN> <BOOL_F>', 28: 'TK_OP_RE <EXPR_BOOL>', 29: '<BOOL_TYPE> <EXPR_BOOL>', 30: 'TK_BOOL', 31: '<OPER_REL>', 32: '#', 33: 'TK_ID', 34: 'TK_NUM' } self.__syntax_table = SYNTAX_TABLE self.ls = ls self.__log_syntax_analyser = [] self.initiate_stack() self.recognise_sentence() self.tokens_recognised() self.show_log() def append_log(self, log): self.__log_syntax_analyser.append(log) def show_log(self): if self.ls: for logline in self.__log_syntax_analyser: print(logline) def initiate_stack(self): self.__stack = Stack() self.append_log("\n---------------Analisador Sintático--------------") self.append_log("\n------LOG DE OPERAÇÕES:") self.append_log("Empilhar $") self.__stack.push('$') self.append_log("Empilhar Não-Terminal Inicial \n") self.__stack.push('<PROGRAMA>') def tokens_recognised(self): self.append_log("Verificar Pilha Vazia") self.append_log("Verificar Estado da Lista\n") return self.__stack.isEmpty() and not self.__tokens def error_verification(self, top_stack, first_elem): tk_line = self.__tokens[0].line tk_col = self.__tokens[0].col lex = self.__tokens[0].lexeme if self.__stack.isEmpty() and self.__tokens: self.append_log("Verificar Pilha Vazia") self.append_log("Verificar Estado da Lista") SyntaxError(tk_line, tk_col, lex, 'PILHA VAZIA e ainda há elementos na LISTA') elif not self.__stack.isEmpty() and len(self.__tokens) == 0: self.append_log("Verificar Pilha Vazia") self.append_log("Verificar Estado da Lista") SyntaxError(tk_line, tk_col, lex, 'LISTA VAZIA e ainda há elementos na Pilha') else: SyntaxError( tk_line, tk_col, lex, f'Não encontrou um elemento correspondente na tabela - {top_stack}:{first_elem}' ) def consult_table(self, line, col): self.append_log("Buscar Indice na Tabela Sintática") rules_index = self.__syntax_table[line][col] # prodution found if rules_index == '': self.error_verification(line, col) self.append_log("Retornar Produção Encontrada") rule = self.__syntax_table_values[rules_index] # pop the last element of the stack self.append_log("Desempilhar") self.__stack.pop() # split the whole rule rule = rule.split() max = len(rule) for i in range(max): # send element in opposite order to the stack rule_to_stack = rule.pop() if rule_to_stack == '#': continue self.append_log(f"Empilhar Produção: {rule_to_stack}\n") self.__stack.push(rule_to_stack) def recognise_sentence(self): index = 0 try: while not self.tokens_recognised(): self.append_log('Consultar Topo') top_stack = self.__stack.peek() self.append_log('Consultar Elemento da Lista') first_elem = self.__tokens[index].type if top_stack == first_elem: self.append_log(f"Desempilhar ({top_stack})") self.__stack.pop() self.append_log( f"Remover Elemento da Lista ({first_elem})\n") self.__tokens.pop(0) #removing first token elif self.__syntax_table[top_stack][first_elem] != None: self.consult_table(top_stack, first_elem) except Exception as ex: self.error_verification(top_stack, first_elem)