Beispiel #1
0
 def tokenizar(self):
     """
     Tokeniza o código da classe Lexer e returna uma 
     fila de tokens. Essa fila é a implementada inter-
     namente na classe 'deque' do python, então em vez
     de um método 'dequeue()' temos um 'popleft()' de 
     funcionalidade equivalente. 
     """
     tokens = []
     while self.caracter_atual != None:
         if self.caracter_atual in ' \t\n\r\b\v\f':
             self.avancar()
         elif self.caracter_atual == '#':
             token = self.make_preprocessor()
             tokens.append(token)
             self.avancar()
         elif self.caracter_atual == '.':
             if self.lookahead() not in digitos:
                 self.avancar()
                 tokens.append(Token(TokenTipo.TOKEN_STRUCT_REF))
         elif self.caracter_atual in digitos + '.':
             token = self.make_numbers()
             tokens.append(token)
         elif self.caracter_atual in list(
                 operadores_unicos.keys()) + operadores_duplos:
             token = self.make_operador()
             if token != None:
                 tokens.append(token)
             self.avancar()
         elif self.caracter_atual in alfabeto + '_':
             token = self.parse_word()
             tokens.append(token)
         elif self.caracter_atual == '"':
             self.avancar()
             token = self.parse_string()
             tokens.append(token)
         elif self.caracter_atual == "'":
             self.avancar()
             token = self.parse_char()
             tokens.append(token)
         elif self.caracter_atual in list(separadores.keys()):
             token = self.make_separador()
             tokens.append(token)
             self.avancar()
         elif self.caracter_atual not in alfabeto_completo:
             message = 'Caracter fora do alfabeto reconhecido ' + str(
                 self.posicao)
             self.avancar()
             message += '\nlinha:\n\n' + self.contexto
             raise Exception(message)
         else:
             message = 'Erro durante analise léxica: "' + self.caracter_atual + '" Caracter não identificado.\n\nposição: ' + str(
                 self.posicao)
             self.avancar()
             message += '\nlinha:\n\n' + self.contexto
             raise Exception(message)
     tokens.append(Token(TokenTipo.TOKEN_EOF))
     return deque(tokens)
Beispiel #2
0
 def parse_word(self):
     """
     Captura uma palavra do tipo identificador ou keyword
     """
     token_str = ''
     while self.caracter_atual != None and self.caracter_atual in alfanumu:
         token_str += self.caracter_atual
         self.avancar()
     if token_str in keywords:
         return Token(TokenTipo.TOKEN_KEYWORD, valor=token_str)
     else:
         return Token(TokenTipo.TOKEN_IDENT, valor=token_str)
Beispiel #3
0
 def parse_char(self):
     """
     Captura um token do tipo char
     """
     token_str = ''
     while self.caracter_atual not in (None, "'"):
         token_str += self.caracter_atual
         self.avancar()
     if self.caracter_atual == "'":
         self.avancar()
     return Token(TokenTipo.TOKEN_CHAR, valor=token_str)
Beispiel #4
0
 def parse_string(self):
     """
     Captura um token do tipo string
     """
     token_str = ''
     while self.caracter_atual not in (None, '"'):
         token_str += self.caracter_atual
         self.avancar()
     if self.caracter_atual == '"':
         self.avancar()
     return Token(TokenTipo.TOKEN_STR, valor=token_str)
Beispiel #5
0
    def make_numbers(self):
        """
        Captura um token do tipo número, seja ele inteiro (
        decimal, binário, octal ou hexadecimal) ou real ( no-
        tação científica ou não).
        """
        numero_final = ''

        while self.caracter_atual != None and self.caracter_atual not in separadores:
            numero_final += self.caracter_atual
            self.avancar()

        if numero_final.startswith('0b') or numero_final.startswith('0B'):
            return Token(TokenTipo.TOKEN_BIN, numero_final)
        if numero_final.startswith('0x') or numero_final.startswith('0X'):
            return Token(TokenTipo.TOKEN_HEXA, numero_final)
        if numero_final.startswith('0') and len(numero_final) > 1:
            return Token(TokenTipo.TOKEN_OCT, numero_final)
        if '.' in numero_final:
            return Token(TokenTipo.TOKEN_REAL, numero_final)
        return Token(TokenTipo.TOKEN_INT, numero_final)
Beispiel #6
0
 def make_preprocessor(self):
     """
     Captura um token do tipo preprocessador (define,
     include e pragma)
     """
     token_str = ''
     token_tipo = None
     while self.caracter_atual not in (None, ' '):
         token_str += self.caracter_atual
         self.avancar()
     if token_str == '#define':
         token_tipo = TokenTipo.TOKEN_DEFINE
     elif token_str == '#include':
         token_tipo = TokenTipo.TOKEN_INCLUDE
     elif token_str == '#pragma':
         token_tipo = TokenTipo.TOKEN_PRAGMA
     token_data = ''
     while self.caracter_atual not in (None, '\n'):
         token_data += self.caracter_atual
         self.avancar()
     return Token(token_tipo, token_data)
Beispiel #7
0
 def make_operador(self):
     """
     Captura um token do tipo Operador, atentando
     para os operadores duplos (>>, <<, || etc.).
     """
     if self.caracter_atual in list(operadores_unicos.keys()):
         return Token(operadores_unicos[self.caracter_atual])
     if self.caracter_atual == '+':
         if self.lookahead() == '=':
             self.avancar()
             return Token(TokenTipo.TOKEN_SOMA_IG)
         if self.lookahead() == '+':
             self.avancar()
             return Token(TokenTipo.TOKEN_SOMA_UM)
         return Token(TokenTipo.TOKEN_SOMA)
     if self.caracter_atual == '-':
         if self.lookahead() == '=':
             self.avancar()
             return Token(TokenTipo.TOKEN_SUB_IG)
         if self.lookahead() == '-':
             self.avancar()
             return Token(TokenTipo.TOKEN_SUB_UM)
         if self.lookahead() == '>':
             self.avancar()
             return Token(TokenTipo.TOKEN_STRUCT_REF)
         return Token(TokenTipo.TOKEN_SUB)
     if self.caracter_atual == '>':
         if self.lookahead() == '>':
             self.avancar()
             if self.lookahead() == '=':
                 self.avancar()
                 return Token(TokenTipo.TOKEN_SHIFT_R_IG)
             return Token(TokenTipo.TOKEN_SHIFT_R)
         if self.lookahead() == '=':
             self.avancar()
             return Token(TokenTipo.TOKEN_MAIOR_IG)
         return Token(TokenTipo.TOKEN_MAIOR)
     if self.caracter_atual == '<':
         if self.lookahead() == '<':
             self.avancar()
             if self.lookahead() == '=':
                 self.avancar()
                 return Token(TokenTipo.TOKEN_SHIFT_L_IG)
             return Token(TokenTipo.TOKEN_SHIFT_L)
         if self.lookahead() == '=':
             self.avancar()
             return Token(TokenTipo.TOKEN_MENOR_IG)
         return Token(TokenTipo.TOKEN_MENOR)
     if self.caracter_atual == '|':
         if self.lookahead() == '|':
             self.avancar()
             return Token(TokenTipo.TOKEN_OR)
         if self.lookahead() == '=':
             self.avancar()
             return Token(TokenTipo.TOKEN_OR_IG)
         return Token(TokenTipo.TOKEN_ORB)
     if self.caracter_atual == '!':
         if self.lookahead() == '=':
             self.avancar()
             return Token(TokenTipo.TOKEN_NOT_IG)
         return Token(TokenTipo.TOKEN_NOT)
     if self.caracter_atual == '&':
         if self.lookahead() == '&':
             self.avancar()
             return Token(TokenTipo.TOKEN_AND)
         if self.lookahead() == '=':
             self.avancar()
             return Token(TokenTipo.TOKEN_AND_IG)
         return Token(TokenTipo.TOKEN_AMPERSAND)
     if self.caracter_atual == '=':
         if self.lookahead() == '=':
             self.avancar()
             return Token(TokenTipo.TOKEN_IGUAL)
         return Token(TokenTipo.TOKEN_ATRIB)
     if self.caracter_atual == '*':
         if self.lookahead() == '=':
             self.avancar()
             return Token(TokenTipo.TOKEN_MULT_IG)
         return Token(TokenTipo.TOKEN_ASTERISCO)
     if self.caracter_atual == '%':
         if self.lookahead() == '=':
             self.avancar()
             return Token(TokenTipo.TOKEN_MOD_IG)
         return Token(TokenTipo.TOKEN_MOD)
     if self.caracter_atual == '^':
         if self.lookahead() == '=':
             self.avancar()
             return Token(TokenTipo.TOKEN_XOR_IG)
         return Token(TokenTipo.TOKEN_XOR)
     if self.caracter_atual == '/':
         if self.lookahead() == '/':
             self.avancar_ate(chars=['\n', None])
         if self.lookahead() == '=':
             self.avancar()
             return Token(TokenTipo.TOKEN_DIV_IG)
         if self.lookahead() == '*':
             self.avancar(2)
             while self.lookahead() not in ['/', None]:
                 self.avancar_ate(chars=['*', None])
             self.avancar()
         else:
             return Token(TokenTipo.TOKEN_DIV)
Beispiel #8
0
 def make_separador(self):
     """
     Captura um token do tipo Separador
     """
     return Token(separadores[self.caracter_atual])