Ders içeriği kapsamında işlenecek konular

  • Derleyicinin Yapısı (Compiler) nedir?
  • Sözdizimi Analizi (Lexical Analysis)
  • Kurallı İfadeler (Regular Expression)
  • Sonlu Otomat (Finite Automata-FA)
  • Sentaks Analizi (Syntax Analysis)
  • Belirsizlik (Ambiguity)
  • Ayrıştırma (Parsing)
  • Tip Kontrolü
  • Ara kod üretimi (Intermediate Code)
  • İyileştirme (Optimizations)
  • Hedef Dil

Kaynaklar

  • Dick Grune, Keesvan Reeuwijk, Henri E. Bal, Ceriel J.H. Jacobs, and Koen G. Langendoen (2012). Modern Compiler Design -Second Edition
  • Alfred V. Aho, Monica S. Lam, Jeffrey D. Ullman, Ravi Sethi(2011). Compilers: Principles, Techniques, and Tools. Pearson Education, Inc. ISBN 0-201-10088-6, ISBN 0-321-48681-1
  • Torben Ægidius Mogensen (2008). Basics of Compiler Design. Department of Computer Science University of Copenhagen.
  • Andrew W. Appel(2004). Modern Compiler Implementation in C.

Bilgisayarlar sadece düşük seviyeli dillerde yazılmış kodu çalıştırabilir. Yüksek seviyeli dillerde yazılmış kodlar çalıştırılmadan önce düşük seviyeli dile çevrilmelidir. Bu çevirme işleminin biraz zaman alsa da sunduğu avantajlar oldukça fazladır.

Yüksek seviyeleri dillerde daha hızlı ve kolay bir şekilde kodlama yapılabilir. Yazılan kod daha okunaklıdır. Farklı ortamlar herhangi bir değişiklik yapmadan ya da çok az bir değişiklikle kullanılabilir. Düşük seviyeleri dillerde ise bir mimaride çalışan kod öteki mimaride çalışması için tekrardan yazılmalıdır.

Düşük Seviyeli Diller

Makine Dili

  • Verilen komutlar direk olarak işlemcide çalıştırılır.
  • Komutlar 0 ve 1’lerden oluşur.
  • En alt düzey programlama dilidir.

Avantajları:

  • En dip noktadır. Herhangi bir çeviriciye ihtiyaç duymaz.
  • Teorik olarak yazılabilecek en hızlı koddur (çünkü direk cpu üzerinde çalışacak en temel komutları yazıyoruz).

Dezavantajları:

  • Kodlanması çok yavaştır.
  • Yazılan kodların okunması ve anlaşılması çok zordur. Hataya açıktır.
  • Kodlayan kişinin bilgisayar mimarisi hakkında detaylı bilgiye sahip olması gerekir.
  • Donanıma bağlıdır. Farklı donanımda çalışmayacaktır.

Makina dilleri daha kolay okunabilir olması için 16’lık sayı sisteminde yazılır fakat sonra 2’lik sisteme çevrilir.

Assembly Dili

Makine dili, daha kolay anlaşılabilecek sembollerle ifade edilir. Günümüzde kullanılmaktadır. Hızlıdır ve daha az depolama alanı gerektirir lakin kullanımı zordur, zaman alır.

Orta Seviye Diller

Düşük seviyeli diller ile yüksek seviyeli diller arasında kalır. Makine dilinden, yüksek seviyeli dillere göre daha az uzak olan dillerdir. Bu diller hem yüksek seviyeli dillerin hem düşük seviyeli dillerin özelliklerini barındırabilir. C, C++, C#, Java gibi diller (günümüzde) orta seviyeli dillere örnek verilebilir.

// C++ kod ornegi
#include <iostream>
using namespace std;

int main(){
    cout<<"Hello there!"<<endl;
    return 0;
}

Yüksek Seviyeli Diller

Daha alt seviyeli dillerde birden fazla komutla yapılan işler tek komuta indirgenmiştir. Öğrenmesi daha kolay ve yazması daha pratiktir. Fortran (!), Basic, Pascal … gibi dilleri yüksek seviyelir dillere örnek verebiliriz.

program merhaba (output);
begin 
    WriteLn('merhaba, dünya');
end

Çok Yüksek Seviyeli Diller.

İnsan diline en yakın programlama dilleridir. Kullanması ve öğrenmesi en kolay dillerdir. Yapılabilecek işler biraz daha kısıtlıdır(?). Visual Basic, Access, VB.NET … diller örnek verilebilir.

Private Sub Button1_Clicked() Handles Button1.xClick
     MsgBox("Merhaba, Dünya")
End Sub

Dil çevirici (translator) nedir?

Kaynak dillerdeki programı hedef dile dönüştüren programa translator (çevirici) diyoruz. Eğer bu çeviri yüksek seviyeden düşük seviyya yapılmışsa bu çevirici programa compiler (derleyici) denmektedir.

Çeviri işleminin iki temel yöntemi vardır:

  • Derleme (compilation)
  • Yorumlama (interpretation)

Derleme (Compilation)

Programcılıkta, bir programlama dilinde yazılmış olan kaynak kodunu başka bir dile (genellikle makine koduna) çeviren yazılım. Derleyiciye bunu yaptırmaktaki amaç genellikle çalışabilir bir yazılım elde etmektir. Kullanıcıların programları kullanırken kolaylık sağlamak amaçlı geliştirilmiştir.

Derleyici programı derlerken kaynak koddaki hataları bulmalıdır. Derleyici, üretilen kodun verimliliği için çeşitli optimizasyon işlemleri yapabilir.


Singlepass – Multipass

Tek geçişli ve çok geçişli derleyici arasındaki temel fark, tek geçişli bir derleyicinin kaynak kodunu her derleme biriminden yalnızca bir kez geçiren bir derleyici olması, çok geçişli bir derleyici ise derlemeyi birden çok geçişe ayırır, burada her geçiş bir öncekinin sonucuyla devam eder.

https://www.geeksforgeeks.org/single-pass-two-pass-and-multi-pass-compilers/


Linker

To understand linkers, it helps to first understand what happens “under the hood” when you convert a source file (such as a C or C++ file) into an executable file (an executable file is a file that can be executed on your machine or someone else’s machine running the same machine architecture).

Under the hood, when a program is compiled, the compiler converts the source file into object byte code. This byte code (sometimes called object code) is mnemonic instructions that only your computer architecture understands. Traditionally, these files have an .OBJ extension.

After the object file is created, the linker comes into play. More often than not, a real program that does anything useful will need to reference other files. In C, for example, a simple program to print your name to the screen would consist of:

printf("Hello Kristina!\n");

When the compiler compiled your program into an obj file, it simply puts a reference to the printf function. The linker resolves this reference. Most programming languages have a standard library of routines to cover the basic stuff expected from that language. The linker links your OBJ file with this standard library. The linker can also link your OBJ file with other OBJ files. You can create other OBJ files that have functions that can be called by another OBJ file. The linker works almost like a word processor’s copy and paste. It “copies” out all the necessary functions that your program references and creates a single executable. Sometimes other libraries that are copied out are dependent on yet other OBJ or library files. Sometimes a linker has to get pretty recursive to do its job.

Note that not all operating systems create a single executable. Windows, for example, uses DLLs that keep all these functions together in a single file. This reduces the size of your executable, but makes your executable dependent on these specific DLLs. DOS used to use things called Overlays (.OVL files). This had many purposes, but one was to keep commonly used functions together in 1 file (another purpose it served, in case you’re wondering, was to be able to fit large programs into memory. DOS has a limitation in memory and overlays could be “unloaded” from memory and other overlays could be “loaded” on top of that memory, hence the name, “overlays”). Linux has shared libraries, which is basically the same idea as DLLs (hard core Linux guys I know would tell me there are MANY BIG differences).

Hope this helps you understand!

https://stackoverflow.com/questions/3322911/what-do-linkers-do


Interpreter

In basic terms the difference between an interpreter and a compiler is the point at which a source text is actually executed.

An interpreter interprets a language by reading the text or source code and then performing computations as it processes the text to execute the text. So as the interpreter is reading the source of the program, the program runs or executes as the interpreter reads lines of code and performs those actions.

A compiler compiles a language by reading the text or source and transforms the source code into another form which is typically machine code.

To make things a bit more complicated you will see that some interpreters have a Just In Time (JIT) compiler component to them. So the process then is the interpreter reads the source code and converts it to an intermediate, more machine friendly, form which is then fed to a JIT compiler which creates a machine code which is then executed by the target hardware. Most interpreters of this form have a Virtual Machine which is hardware independent that uses a JIT compiler to target the actual hardware when the program is executing. The Virtual Machine is hardware independent but the JIT compiler must be tailored to the particular hardware. The JIT compiler compiles the Virtual Machine code or instructions into the target hardware machine code which is then executed by the hardware.

And by the way this kind of Virtual Machine is different from the virtual machine used with Docker and other types of containers which has hardware virtual machine support. The Virtual Machine used by these interpreters is an application which emulates some abstract hardware.

For examples of this kind of Virtual Machine look to the Java Virtual Machine. Or the Python Virtual Machine. See Java “Virtual Machine” vs. Python “Interpreter” parlance? .

And this document, Python (2.5) Virtual Machine: a guided tour has some of the gritty details about the Python Virtual Machine though an older version of Python.

A compiler will normally compile the source text to actual hardware machine language. So the output of a compiler depends on the actual target hardware. The machine code of a compiler that targets an x86 architecture is different from one that targets an ARM architecture.

Using a compiler will require additional software tools as the process for a compiler is generally something like the following:

  • create the source code file or files
  • compile the source code file or files to generate one or more object code files
  • link the object code files with various libraries to generate an executable
  • run the executable application

Using an interpreter will be a simpler procedure something like the following:

  • create the source code file or files
  • execute the interpreter program, specifying the source code file

The C programming language is normally a compiled language using a compiler. The python programming language is normally an interpreted language using an interpreter.

However there is nothing to stop someone from writing a compiler for what is normally an interpreted language nor writing an interpreter for what is normally a compiled language. And you can see examples of this all over the internet.

To make things even a bit more complicated in the naming of things, there are applications called compilers that translates one programming language into another.

A classic example is the first C++ compilers which would transform C++ source code into C source code and then compile the C source code into machine language. It’s not done like that anymore and the C++ language was a subset of modern C++ (C++11/17) but it worked for a proof of concept.

I have also seen a translator that would transform C source code into JavaScript.

https://cs.stackexchange.com/questions/84970/the-difference-between-compiler-and-interpreter


Basit Bir Derleyici Yapısı

Bir derleyici temelde

  • Lexical Analyzer
  • Syntxa Analyzer
  • Context handler

bloklarından oluşur bu bloklar front-end olarak adlandırılır.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *