Basic.Py

 avatar
unknown
python
3 years ago
5.2 kB
3
Indexable
 Base.py
 
#constants
 
DIGITS = '0123456789'
 
 
 
# errors
 
class Error:
    def __ init__(self, Positon_start,Positon_end,Error_name, details):
        self.Positon_start = Positon_start
        self.Positon_end = Positon_end
        self.Error_name = Error_name
        self.details = details
        
    def as_string(self):
        result = f '{self.Error_name}: {self.details}'
        result += f'filename {self.Positon.filename}, lineNumber {self.Positon_start.index + 1}'
        return result
        
class InvaildCharacterError(Error):
    def __ init__(self, Positon_start, Positon_end, details):
        super().__init__(Positon_start,Positon_end,'InvaildCharacter', details):
            
            
# Positon
 
 
class Positon:
    def__init__(self, index, lineNumber, ColumNumber, filename, filetext)
    self.index = index
    self.lineNumber = lineNumber
    self.ColumNumber = ColumNumber
    self.filename = filename
    self.filetext = filetext
    def advance(self, current_Character):
        self.index += 1
        self.ColumNumber +=1
        
        if current_Character = '\n':
            self.lineNumber +=1
            self.ColumNumber = 0
            
            return self
def copy(self):
    return Positon(self.index, self.index, self.ColumNumber, self.filename, self.filetext)
        
        
 
 
 
# Tokens
TT_INT = 'TT_INT'
TT_FLOAT = "TT_FLOAT"
TT_PLUS = "TT_PLUS"
TT_MINUS = "TT_MINUS"
TT_MULITIPLY = "TT_MULITIPLY"
TT_DIVIDE = "TT_DIVIDE"
TT_Leftparenthesi = "TT_Leftparenthesi"
TT_Rightparenthesi = "TT_Rightparenthesi"
TT_ToThePower = "TT_ToThePower"
 
class Token:
    def __ init__(self, type_, value = None):
    self.type = type_
    self.value = value
    
    
    def __repr__(self):
         if self.value: return f'{self.type}:{self.value}`
         return f' {self.type}'
         
#Lexer
 
class Lexer:
    def __init__(self, filename, text):
        self.filename = filename
        self.text = text
        self.Positon Positon(-1, 0, -1, filename, text)
        self.current_Character = None
        self.advance()
        
        
    def advance(self):
        self.Positon.advance(self.current_Character)
        self.current_Character = self.text[self.Positon.index] if self.Positon.index < length(self.text) else None
    
    def make_tokens(self):
        Tokens = []
        
       while self.current_Character != None:
           if self.current_Character in '\t':
               self.advance()
               elif self.current_Character in DIGITS:
                   Tokens.append(self.make_number())
               elif self.current_Character == '+':
                   Tokens.append(Token(TT_PLUS))
                   self.advance()
                   elif self.current_Character = '-':
                       Tokens.append(Token(TT_MINUS))
                       self.advance()
                       elif self.current_Character = '*':
                       Tokens.append(Token(TT_MULITIPLY))
                       self.advance()
                       elif self.current_Character = '/':
                           Tokens.append(Token(TT_DIVIDE))
                           self.advance()
                           elif self.current_Character = '^':
                               Tokens.append(Token(TT_ToThePower))
                               self.advance()
                               elif self.current_Character = '('
                               Tokens.append(Token(TT_Leftparenthesi))
                               self.advance
                               elif self.current_Character = ')'
                               Tokens.append(Token(TT_Rightparenthesi))
                               self.advance
                               else:
                                   Positon_start = self.Positon.copy()
                                   character = self.current_Character
                                   self.advance
                                   return [], InvaildCharacterError(Positon_start, self.Positon, "'"+  character + "'")
                           
       
        return Tokens, None
        
        def make_number(self):
            number_string = ''
            dot_count = 0
            
            while self.current_Character != None and self.current_Character in DIGITS + '.':
                if self.current_Character == '.':
                    if dot_count == 1: break
                    dot_count += 1
                    number_string += '.'
                else:
                    Positon_start = Positon.copy()
                    number_string += self.current_Character
                    self.advance()
                    
        if dot_count == 0:
            return Token(TT_INT, int(number_string))
            else:
                return Token(TT_FLOAT, float(number_string))
                
                # Run
def Run(filename,text):
    Lexer = Lexer(filename,text)
    Tokens, Error = Lexer.make_tokens()
    
    return Tokens, Error