Hiç düşündünüz mü, Python 3 + 2 yazdiğımızda 5 olarak sonucu nasıl bize gösteriyor.
Yada yazdığımız kodlar nasil bir sıra halinde yürütülüyor.
Veya "8 + "yazdığımızda python nasıl bize Invalid syntax hatası veriyor.
Bazı arkadaşların, "Amaaan nasıl yapıyorsa yapıyor işte" dediğini duyar gibiyim. Bu arkadaşlar geri tuşuna basıp konudan ayrılabilirler. Nasıl yaptığını merak edenler ise okumaya devam etsinler.
"Derleyicilerin nasıl çalıştığını bilmiyorsanız, bilgisayarların nasıl çalıştığını bilmiyorsunuz.Derleyicilerin nasıl çalıştığını bildiğinizden % 100 emin değilseniz, nasıl çalıştığını bilmiyorsunuzdur. *- Steve Yegge
Interpreter(Yorumlayıcı) veya Compiler(Derleyici)'in amacı, bir kaynak programı bazı üst düzey dilde başka bir formata çevirmektir. Interpreter ile Compiler arasındakı fark ise ; Compilerler kaynak kodu makine diline çevirirken, Interpreter ise makine diline çevirmeden işlemleri yürütür.
Neden bir Interpreter(veya Compiler) yazayım ki? Cünkü:
* Bir interpreter(veya compiler) yazmak,birlikte kullanmaniz gereken cok fazla teknik bilgiye ve beceriye sahip olmaniz gerekir. Bir interpreter(veya compiler) yazmak, bu becerilerinizi gerliştireceği icin daha iyi bir yazılımcı olmanizi sağlar.
* Her seyin kontrolünü eline almak, bilgisayari anlamak için
* Kendi eşsiz programlama dilinizi oluşturmak için
interpreter(veya compilerin) yazmayı deneyebilirsiniz.
"Aman tanrım! Başlıkta Iler Seviye yazıyor. Kesin anlayamam" derseniz hata edersiniz. Aşağida yazilan bütün kodları Pyhton Nesne Tabanlı Programlamaya kadar geldim diyen herkez anlayabılır.
---- Hadi Başlayalım ----
Dilerseniz hesap makinesi olarak bilinen, aritmatik ifadelerin bir interpreter'ini yazarak başlayalim. Hedefimiz oldukça minimalist "4+8" gibi iki tane tek haneli tam sayının birbirine eklenmesini sağlamak.
Simdi bir Inperpreter classi yazalim.
Aslinda kodda herşeyi acikladim. Ama kısaca özetlemek gerekirse.
* Bir Token classi olusturduk bu class tip ve degerleri tutyor
* Interpreter in icindeki eat methodu bir nevi kontrol islemi yaptik eger gelen karakter istedigimiz tipte degilse hata mesajiyla uyariyor.
* expr ile solaki sayiyi, oparetoru ve sagdaki sayıyı buluyoruz ve topluyoruz.
* getNextToken() bir Lexerdır yani amacı gelen text deki bizim icin uygun parcalari ayirmaktir. Bu isleme "Sözcüksel Analiz" denir.
Yazdigimiz Lexer soyle çalisiyor.
Ayrica yazdığımız mukemmel Interpretrimizin doğru çalışması için bazı kurallara uyulması gerekir:
* Sadece tek haneli sayilarin yazilmasi gerekir.
* Sadece tek aritmatik islem yapabiliyor
* Ve aralarda boşluk olmayacak.
Diğer yazımda bunlarin cözümlerini yapacağız.
Eveeet. Bugünlük benden bu kadar. Sinavlarimdan vakit buldukça bu seriye devam edeceğim.
Kaynak:
https://ruslanspivak.com/
(Mukemmel bir blog. Okumanizi tavsiye ederim.)
Yada yazdığımız kodlar nasil bir sıra halinde yürütülüyor.
Veya "8 + "yazdığımızda python nasıl bize Invalid syntax hatası veriyor.
Bazı arkadaşların, "Amaaan nasıl yapıyorsa yapıyor işte" dediğini duyar gibiyim. Bu arkadaşlar geri tuşuna basıp konudan ayrılabilirler. Nasıl yaptığını merak edenler ise okumaya devam etsinler.
"Derleyicilerin nasıl çalıştığını bilmiyorsanız, bilgisayarların nasıl çalıştığını bilmiyorsunuz.Derleyicilerin nasıl çalıştığını bildiğinizden % 100 emin değilseniz, nasıl çalıştığını bilmiyorsunuzdur. *- Steve Yegge
Interpreter(Yorumlayıcı) veya Compiler(Derleyici)'in amacı, bir kaynak programı bazı üst düzey dilde başka bir formata çevirmektir. Interpreter ile Compiler arasındakı fark ise ; Compilerler kaynak kodu makine diline çevirirken, Interpreter ise makine diline çevirmeden işlemleri yürütür.
Neden bir Interpreter(veya Compiler) yazayım ki? Cünkü:
* Bir interpreter(veya compiler) yazmak,birlikte kullanmaniz gereken cok fazla teknik bilgiye ve beceriye sahip olmaniz gerekir. Bir interpreter(veya compiler) yazmak, bu becerilerinizi gerliştireceği icin daha iyi bir yazılımcı olmanizi sağlar.
* Her seyin kontrolünü eline almak, bilgisayari anlamak için
* Kendi eşsiz programlama dilinizi oluşturmak için
interpreter(veya compilerin) yazmayı deneyebilirsiniz.
"Aman tanrım! Başlıkta Iler Seviye yazıyor. Kesin anlayamam" derseniz hata edersiniz. Aşağida yazilan bütün kodları Pyhton Nesne Tabanlı Programlamaya kadar geldim diyen herkez anlayabılır.
---- Hadi Başlayalım ----
Dilerseniz hesap makinesi olarak bilinen, aritmatik ifadelerin bir interpreter'ini yazarak başlayalim. Hedefimiz oldukça minimalist "4+8" gibi iki tane tek haneli tam sayının birbirine eklenmesini sağlamak.
Kod:
[FONT="Courier New"][COLOR="WHITE"]
INTEGER, PLUS, EOF = 'INTEGER', 'PLUS', 'EOF'
#EOF: End Of File
#verilen ifadenin sonuna gelip gelmedigimizi kontrol edecegiz
[COLOR="CYAN"]class[/COLOR] Token(object):
"""
Her gecerli parcacik icin olusacak Token [COLOR="CYAN"]class[/COLOR]i
"""
[COLOR="CYAN"]def[/COLOR] __init__([COLOR="CYAN"]self[/COLOR], type, value):
## Tur: INTEGER, PLUS veya EOF
[COLOR="CYAN"]self[/COLOR].type = type
#Token degeri: 1,2,3,4,5,6... '+' gibi
[COLOR="CYAN"]self[/COLOR].value = value
[COLOR="CYAN"]def[/COLOR] __str__([COLOR="CYAN"]self[/COLOR]):
[COLOR="CYAN"]return [/COLOR]'Token(type = {}, value = {})'.[COLOR="CYAN"]for[/COLOR]mat([COLOR="CYAN"]self[/COLOR].type, [COLOR="CYAN"]self[/COLOR].value)
[COLOR="CYAN"]def[/COLOR] __str__([COLOR="CYAN"]self[/COLOR]):
[COLOR="CYAN"]return [/COLOR][COLOR="CYAN"]self[/COLOR].__str__()
[/COLOR][/FONT]
Simdi bir Inperpreter classi yazalim.
Kod:
[FONT="Courier New"][COLOR="WHITE"]
Kod:
[COLOR="CYAN"]class[/COLOR] Interpreter(object):
[COLOR="CYAN"]def[/COLOR] __init__([COLOR="CYAN"]self[/COLOR], text):
[COLOR="CYAN"]self[/COLOR].text = text #Gelen string
[COLOR="CYAN"]self[/COLOR].pos = 0 #Bir nevi imlec, karakterlein yerlerini belirlemek icin
[COLOR="CYAN"]self[/COLOR].current_token =[COLOR="ORANGE"] None [/COLOR] #token ornegi
[COLOR="CYAN"]def[/COLOR] error([COLOR="CYAN"]self[/COLOR]):
raise Exception('Error parsing input') #Eger hatali kullanim olursa
[COLOR="CYAN"]def[/COLOR] getNextToken([COLOR="CYAN"]self[/COLOR]):
"""
Lexer: bu kod verilen degerin ([COLOR="CYAN"]self[/COLOR].text)[COLOR="CYAN"] in [/COLOR]parcalanmasindan sorumludur.
Tokenlerine ayirir.
"""
text = [COLOR="CYAN"]self[/COLOR].text
#text[COLOR="CYAN"] in [/COLOR]sonuna geldiginde
# Token End of File i dondur
[COLOR="CYAN"]if [/COLOR][COLOR="CYAN"]self[/COLOR].pos > len(text) - 1:
[COLOR="CYAN"]return [/COLOR]Token(EOF, None)
#Su an hangi karakterle islem yapiyoruz [COLOR="CYAN"]self[/COLOR].pos a gore bul
current_char = text[[COLOR="CYAN"]self[/COLOR].pos]
#Eger suanki karalter bir sayi ise
#Integer tipli bir token olustur
#[COLOR="CYAN"]self[/COLOR].pos degerini 1 arttir ki diger karaktere gecebilsin
#sonra token nesnesini dondur
[COLOR="CYAN"]if [/COLOR]current_char.isdigit():
token = Token(INTEGER, int(current_char))
[COLOR="CYAN"]self[/COLOR].pos += 1
[COLOR="CYAN"]return [/COLOR]token
[COLOR="CYAN"]if [/COLOR]current_char == '+':
token = Token(PLUS, '+')
[COLOR="CYAN"]self[/COLOR].pos += 1
[COLOR="CYAN"]return [/COLOR]token
#hicbir kosula girmez ise
[COLOR="CYAN"]self[/COLOR].error()
[COLOR="CYAN"]def[/COLOR] eat([COLOR="CYAN"]self[/COLOR], token_type):
"""
Gecerli bir tip degeri (Integer, plus)ile gelen tip degerini karsilastir eger eslesirse tokeni 'ye' :) ve yeni tokeni esitle.
eger eslesmez ise hata mesaji goster.
"""
[COLOR="CYAN"]if [/COLOR][COLOR="CYAN"]self[/COLOR].current_token.type == token_type:
[COLOR="CYAN"]self[/COLOR].current_token = [COLOR="CYAN"]self[/COLOR].getNextToken()
else:
[COLOR="CYAN"]self[/COLOR].error()
[COLOR="CYAN"]def[/COLOR] expr([COLOR="CYAN"]self[/COLOR]):
#EXPR INTEGER -- PLUS -- INTEGER
#Ilk tokenimizi alalim
[COLOR="CYAN"]self[/COLOR].current_token = [COLOR="CYAN"]self[/COLOR].getNextToken()
#Gecerli tokenin tek haneli bir tamsayi olmasini bekliyoruz
left = [COLOR="CYAN"]self[/COLOR].current_token
[COLOR="CYAN"]self[/COLOR].eat(INTEGER)
#Tokenin + isareti olmasini bekliyoruz
op = [COLOR="CYAN"]self[/COLOR].current_token
[COLOR="CYAN"]self[/COLOR].eat(PLUS)
#Tokenin tamsayi olmasini bekliyoruz
right = [COLOR="CYAN"]self[/COLOR].current_token
[COLOR="CYAN"]self[/COLOR].eat(INTEGER)
#Son olarak iki tokenin value degerlerini topluyoruz.
[COLOR="CYAN"]return [/COLOR]left.value + right.value
[COLOR="CYAN"]def[/COLOR] main():
[COLOR="CYAN"]while[/COLOR] [COLOR="GREEN"]True[/COLOR]:
text = raw_input('Interpreter> ')
[COLOR="CYAN"]if [/COLOR]not text:
continue
interpreter = Interpreter(text)
result = interpreter.expr()
[COLOR="CYAN"]print[/COLOR] result
main()
[/COLOR][/FONT]
Aslinda kodda herşeyi acikladim. Ama kısaca özetlemek gerekirse.
* Bir Token classi olusturduk bu class tip ve degerleri tutyor
* Interpreter in icindeki eat methodu bir nevi kontrol islemi yaptik eger gelen karakter istedigimiz tipte degilse hata mesajiyla uyariyor.
* expr ile solaki sayiyi, oparetoru ve sagdaki sayıyı buluyoruz ve topluyoruz.
* getNextToken() bir Lexerdır yani amacı gelen text deki bizim icin uygun parcalari ayirmaktir. Bu isleme "Sözcüksel Analiz" denir.
Yazdigimiz Lexer soyle çalisiyor.
Ayrica yazdığımız mukemmel Interpretrimizin doğru çalışması için bazı kurallara uyulması gerekir:
* Sadece tek haneli sayilarin yazilmasi gerekir.
* Sadece tek aritmatik islem yapabiliyor
* Ve aralarda boşluk olmayacak.
Diğer yazımda bunlarin cözümlerini yapacağız.
Kod:
[FONT="Courier New"]Interpreter> 3+4
Token(type=INTEGER, value = 3)
Token(type=PLUS, value = '+')
Token(type=INTEGER, value = 4)
7
Interpreter> 3+5
Token(type=INTEGER, value = 3)
Token(type=PLUS,value = '+')
Token(type=INTEGER, value = 5)
8
Interpreter> 3+9
Token(type=INTEGER, value = 3)
Token(type=PLUS, value = '+')
Token(type=INTEGER, value = 9)
12
Interpreter>[/FONT]
Eveeet. Bugünlük benden bu kadar. Sinavlarimdan vakit buldukça bu seriye devam edeceğim.
Kaynak:
https://ruslanspivak.com/
(Mukemmel bir blog. Okumanizi tavsiye ederim.)
Son düzenleme: