Merhaba sevgili okurlar. Bu ay biraz gecikmeli olsa da yine dopdolu içeriğimizle karşınızdayız.
Geçen ay derleyicilerin yapısına giriş yapmış ve derleyicinin kısımlarını ayrı ayrı ele almaya başlamıştık. Bu ay kaldığımız yerden devam edeceğiz. Sözcüksel analiz aşamasından sonra söz dizimsel analiz aşaması işlev kazanır. Bu aşamada, parser denilen derleyici parçası görev yapar.
Söz Dizimsel Analiz (Syntax Analysis)
Parser, lexerın oluşturduğu token listesini alır ve bir ağaç yapısı üretir. Bu oluşturulan ağaca "parse ağacı" denir. Token listesinden oluşturulmuş olan parse ağacı yine tokenlerden oluşmuş bir yapıdır ve derleyicinin tanıdığı gramere göre oluşturulur. Parser, ağacı oluştururken gramere uygun olmayan bir token ile karşılaşırsa bunu hata olarak bildirir. Parserın ürettiği bu hataya "gramer hatası" ya da "parse hatası (parse error)" denir.
Resim 1: Parse ağacının yapısı
Parser,
- Token içinde bulunan ve tokenin ifade ettiği metin ile uğraşmaz.
- Tokenin karakter katarında hangi pozisyonda bulunduğu ile ilgilenmez.
- Lexer gibi tokenin ifade ettiği anlam ile uğraşmaz.
Parser, yalnızca token listesinin dizilişine göre gramere uygunluğu kontrol eder. Bunun sonucunda da bu token listesinden oluşan bir parse ağacı üretir.
Bir dilin söz dizimi Bağlamdan Bağımsız Dil Bilgisi (Context Free Grammar - CFG) ile belirlenir. CFG'de belirlenen kurallar genellikle özyinelemelidir. (recursive)
Söz dizimsel analizde, verilen bir programın CFG tarafından belirtilen kurallara uyup uymadığı kontrol edilir. Eğer uyuyorsa bu program için bir ayrıştırma ağacı oluşturulur.
Örnek: CFG, BNF (Back Naur Form) kullanılarak yazılır:
assignmnet -> identifier := expression
expression -> identifier
expression -> number
expression -> expression + expression
Ayrıştırma ağacının oluşturulmasına bağlı olarak farklı ayrıştırma teknikleri bulunmaktadır.
Ayrıştırma teknikleri iki grupta toplanabilir:
- Yukarıdan Aşağıya Ayrıştırma (Top - Down Parsing)
- Aşağıdan Yukarıya Ayrıştırma (Bottom - Up Parsing)
Yukarıdan Aşağıya Ayrıştırma
Ayrıştırma ağacının yapısı kökten başlar ve yapraklara doğru ilerler. Etkin yukarıdan aşağıya ayrıştırıcılar kolaylıkla çizilebilir.
Aşağıdan Yukarıya Ayrıştırma
Ayrıştırma ağacının yapısı yapraklardan başlar ve köke doğru ilerler. Etkin aşağıdan yukarıya ayrıştırıcılar bir yazılım aracı ile oluşturulabilirler.
|
|
| Resim 2: Lexer ve parser işleyişi |
Anlamsal Analiz (Semantic Analysis)
Parse ağacı oluştuktan sonra bu ağaç, semantik analize (semantic analysis) tabi tutulur. Ağacın her yaprağında bulunan tokenler, bu aşamada derleyici için bir anlam ifade etmeye başlar. Örneğin; derleyici tarafından integer olan bir tokene integer, değişken olan tokene ise değişken olarak anlam verilir. Bunun sonucunda anlam olarak belli hatalar oluşabilir. Bu aşamada oluşabilecek hatalara "semantik hatalar (semantic errors)" denir. Örneğin; integer olan bir değişken, string olan bir değişkene direkt olarak eşitlenemez çünkü bunların token tipleri farklıdır.
Bu aşamada, kaynak programdaki anlamsal hatalar kontrol edilir ve kod üretimi için veri tipi bilgileri belirlenir. Tip kontrolü anlamsal analizin en önemli kısmıdır. Anlamsal bilgi, bağlamdan bağımsız dil ile gösterilmez. Söz dizimsel analizde kullanılan CFG, anlamsal kurallar ile birleştirilir.
Örnek:
newval := oldval + 12
newval verisinin tipi (oldval+12) ifadesinin tipi ile uyum göstermektedir.
İngilizcede Anlamsal Analiz
Örnek:
Jack said Jerry left his assignment at home.
Burada "his" kimin için kullanılmıştır? Jack mi, Jerry mi?
Daha kötüsü:
Jack said Jack left his assignment at home.
Bu durumda kaç tane Jack vardır? Hangisi ödevini evde bırakmıştır?
Programlamada Anlamsal Analiz
Programlama dilleri bu tür belirsizlikleri önlemek için katı kurallar tanımlarlar.
Bu C++ kodunun çıktısı "4" olur; en içteki tanımlama kullanılmıştır.
Derleyiciler, değişken bağlamanın (variable bindings) yanında pek çok anlamsal kontrol de yaparlar.
Örnek:
Jack left her homework at home.
Tip uyuşmazlığı (type mismatch): Her ve Jack arasında; bu iki sözcük farklı kişilerden bahsediyor olmalı, Jack muhtemelen erkek olmalı.
Orta Düzey Kod Üretimi
Semantik analiz sonucunda herhangi bir hata oluşmamış ise parse ağacı yardımı ile "intermediate code" ya da "intermediate representation" denilen ara bir kod oluşturulur. Bu ara kod oluşturulduktan sonra kodlar optimize edilir ve tekrar son çıktı için kod üretilir. Bu safha her derleyicide bulunmayabilir. Bazı derleyiciler ara kod oluşturmadan direkt olarak kod oluşturabilir.
Derleyiciler kaynak programı temsil eden açık orta düzey kod üretebilirler. Bu orta düzey kodlar genellikle bilgisayar mimarisinden bağımsızdır. Ancak bu kodların seviyesi makine kodu seviyesine yakındır.
Örnek:
newval := oldval * fact + 1
id1 := id2 * id3 + 1
MULT id2, id3, temp1
ADD temp1, #1, temp2
MOV temp2, id1
Kod Optimizasyonu
İngilizce için tam karşılığı olmamakla birlikte redaksiyona (editing) benzemektedir.
Programları otomatik olarak değiştirerek
- - Daha hızlı çalışmasını
- - Daha az bellek kaplamasını
- - Genel olarak kaynak kullanımında tutumlu davranmayı sağlamaktadır.
Örnek:
MULT id2, id3, temp1
ADD temp1, #1, id1
Kod Üretimi
İstenen mimaride hedef dili üretebilir. Genelde assembly kodu üretir. Bu daha sonra assembler
(çevirici, toplayıcı) tarafından çalıştırılabilir koda çevrilir.
Başka bir dile çeviri şeklinde de olabilir. Bu, insanların yaptığı çeviriyle özdeşlelştirilebilir.
Resim 3: Derleyici işleyiş diyagramı
Bu işlemlerden bizi en çok zorlayan kısım lexer ve parser kısımlarıdır çünkü bu parçalar, programlama dilinin gramerini ifade eden, tanımlanmasında hata kabul etmeyen, iş yükü çok olan parçalardır. Bu zorluklardan dolayı birçok "derleyici derleyicisi" denilen yardımcı programlar geliştirilmiştir.
Optimizasyonu her zaman kullanmak gerekli değildir. Ancak:
- Bilimsel programlarda
- İleri işlemcilerde (DSP - Digital Signal Processors)
- Küçük cihazlarda (hız = daha uzun pil ömrü) gerekebilir.
Kodun güvenilirliğini artırmak için derlemede ele alınan konular:
- Bellek güvenliği
- Uyumluluk sorunlarını (concurrency errors) tespit etmek.
Derleyici tasarımında kullanan teknikler, bir derleyicinin geliştirilmesine ek olarak, bilgisayar biliminde birçok probleme de uygulanabilir.
- Sözcüksel analiz için kullanılan teknikler, metin düzenleyici, bilgi elde etme (information retrieval), örüntü tanıma programları için de kullanılabilir.
- Ayrıştırmada kullanılan teknikler SQL gibi sorgu işleme sistemlerinde kullanılabilir.
- Derleyici tasarımında kullanılan tekniklerin birçoğu Doğal Dil İşleme (Natural Language Processing) sistemlerinde kullanılabilir.
Günümüzde derleyicilere daha çok ihtiyaç duyulmakta ve daha karmaşıklaşmaktadırlar. Yeni diller ve yeni mimariler arasındaki farklılıklara bağımlı olarak gelişmektedirler. Önemle çalışılan ve sağlıklı bir gelişim sergileyen, geliştirilen bir alandır.