- 16 Eki 2020
- 442
- 20
Herkese merhabalar dostlar yeni bir seri ile karşınızdayım bu seri ile Python programlama dilini kullanarak beraber programlama dili geliştireceğiz, başlayalım:
Kullanacağımız programlama dili:
- Python
Programlama dili nasıl yapılır?:
Şimdi kodları oluşturan yorumlayıcı veya derleyicilerdir.
Yorumlayıcı bir kaç kısımdan oluşur. Derleyici ile yorumlayıcı arasında pek çok fark yoktur. Derleyici kod üretir yorumlayıcı üretmez.
Kaynak Kod Lexer Parser
Yorumlayıcı sizin yazdığınız kaynak kodu alır ve Lexer kısmında (yani söz dizilimi) kısmında işleme sokar, lexer kuralları oluşturur ve sizin oluşturduğunuz kurallara göre kodu parçalara böler, eğer kurallar aşılırsa hata verdirilir.
Lexer'de işlem bittikten sonra oluşturulan token'ler parser kısmında yeniden işleme sokulur ve parser ile kodlar ağaç yapısı şeklinde gruplara bölünür.
Yorumlayıcı bir kaç kısımdan oluşur. Derleyici ile yorumlayıcı arasında pek çok fark yoktur. Derleyici kod üretir yorumlayıcı üretmez.
Kaynak Kod Lexer Parser
Yorumlayıcı sizin yazdığınız kaynak kodu alır ve Lexer kısmında (yani söz dizilimi) kısmında işleme sokar, lexer kuralları oluşturur ve sizin oluşturduğunuz kurallara göre kodu parçalara böler, eğer kurallar aşılırsa hata verdirilir.
Lexer'de işlem bittikten sonra oluşturulan token'ler parser kısmında yeniden işleme sokulur ve parser ile kodlar ağaç yapısı şeklinde gruplara bölünür.
Dilimizi yapmaya başlayalım:
İlk önce shell.py adında bir dosya oluşturalım dilimizin komut satırı burası olucak, içerisine şu komutları yazalım:
Kod:
# kod aktarımı
import basic
while True:
text = input('>> ')
# hatalar
result, error = basic.run('<stdin>', text)
if error: print(error.as_string())
else: print(result)
Şimdi lexer yazarak başlayalım:
Kod:
# Constants
DIGITS = '0123456789'
# Hatalar
class Error:
def __init__(self, pos_start, pos_end, error_name, details):
self.pos_start = pos_start
self.pos_end = pos_end
self.error_name = error_name
self.details = details
def as_string(self):
result = f'{self.error_name}: {self.details}\n'
result += f'File {self.pos_start.fn}, line {self.pos_start.ln + 1}'
return result
class IllegalCharError(Error):
def __init__(self, pos_start, pos_end, details):
super().__init__(pos_start, pos_end, 'Illegal Character', details)
# Pozisyon
class Position:
def __init__(self, idx, ln, col, fn, ftxt):
self.idx = idx
self.ln = ln
self.col = col
self.fn = fn
self.ftxt = ftxt
def advance(self, current_char):
self.idx += 1
self.col += 1
if current_char == '\n':
self.ln += 1
self.col = 0
return self
def copy(self):
return Position(self.idx, self.ln, self.col, self.fn, self.ftxt)
# Tokenler
TT_INT = 'INT'
TT_FLOAT = 'FLOAT'
TT_PLUS = 'PLUS'
TT_MINUS = 'MINUS'
TT_MUL = 'MUL'
TT_DIV = 'DIV'
TT_LPAREN = 'LPAREN'
TT_RPAREN = 'RPAREN'
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, fn, text):
self.fn = fn
self.text = text
self.pos = Position(-1, 0, -1, fn, text)
self.current_char = None
self.advance()
def advance(self):
self.pos.advance(self.current_char)
self.current_char = self.text[self.pos.idx] if self.pos.idx < len(self.text) else None
def make_tokens(self):
tokens = []
while self.current_char != None:
if self.current_char in ' \t':
self.advance()
elif self.current_char in DIGITS:
tokens.append(self.make_number())
elif self.current_char == '+':
tokens.append(Token(TT_PLUS))
self.advance()
elif self.current_char == '-':
tokens.append(Token(TT_MINUS))
self.advance()
elif self.current_char == '*':
tokens.append(Token(TT_MUL))
self.advance()
elif self.current_char == '/':
tokens.append(Token(TT_DIV))
self.advance()
elif self.current_char == '(':
tokens.append(Token(TT_LPAREN))
self.advance()
elif self.current_char == ')':
tokens.append(Token(TT_RPAREN))
self.advance()
else:
pos_start = self.pos.copy()
char = self.current_char
self.advance()
return [], IllegalCharError(pos_start, self.pos, "'" + char + "'")
return tokens, None
def make_number(self):
num_str = ''
dot_count = 0
while self.current_char != None and self.current_char in DIGITS + '.':
if self.current_char == '.':
if dot_count == 1: break
dot_count += 1
num_str += '.'
else:
num_str += self.current_char
self.advance()
if dot_count == 0:
return Token(TT_INT, int(num_str))
else:
return Token(TT_FLOAT, float(num_str))
# Çalıştır
def run(fn, text):
lexer = Lexer(fn, text)
tokens, error = lexer.make_tokens()
return tokens, error
Bugün ne yaptık?
Programlama dilimizin lexerini hazırladık. Bugünlük bu kadardı, Hayırlı günler.
GitHub: https://github.com/mikisoft/lang
Moderatör tarafında düzenlendi: