21
Derleyici Teorisine Giriş Sözlüksel Çözümleme

Lexical Analysis

  • Upload
    roger

  • View
    50

  • Download
    0

Embed Size (px)

DESCRIPTION

Lexical Analysis. Derleyici Teorisine Giriş Sözlüksel Çözümleme. Programlama Dilleri Gerçekleştirimleri. Programlama dillerinin gerçekleştirimleri iki farklı yolla olabilir: - PowerPoint PPT Presentation

Citation preview

Page 1: Lexical Analysis

Derleyici Teorisine GirişSözlüksel Çözümleme

Page 2: Lexical Analysis

Programlama Dilleri GerçekleştirimleriProgramlama dillerinin gerçekleştirimleri iki

farklı yolla olabilir:Yorumlayıcılar (Interpreter) bir programın az

veya hiç ön işleme yapılmadan, platformdan bağımsız olarak çalıştırılmasını sağlar.

Derleyiciler (Compiler) programı yoğun bir ön işlemeden geçirir ve 2-20 kat arası daha hızlı çalışmayı sağlar. Platforma özgü kod üretirler.

Bazı dillerde bu iki yolun bir kombinasyonu kullanılır.

Page 3: Lexical Analysis

Derleyiciler TarihiÜzerinde assembly dili ile program yazılabilen

ilk bilgisayarlar 1950’lerde üretildiler. Ancak assembly ile hızlı kod yazımı ve büyük

projelerin geliştirilmesi çok uzun zaman alıyordu.

1953’te John Backus ilk yorumlayıcıyı üretti ancak bu assembly kodundan daha yavaş çalışıyordu.

1956’da Backus ve arkadaşları, FORTRAN dilinin ilk derleyicisini ürettiğinde ise hız sorunu aşılmış oldu.

Page 4: Lexical Analysis

Otomatik Çeviri Paradigması

anal

izüretim

Kaynak Dil

Hedef Dil

Ara Dil

transfer

doğrudan çeviri

Page 5: Lexical Analysis

Modern DerleyicilerGünümüzde derleyiciler de otomatik çeviri

paradigmasına uygun olarak geliştirilirler. Bu sebeple iki ana bileşenden oluşurlar:Analiz işlemleri için kullanılan ön uç (front end),

kaynak programlama dilini işler ve bundan bir ara gösterim elde eder.

Üretim aşaması ise arka uç (back end) bileşeninde kodun optimizasyonu ve hedef dile dönüştürülmesiyle gerçekleşir.

Hedef dil genelde assembly olur. Böylece yüksek seviye bir programlama dilinin makine düzeyine indirgenmesi sağlanır.

Page 6: Lexical Analysis

Bir Derleyicinin Yapısı

Hedef Dil

Semantic Analyzer

Syntax Analyzer

Lexical Analyzer

Ön Uç

Kod Optimizasyonu

Hedef Dil ÜreticisiArka Uç

Ara Kod Üreticisi

Ara Kod

Kaynak Dil

Page 7: Lexical Analysis

Derleme Örneği

Hedef Dil

Semantic Analyzer

Syntax Analyzer

Lexical Analyzer

Kod Optimizasyonu

Hedef Dil Üreticisi

Ara Kod Üreticisi

Ara Kod

Kaynak Dil Kaynak Dil:cur_time = start_time + cycles * 60

Lexical Analiz:ID(1) ASSIGN ID(2) ADD ID(3) MULT INT(60)

Sözdizim Analizi: ASSIGN

ID(1) ADD

ID(2) MULT

ID(3) INT(60)

Anlamsal Analiz: ASSIGN

ID(1) ADD

ID(2) MULT

ID(3) int2real

INT(60)

Page 8: Lexical Analysis

Derleme Örneği

Adım 1:temp1 = 60.0temp2 = id3 * temp1temp3 = id2 + temp2id1 = temp3

Adım 2:temp2 = id3 * 60.0temp3 = id2 + temp2id1 = temp3

Adım 3:temp2 = id3 * 60.0id1 = id2 + temp2

Optimize Edilmiş Kod:temp1 = id3 * 60.0id1 = id2 + temp1Hedef Dil:MOVF id3, R2MULF #60.0, R2MOVF id2, R1ADDF R2, R1MOVF R1, id1

Hedef Dil

Semantic Analyzer

Syntax Analyzer

Lexical Analyzer

Kod Optimizasyonu

Hedef Dil Üreticisi

Ara Kod Üreticisi

Ara Kod

Kaynak Dil Ara Kod:temp1 = int2real(60)temp2 = id3 * temp1temp3 = id2 + temp2id1 = temp3

Optimizasyon:

Page 9: Lexical Analysis

Lexical Analiz (1)if (i==j);

z=1;

else;

z=0;

endif;Yukarıdaki kod parçası bizim için anlamlı

ifadelerden oluşsa da bilgisayar için aşağıdaki gibi bir karakter katarından başka bir şey ifade etmez.i f _ ( i = = j ) ; \n \t z = 1 ;

\n e l s e ; \n \t z = 0 ; \n e n d i f ;

Page 10: Lexical Analysis

Lexical Analiz (2)Yüksek seviyeli bir dille yazılan kodun

çalıştırılabilmesi için en düşük seviyede bilgisayarın işleyebileceği komutlar dizisi haline getirilmesi gereklidir.

Bu sebeple kaynak kodu oluşturan karakter katarı anlamlı alt parçalara ayrıştırılmalıdır.

Alt parçalara token (belirtke), bunları ayrıştırma işlemine de lexical analiz denir.

Lexical analiz işleminin çıktısı olan tokenlar bir sonraki aşama olan sözdizimsel analiz bileşenine aktarılır.

Page 11: Lexical Analysis

Lexical Analiz (3)Token sözdizimsel bir kategori belirtir. Bu kategoriler doğal diller için “isim”, “sıfat”, “fiil” vb.

olabilirken, programlama dilleri için “matematiksel sembol” veya “anahtar kelime” gibi alt ifadeler olurlar.

Token belirten bir alt karakter katarı lexeme olarak adlandırılır.

Programlama dili içinde kullanılması mümkün olan tüm lexemeler tanımlanırken örüntüler (pattern) kullanılır.

Örüntüler düzenli ifadeler (regular expressions) kullanılarak tanımlanır.

Bu aşamada düzenli ifadelerin kullanılmasının sebebi işlenen karakter katarı içinde kabul edilebilir bir token bulabilmenin bazen geriye dönük arama da gerektirebilmesidir.

Page 12: Lexical Analysis

Lexical Analiz (4)Bir lexical analiz aracı şu 3 şeyi

yapabilmelidir:1. Bütün boşlukları ve açıklamaları temizlemeli,2. Karakter katarı içindeki tüm tokenlar

bulunmalı,3. Bulunan token için lexeme ve bulunduğu satır

numarası gibi özellikler döndürülmelidir.sum=3+2;

Lexeme Token sum IDENTIFIER = ASSIGN_OP 3 NUMBER + ADD_OP 2 NUMBER ; SEMICOLON

Page 13: Lexical Analysis

Düzenli İfadelerSonlu durum otomatları (FSA) ile

tanımlanabilen dilleri ifade etmede kullanılırlar.

Eğer A bir düzenli ifade ise, L(A) bu ifade ile tanımlanan dildir.

L(“if”|”then”|”else”) dili sadece “if”, “then” ve “else” ifadelerini tanıyabilen bir dil belirtir.

Lexical analiz işleminde tarayıcı (scanner), kaynak kodun içinde önceden düzenli ifadelerle tanımlanmış anahtar kelimeleri arar ve bunların token tiplerini belirler.

Page 14: Lexical Analysis

Düzenli İfadelerin TasarımıTanımladığımız düzenli ifadeler dil içerisindeki tüm

ifadeleri kapsamalıdır. Bu sebeple şu durumlar dikkate alınmalıdır:1. Bir düzenli ifade özel bir token tipinin tüm durumlarını

ifade etmelidir.2. Belirsizliği önlemek için en uzun olan eşleme seçilir.3. Eş uzunluklu belirsizlik durumlarında ilk eşleme seçilir.

n adet farklı token tipi olduğu varsayıldığında n farklı düzenli ifade kullanılmalıdır. Bir token tipini tanıyan düzenli ifade Rn ile gösterilirse, tüm tokenları tanıyan düzenli ifade topluluğu R şöyle ifade edilir:

R = R1 | R2 | … | Rn

Page 15: Lexical Analysis

Lex ve Yacc (1)Yapısal programlamada ortaya çıkan iki temel görev vardır:

1. Girdiyi anlamlı alt parçalara ayırmak2. Bu alt parçalar arasındaki ilişkiyi ortaya koymak

Düzenli ifadeler veya sonlu durum otomatları ilk aşama için yeterli düzeyde olsa da ikinci aşamada ortaya çıkabilecek özyinelemeli örüntüleri tanımlamak için yeterli güce sahip değildir. İkinci aşama için kullanılan ayrıştırıcı (parser) yığıt (stack) gibi yapılardan faydalanmalıdır.

Bu işlemleri otomatik olarak gerçekleştirmeye yarayan çeşitli araçlar vardır.

Lex, ilk aşamadaki token ayrıştırma işlemini düzenli ifadeler kullanarak gerçekleştirecek C veya C++ kodunu otomatik olarak üreten bir yazılımdır.

Yacc ise Lex tarafından üretilen çıktıyı alarak sözdizimsel kurallarla ayrıştırma işlemini gerçekleştirecek kodu üreten bir yazılımdır.

Bu iki yazılımın açık kaynak sürümleri flex ve bison’dır.

Page 16: Lexical Analysis

Lex ve Yacc (2)Lex içinde kullanılan düzenli ifadeler, Chomsky

hiyerarşisi içinde düzenli diller sınıfındadır.Yacc 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.

select_command ::= "select" [ "all" | "distinct" ] ( "*" | (

displayed_column { "," displayed_column } ) ) "from" ( selected_table { "," selected_table } ) [ “where" condition ] { connect_clause } {

group_clause } { set_clause } { order_clause } { update_clause }

Page 17: Lexical Analysis

Flex KullanımıLexical analizde kullanmak üzere bir tarayıcı

üretmek için öncelikle .lex uzantılı bir yapılandırma dosyası üretmek gerekir.

Bu dosya kullanılarak flex ile komut istemi üzerinden gerekli C veya C++ kodu üretilir. flex deneme.lex

Üretilen kod derlenerek lexical analiz işlemi yapılabilir.

gcc lex.yy.c –o main

Page 18: Lexical Analysis

Lex Program YapısıBütün lex programları yanyana iki % işareti

kullanılarak birbirinden ayrılan 3 bölümden oluşur.

Tanım (definition) bölümü: C kodunun üstünde olması istenen tüm kod buraya yazılır. Bütün kod “%{“ ile “%}” arasında yer almalıdır. Kullanılması zorunlu değildir.

Kurallar (rules) bölümü: Burada örüntüler ve bu örüntülerle karşılaşıldığında yapılacak işlemler tanımlanır.

Kullanıcı alt-programları (user sub-routines) bölümü: Lex oluşturduğu koda bu alt-programları kopyalar.

Page 19: Lexical Analysis

Örnek – 1 %%

[\t ]+ /* boşlukları atla*/;

Pazartesi|Salı|Çarşamba|Perşembe|Cuma

{ printf("%s hafta içi bir gündür.", yytext); }

Cumartesi|Pazar

{ printf("%s haftasonu bir gündür.", yytext); }

[a-zA-Z]+

{ printf("%s gün değildir.", yytext); }

%%

int yywrap(void) { return 1; }

int main(void)

{ yylex(); return 0; }

Page 20: Lexical Analysis

Örnek – 2%{

int line_num = 1;

%}

%%

[\t ]+ /* Boşlukları atla */;

\n { line_num++; }

[+-]?[0-9]+(\.[0-9]+)?([eE][+-]?[0-9]+)?

{printf(“satır no: %d \n", line_num);}

%%

int yywrap(void) { return 1; }

int main(void) {

yylex(); return 0;

}

Page 21: Lexical Analysis

ÖzetDerleyiciler yüksek seviye bir programlama dilini

düşük seviye bir dile dönüştürme işlemini gerçekleştirirler.

Bu dönüşüm işleminin ilk aşaması lexical analizdir.Lexical analiz işlemleri düzenli diller sınıfında bir dil

tanımlama aracı olan düzenli ifadeler ile yapılabilir.Düzenli ifadelerin tanımlarından oluşan bir kod

kullanılarak flex yazılımıyla gerekli C veya C++ kodu üretilebilir.

Lexical analiz işlemleri sonucunda belirlenen tokenlar derleyicinin sözdizim analizi yapan parçasına aktarılır.