Derleyici Teorisine Giriş Sözdizim Analizi Derleyici Teorisine Giriş
Otomatik Çeviri Paradigması Ara Dil transfer analiz üretim doğrudan çeviri Kaynak Dil Hedef Dil
Analiz Yapısal programlamada ortaya çıkan iki temel görev vardır: Girdiyi anlamlı alt parçalara ayırmak Bu alt parçalar arasındaki ilişkiyi ortaya koymak Flex içinde kullanılan düzenli ifadeler, Chomsky hiyerarşisi içinde düzenli diller sınıfındadır. Bison ise ayrıştırma işlemi için Backus – Naur Form (BNF) adı verilen ve Chomsky hiyerarşisi içinde Bağlam Bağımsız Diller (Context-Free) sınıfında olan bir gösterim kullanmaktadır.
Ayrıştırıcı (Parser) CFG (G) Ayrıştırıcı L(G), s’yi kabul eder ve ağacı bulur. Token dizisi (s) Hata mesajları Ayrıştırıcı, bir CFG ve token dizisini girdi olarak alır, dizi CFG kurallarına uygunsa kabul eder ve çıktısını bir veri yapısı (ayrıştırma ağacı veya soyut sözdizim ağacı) olarak verir. Dizi CFG’ye uygun değilse hata mesajı döndürür. Her bir token görüldüğünde tek bir seçim yapılacak şekilde bir gramer geliştirilmelidir.
Derleyicinin Yapısı Ön Uç Arka Uç Kaynak Dil Lexical Analyzer Syntax Analyzer Ön Uç Semantic Analyzer Ara Kod Üreticisi Ara Kod Kod Optimizasyonu Arka Uç Hedef Dil Üreticisi Hedef Dil
Sözlüksel Analiz position := initial + rate * 60 [ \t\n]* → boşluk [a-z][A-zA-Z0-9]* → identifier [0-9]+ → number
Sözdizim Analizi Hedef: Elimizdeki tokenlardan oluşan listenin dilin sözdizimine uygun olup olmadığını belirlemek. Sözlüksel analiz için düzenli ifadeleri kullanan lex’ten faydalandık. Düzenli dillerin çözebildiği yapıların karmaşıklığı sınırlı olduğu için sözdizim analizinde kullanılmaya yetmez. {{} {} {{} { }}} { } . . .
Bağlam-Bağımsız Gramerler (CFG) CFG’ler birçok programlama dilini tanımada yeterlidir. 4 temel bileşenden oluşurlar: Terminal semboller (a, b) Terminal olmayan semboller (T) Başlangıç sembolü (S) Üretim kuralları Karşılıklı parantezleri tanıyan bir CFG şöyledir: S ( S ) S S 1 terminal olmayan: S 2 terminal: “(”, “)” Başlangıç sembolü: S 2 üretim kuralı S a S a S T T b T b T
Sözdizim Analizi Expression → identifier Expression → number Expression → Expression "+" Expression Expression → Expression "*" Expression Expression → "(" Expression ")“ Statement → identifier ":=" Expression
Tanıma (2 - 1) + 1 Open Int Op Int Close Op Int 1) Start Expr 2) Expr Expr Op Expr 3) Expr Int 4) Expr Open Expr Close (2 - 1) + 1 Open Int Op Int Close Op Int Open Expr Op Expr Close Op Expr Open Expr Close Op Expr Expr Op Expr Expr Start
Üretim Start Expr Expr Op Expr Open Expr Close Op Expr 3) Expr Int 4) Expr Open Expr Close Start Expr Expr Op Expr Open Expr Close Int Expr Op Expr Int Int Start Expr Expr Op Expr Open Expr Close Op Expr Open Expr Op Expr Close Op Expr Open Int Op Int Close Op Int (2 - 1) + 1
Bison Kod yapısı %{ C tanımlamaları (tipler, değişkenler, fonksiyonlar, önişlemci komutları) %} Bison belirtimleri (gramer sembolleri, operator öncelik tanımları, vb.) %% Gramer kuralları Ek C kodları
Örnek Lex Kodu %{ #include "prog0-parser.h" %} %% [0-9]+ { return NUMBER; } [ \t] ; /*boşlukları atla*/ \n return 0; /*mantıksal EOF*/ . return yytext[0]; /*Bilinmeyen karakter*/
Örnek Bison Kodu %{ #include <iostream> using namespace std; void yyerror(char * err_string) { cerr << “Girdi eşleşmedi!" << endl; } extern int yylex(); %} %token NUMBER %% num_entry: NUMBER {cout << “Sayı buldum!" << endl;}; main() { yyparse(); }
Komutlar bison -d calc.y flex calc.l gcc calc.tab.c lex.yy.c –o calculator