Beispiel #1
0
    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
Beispiel #2
0
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
Beispiel #3
0
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)