it-swarm.asia

Kendi programlama dilimi ve bunun için bir derleyiciyi nasıl oluştururum

Programlama konusunda titizim ve BASIC, FORTRAN, COBOL, LISP, LOGO, Java, C++, C, MATLAB, Mathematica, Python, Ruby, Perl, JavaScript, Assembly ve benzeri dillerle karşılaştım. İnsanların nasıl programlama dilleri oluşturduğunu ve bunun için derleyicileri nasıl geliştirdiğini anlayamıyorum. İnsanların Windows, Mac, UNIX, DOS ve benzeri işletim sistemlerini nasıl oluşturduklarını da anlayamadım. Benim için gizemli olan bir diğer şey de insanların OpenGL, OpenCL, OpenCV, Cocoa, MFC ve benzeri kütüphaneleri nasıl oluşturdukları. Anlayamadığım son şey, bilim adamlarının bir mikroişlemci için nasıl bir Montaj dili ve bir montajcı geliştirdiğidir. Tüm bunları öğrenmek istiyorum ve 15 yaşındayım. Her zaman Babbage, Turing, Shannon veya Dennis Ritchie gibi bir bilgisayar bilimcisi olmak istedim.


Aho'nun Derleyici Tasarımı ve Tanenbaum'un OS konseptleri kitabını zaten okudum ve hepsi sadece kavramları ve kodları üst düzeyde tartışıyor. Ayrıntılara ve nüanslara ve bir derleyici veya işletim sisteminin nasıl tasarlanacağına girmezler. Sadece bir iş parçacığının, semaforun, işlemin veya ayrıştırmanın ne olduğunu anlamak için değil, kendim de bir tane oluşturabilmek için somut bir anlayış istiyorum. Kardeşime bütün bunları sordum. EECS'de MIT) 'da bir SB öğrencisidir ve tüm bu şeyleri gerçek dünyada nasıl yaratacağına dair bir fikri yoktur. Tek bildiği sadece Derleyici Tasarımı ve İşletim Sistemi hakkında bir anlayıştır. bahsettikleriniz gibi kavramlar (örneğin, Konu, Senkronizasyon, Eşzamanlılık, bellek yönetimi, Sözcük Analizi, Ara kod üretimi vb.)

427
Dave

Temel olarak, sorunuz "bilgisayar çipleri, talimat setleri, işletim sistemleri, diller, kütüphaneler ve uygulamalar nasıl tasarlanıyor ve uygulanıyor?" Bu, dünya çapında milyonlarca insanın istihdam ettiği ve çoğu uzman olan milyarlarca dolarlık bir endüstri. Sorunuza biraz daha odaklanmak isteyebilirsiniz.

Dedi ki, ben bir çatlak alabilir:

İnsanların nasıl programlama dilleri oluşturduğunu ve bunun için derleyicileri nasıl geliştirdiğini anlayamıyorum.

Benim için şaşırtıcı, ama birçok insan programlama dillerini büyülü olarak görüyor. Partilerdeki insanlarla tanıştığımda ya da her neyse, bana ne yaptığımı sorarlarsa, onlara programlama dilleri tasarladığımı ve derleyicileri ve araçları uyguladığımı söylerim ve insanların - profesyonel programcılar, aklınızda - kaç kez olduğunu söylemek şaşırtıcıdır. "vay, bunu hiç düşünmedim, ama evet, birileri bu şeyleri tasarlamak zorunda". Dillerin çevrelerindeki araç altyapıları ile tamamen oluştuğunu düşündükleri gibi.

Sadece görünmezler. Diller diğer tüm ürünler gibi tasarlanmıştır: rakip olasılıklar arasında bir dizi ödünleşimi dikkatle yaparak. Derleyiciler ve araçlar, diğer herhangi bir profesyonel yazılım ürünü gibi inşa edilmiştir: sorunu çözerek, her seferinde bir kod satırı yazarak ve ardından ortaya çıkan programın testini test ederek.

Dil tasarımı büyük bir konudur. Bir dil tasarlamakla ilgileniyorsanız, başlamak için iyi bir yer, zaten bildiğiniz bir dilde eksikliklerin ne olduğunu düşünmektir. Tasarım kararları genellikle başka bir üründe bir tasarım hatası dikkate alındığında ortaya çıkar.

Alternatif olarak, ilgilendiğiniz bir etki alanını düşünün ve ardından o etki alanındaki sorunların çözümlerini belirten etki alanına özgü bir dil (DSL) tasarlayın. LOGO'dan bahsettiniz; bu, "çizgi çizme" alanı için bir DSL örneğidir. Normal ifadeler, "dizede bir model bul" alanı için bir DSL'dir. C #/VB'deki LINQ, "filtreleme, birleştirme, sıralama ve proje verilerini yansıtma" alanı için bir DSL'dir. HTML, "sayfadaki metnin mizanpajını tanımlayın" alanı için bir DSL'dir. Dil tabanlı çözümlere uygun birçok alan vardır. Benim favorilerimden biri "metin tabanlı macera oyunu" alanı için bir DSL olan Inform7; muhtemelen şimdiye kadar gördüğüm en üst düzey ciddi programlama dilidir. Hakkında bir şey bildiğiniz bir alan seçin ve o alandaki sorunları ve çözümleri tanımlamak için dili nasıl kullanacağınızı düşünün.

Dilinizin neye benzemesini istediğinizi belirledikten sonra, yasal ve yasa dışı bir programın ne olduğunu belirlemek için tam olarak kuralların ne olduğunu yazmayı deneyin. Genellikle bunu üç seviyede yapmak istersiniz:

  1. lexical: Dildeki kelimeler için kurallar nelerdir, hangi karakterler yasaldır, sayılar neye benziyor vb.
  2. sözdizimsel: dil kelimeleri daha büyük birimlerde nasıl birleşir? C # 'da daha büyük birimler ifadeler, ifadeler, yöntemler, sınıflar vb.
  3. anlamsal: sözdizimsel olarak yasal bir program verildiğinde, programın ne olduğunu nasıl anlarsınız ne yapar?

Bu kuralları yazın olabildiğince kesin. Eğer iyi bir iş çıkarırsanız, bunu derleyici veya tercüman yazmanın temeli olarak kullanabilirsiniz. Ne demek istediğimi görmek için C # belirtimine veya ECMAScript belirtimine bir göz atın; yasal bir programı neyin oluşturduğunu ve ne yaptığını nasıl anlayacağınızı açıklayan çok kesin kurallarla doludurlar.

Derleyici yazmaya başlamanın en iyi yollarından biri, üst düzey dilden üst düzey dile bir derleyici yazmaktır. Kendi dilinizde dizeler alan ve C # veya JavaScript ya da bildiğiniz herhangi bir dilde dizeler çıkaran bir derleyici yazın; o dil için derleyicinin çalıştırılabilir koda dönüştürülmesinin ağır kaldırılmasına dikkat edin.

C #, VB, VBScript, JavaScript ve diğer diller ve araçların tasarımı hakkında bir blog yazıyorum; bu konu ilginizi çekiyorsa, bir göz atın. http://blogs.msdn.com/ericlippert (geçmiş) ve http://ericlippert.com (mevcut)

Özellikle bu yazıyı ilginç bulabilirsiniz; burada C # derleyicisinin semantik analizi sırasında sizin için gerçekleştirdiği görevlerin çoğunu listeliyorum. Gördüğünüz gibi birçok adım var. Büyük analiz problemini bireysel olarak çözebileceğimiz bir dizi soruna ayırıyoruz.

http://blogs.msdn.com/b/ericlippert/archive/2010/02/04/how-many-passes.aspx

Son olarak, yaşlandıkça bu işi yapan bir iş arıyorsanız, Microsoft'a bir üniversite stajyeri olarak gelmeyi ve geliştirici bölümüne girmeyi deneyin. Bugün işimi böyle bitirdim!

407
Eric Lippert

Jack Crenshaw'dan Derleyici Oluşturalım derleyicileri ve Derleme dilini yazmaya ilginç bir giriş bulabilirsiniz.

Yazar bunu çok basit tuttu ve gerçek işlevsellik oluşturmaya odaklandı.

127
user1249

" gerçekten bu şeyleri öğrenmek istiyorum". Uzun vadeli ciddi iseniz:

  • Üniversiteye gidin, yazılım mühendisliğinde uzmanlaşın. Alabileceğiniz her derleyici sınıfını alın. Sınıfları sağlayan insanlar sizden daha iyi eğitimli ve daha deneyimli; uzman bakış açılarının bilgiyi size kodu okumadan asla elde edemeyeceğiniz şekilde sunmak için kullanması iyidir.

  • Lise boyunca matematik derslerine sadık kalın ve 4 yıl boyunca üniversiteye devam edin. Standart olmayan matematiğe odaklanın: mantık, grup teorisi, meta-matematik. Bu sizi soyut düşünmeye zorlayacaktır. Derleme ile ilgili gelişmiş teori belgelerini okumanızı ve bu teorilerin neden ilginç ve faydalı olduğunu anlamanıza olanak tanır. Sonsuza dek en son teknolojinin arkasında olmak istiyorsanız, bu gelişmiş teorileri görmezden gelebilirsiniz.

  • Standart derleyici metinlerini toplayın/okuyun: Aho/Ullman, vs. Topluluğun genel olarak kabul ettiği şeyleri içerir. Bu kitaplardaki her şeyi kullanamayabilirsiniz, ancak var olduğunu bilmelisiniz ve neden kullanmadığınızı bilmelisiniz. Muchnick'in harika olduğunu düşündüm, ancak oldukça gelişmiş konular için.

  • Bir derleyici oluşturun. Çürümüş bir tane oluşturarak ŞİMDİ başlayın. Bu size bazı konuları öğretecektir. İkinci bir tane oluşturun. Tekrar et. Bu deneyim, kitap öğrenmenizle büyük bir sinerji yaratır.

  • Başlamak için gerçekten iyi bir yer, BNF (Backus Naur Formu), ayrıştırıcılar ve ayrıştırıcı jeneratörler hakkında bilgi edinmek. BNF derleyici arazisinde evrensel olarak kullanılır ve bilmiyorsanız diğer derleyici türlerinizle gerçekçi bir şekilde konuşamazsınız.

Derlemeye harika bir ilk giriş yapmak ve sadece dokümantasyon için değil, araçla işlenebilir bir meta dil olarak BNF'nin doğrudan değeri istiyorsanız, "meta" derleyicileri (derleyiciler) oluşturmak için bu eğitici (benim değil) derleyiciler derleyen) Val Schorre'nin 1964 (evet, doğru okudunuz) ["META II sözdizimine dayalı derleyici yazma dili" adlı bir makaleye dayanarak oluşturulmuştur. (http://doi.acm.org/10.1145/800257.808896)] Bu IMHO, şimdiye kadar yazılan en iyi comp-sci gazetelerinden biridir: 10 sayfada derleyici derleyicileri oluşturmayı öğretir. Başlangıçta bu makaleden öğrendim.

Yukarıda yazdıklarım kişisel deneyimlerden çok fazla ve bence bana oldukça iyi hizmet etti. YMMV, ama IMHO, fazla değil.

72
Ira Baxter

İşte takip edebileceğiniz çevrimiçi bir kitap/ders --- Bilişim Sistemlerinin Elemanları: İlk İlkelerden Modern Bilgisayar Kurmak .

Simülatörleri kullanarak, aslında baştan aşağı eksiksiz bir bilgisayar sistemi inşa edersiniz. Birçok yorumcu sorunuzun çok geniş olduğunu belirtmiş olsa da, bu kitap aslında çok yönetilebilir kalırken cevaplıyor. İşiniz bittiğinde, kendi işletim sisteminizin işlevselliğini kullanan yüksek düzeyli bir dilde (tasarladığınız) bir oyun yazmış olacaksınız; bu, VM dil ( tasarladınız) derleyiciniz tarafından, derleyici tarafından (tasarladığınız) VM çevirmeniniz tarafından), bu da derleyiciniz tarafından makine koduna (tasarladığınız) monte edilir. boolean mantığı ve basit bir donanım açıklama dili kullanarak tasarladığınız yongalardan bir araya getirdiğiniz bilgisayar sisteminizde.

Bölümler:

  1. Derse Genel Bakış
  2. Boole mantığı
  3. Kombinatoryal Cipsler
  4. Sıralı Yongalar
  5. Makine dili
  6. Bilgisayar Mimarisi
  7. Montajcı
  8. Sanal Makine I: Aritmetik
  9. Sanal Makine II: Kontrol
  10. Programlama dili
  11. Derleyici I: Sözdizimi Analizi
  12. Derleyici II: Kod Üretimi
  13. İşletim sistemi
  14. Liste öğesi

Gitmek İçin Daha Eğlenceli

46
Joe Internet

Bir adım geri at. Derleyici, basitçe bir dildeki bir belgeyi başka bir dildeki bir belgeye çeviren bir programdır. Her iki dil de iyi tanımlanmış ve spesifik olmalıdır.

Dillerin programlama dili olması gerekmez. Kuralları yazılabilen any dil olabilirler. Muhtemelen görmüşsünüz Google Çeviri ; bu bir derleyici çünkü bir dili (örneğin, Almanca) diğerine (belki Japonca) çevirebilir.

Derleyicinin başka bir örneği, bir HTML oluşturma motorudur. Girdi bir HTML dosyasıdır ve çıktı ekranda pikselleri çizmek için bir dizi talimattır.

Çoğu kişi bir derleyici hakkında konuştuğunda, genellikle üst düzey bir programlama dilini (Java, C, Prolog gibi) düşük seviyeli bir dile (Montaj veya makine kodu) çeviren bir programdan bahseder. Bu göz korkutucu olabilir. Ancak, bir generalistin görüşüne baktığınızda, derleyicinin bir dili diğerine çeviren bir program olduğu o kadar da kötü değil.

Bir dizedeki her Word'ü tersine çeviren bir program yazabilir misiniz? Örneğin:

When the cat's away, the mice will play.

olur

nehW eht s'tac yawa, eht ecim lliw yalp.

Bu yazmak zor bir program değil, ancak bazı şeyleri düşünmeniz gerekiyor:

  • "Kelime" nedir? Hangi karakterlerin bir kelimeyi oluşturduğunu tanımlayabilir misiniz?
  • Kelimeler nerede başlar ve biter?
  • Sözcükler yalnızca bir boşlukla mı ayrılıyor yoksa daha fazla mı yoksa daha az mı olabilir?
  • Noktalama işaretlerinin de tersine çevrilmesi gerekiyor mu?
  • Bir kelimenin içindeki noktalama işaretleri ne olacak?
  • Büyük harflere ne olur?

Bu soruların cevapları dilin iyi tanımlanmasına yardımcı olur. Şimdi devam edin ve programı yazın. Tebrikler, yeni bir derleyici yazdınız.

Buna ne dersiniz: Bir dizi çizim talimatı alan ve bir PNG (veya JPEG) dosyası çıkaran bir program yazabilir misiniz? Belki böyle bir şey:

image 100 100
background black
color red
line 20 55 93 105
color green
box 0 0 99 99

Yine, dili tanımlamak için biraz düşünmeniz gerekir:

  • İlkel talimatlar nelerdir?
  • Word "satırından" sonra ne olur? "Renk" ten sonra ne olur? Aynı şekilde "arka plan", "kutu" vb.
  • Sayı nedir?
  • Boş bir giriş dosyasına izin veriliyor mu?
  • Kelimeleri büyük harfle kullanmak uygun mudur?
  • Negatif sayılara izin veriliyor mu?
  • "Görüntü" yönergesini vermezseniz ne olur?
  • Bir renk belirtmemek uygun mu?

Elbette cevaplanması gereken daha fazla soru var, ancak eğer onları çivileyebiliyorsanız, bir dil tanımladınız. Çeviriyi yapmak için yazdığınız program, tahmin edersiniz, bir derleyicidir.

Bir derleyici yazmak o kadar da zor değil. Java veya C içinde kullandığınız derleyiciler bu iki örneğin sadece daha büyük versiyonlarıdır. Öyleyse gidin! Basit bir dil tanımlayın ve bu dilin bir şeyler yapmasını sağlamak için bir program yazın. daha sonra dilinizi genişletmek istersiniz.Örneğin, değişkenler veya aritmetik ifadeler eklemek isteyebilirsiniz Derleyiciniz daha karmaşık hale gelecek, ancak kendiniz yazdığınız için her bir kısmını anlayacaksınız. Bu diller ve derleyiciler böyle ortaya çıkıyor.

46
Barry Brown

Derleyici tasarımı ile ilgileniyorsanız, Dragon Book (resmi başlık: Derleyiciler: İlkeler, Teknikler ve Araçlar) bölümüne bakın. Yaygın olarak bu konuda klasik bir kitap olarak kabul edilir.

21
Brian Agnew

Bir derleyici veya işletim sistemi hakkında sihirsel bir şey olduğuna inanmayın: yoktur. Bir dizedeki tüm sesli harfleri saymak için yazdığınız programları hatırlayın veya bir dizideki sayıları toplayın? Bir derleyici kavram açısından farklı değildir; sadece çok daha büyük.

Her programın üç aşaması vardır:

  1. bazı şeyler oku
  2. bu işlemi yapın: giriş verilerini çıkış verilerine çevirin
  3. başka şeyler yazın - çıktı verileri

Bir düşünün: derleyiciye girdi nedir? Kaynak dosyadan bir karakter dizisi.

Derleyiciden çıktı nedir? Hedef bilgisayara makine yönergelerini temsil eden bayt dizisi.

Derleyicinin "süreç" aşaması nedir? Bu aşama ne yapıyor?

Derleyicinin - diğer herhangi bir program gibi - bu üç fazı dahil etmek için olduğunu düşünüyorsanız, iyi bir bir derleyicinin nasıl oluşturulduğu fikri.

10
Pete Wilson

"Derleyici derleyelim" zaten önerilmişti. Turbo Pascal yerine Haskell kullanan "modernize edilmiş" bir versiyon var: http://alephnullplex.appspot.com/blog/view/2010/01/12/lbach-1-introduction

Haskell'e bağlı olarak, daha fazla fikir verebilecek çok öğretici bir Şema yorumlayıcısı vardır: 48 Saatte Kendinize bir Şema Yazınız

10
Landei

Ben uzman değilim, ama işte benim bıçakım:

Bir derleyici yazmak istemiyorsunuz, sadece bir montajcı. Bu gerçekten sihir değil.

Birinin cevaplarını çalmak SO ( https://stackoverflow.com/questions/3826692/how-do-i-translate-Assembly-to-binary ), Meclis şöyle:

label:  LDA #$00
        JMP label

Sonra bir montajcı aracılığıyla çalıştırın ve böyle bir şeye dönüşür:

$A9 $00
$4C $10 $00

Sadece hepsi ezilmiş, şöyle:

$A9 $00 $4C $10 $00

Gerçekten sihir değil.

Bunu not defterinde yazamazsınız, çünkü not defteri ASCII (onaltılık değil) kullanır. Onaltılık bir düzenleyici kullanırsınız veya baytları programlı olarak yazarsınız. , "a.exe" veya "a.out" olarak adlandırın, ardından işletim sistemine çalıştırmasını söyleyin.

Elbette, modern CPU'lar ve işletim sistemleri oldukça karmaşıktır, ancak bu temel fikirdir.

Yeni bir derleyici yazmak istiyorsanız, işte böyle yapılır:

1) Pyparsing'teki (veya başka bir iyi ayrıştırma çerçevesindeki) hesap makinesi örneği gibi bir şey kullanarak yorumlanmış bir dil yazın. Bu sizi ayrıştırma temelleri üzerinde hızlandıracaktır.

2) Bir çevirmen yazın. Dilini javascript diline çevir. Şimdi diliniz bir tarayıcıda çalışacak.

3) LLVM, C veya Assembly gibi daha düşük bir seviyeye çevirmen yazın.

Burada durabilirsin, bu bir derleyici. Optimize edici bir derleyici değil, ama soru bu değildi. Bir bağlayıcı ve birleştirici yazmayı da düşünmeniz gerekebilir, ancak gerçekten istiyor musunuz?

4) (Deli) Bir iyileştirici yazın. Büyük ekipler onlarca yıldır bu konuda çalışıyor.

4) (Sane) Mevcut bir topluluğa katılın. GCC, LLVM, PyPy, herhangi bir tercüman üzerinde çalışan çekirdek ekip.

8
wisty

Bazıları mükemmel cevaplar verdiler. Birkaç öneri daha ekleyeceğim. İlk olarak, yapmaya çalıştığınız şey için iyi bir kitap Appel'in Modern Derleyici Uygulama metinleridir ( C , Java =, veya Standart ML ). Bu kitap, basit bir dil için bir derleyicinin tam bir uygulaması olan Tiger'ı, minimum çalışma zamanı destek kitaplığıyla birlikte bir emülatörde çalıştırılabilen MIPS Assembly'ye götürür. Derlenmiş bir dilin çalışması için gereken her şeyden tek bir geçiş yapmak için oldukça iyi bir kitap1.

Appel, önceden tasarlanmış bir dilin nasıl derleneceğini, ancak çeşitli dil özelliklerinin ne anlama geldiği veya kendiniz tasarlamanın göreceli değerleri açısından nasıl düşünüleceği konusunda fazla zaman harcamaz. Bu açıdan Programlama Dilleri: Kavramlar ve Yapılar iyi. Bilgisayar Programlamanın Kavramları, Teknikleri ve Modelleri , dil tasarımı hakkında derin düşünmek için de iyi bir kitaptır, ancak bunu tek bir dil bağlamında yapar ( Oz ).

Son olarak, Appel'in metninin C, Java ve Standart ML'de olduğunu belirttim - derleyici yapım ve programlama dilleri konusunda ciddi iseniz, ML öğrenmenizi ve Appel'in bu sürümünü kullanmanızı öneririm. ML-aile dillerinin güçlü tip sistemleri ağırlıklı olarak işlevseldir - diğer birçok dilden farklı olacak özellikler, bu nedenle zaten işlevsel bir dil bilmiyorsanız bunları öğrenmek dil teknenizi geliştirecektir. Ayrıca, desen eşleştirme ve fonksiyonel zihniyetleri, bir derleyicide sık sık yapmanız gereken manipülasyon türlerine son derece uygundur, bu nedenle ML tabanlı dillerde yazılmış derleyiciler, C'de yazılmış derleyicilerden genellikle çok daha kısa ve anlaşılır, Java veya benzer diller. Harper'ın kitabı Standard ML'de başlamanız için oldukça iyi bir rehberdir; bunun üzerinde çalışmanız sizi Appel'in Standart ML derleyici uygulama kitabına götürmeye hazırlamalıdır. Standart ML öğrenirseniz, daha sonra çalışmak için OCaml'ı almak oldukça kolay olacaktır; IMO, çalışma programcısı için daha iyi takımlara sahiptir (çevredeki işletim sistemi ortamıyla daha temiz bir şekilde bütünleşir, yürütülebilir programları kolayca üretir ve ulex ve Menhir gibi muhteşem derleyici oluşturma araçlarına sahiptir).


1Uzun vadeli referans için, e-posta kitabını tercih ediyorum, çünkü ayrıştırıcı algoritmaların iç çalışması gibi daha fazla atıfta bulunacağım şeyler hakkında daha fazla ayrıntıya sahip ve farklı yaklaşımların daha geniş bir kapsama alanına sahip, ancak Appel'in kitabı çok iyi ilk geçiş. Temel olarak, Appel size derleyici boyunca işleri yapmanın bir yolunu öğretir ve size rehberlik eder. Dragon Book, farklı tasarım alternatiflerini daha ayrıntılı bir şekilde ele alır, ancak bir şeyin nasıl işe yarayacağı konusunda çok daha az rehberlik sağlar.


Düzenlendi : hatalı Aho referansını Sethi ile değiştirin, CTMCP'den bahsedin.

8
Michael Ekstrand

Üniversitede ders için bir derleyici oluşturmak zorunda kaldım.

Bunu yapmanın temelleri düşündüğünüz kadar karmaşık değil. İlk adım dilbilginizi oluşturmaktır. İngiliz dilinin gramerini düşünün. Aynı şekilde, bir öznesi ve yüklemi varsa bir cümleyi ayrıştırabilirsiniz. Bununla ilgili daha fazla bilgi için Bağlamdan Bağımsız Dilbilgileri konusunu okuyun.

Dilbilgisini (dilinizin kuralları) öğrendikten sonra, bir derleyici yazmak sadece bu kurallara uymak kadar basittir. Derleyiciler genellikle makine koduna dönüşür, ancak x86 öğrenmek istemiyorsanız, MIPS'e bakmanızı veya kendi Sanal Makinenizi yapmanızı öneririm.

Derleyiciler tipik olarak iki bölümden oluşur, bir tarayıcı ve bir ayrıştırıcı. Temel olarak, tarayıcı kodu okur ve belirteçlere ayırır. Ayrıştırıcı, bu belirteçlerin yapısına bakar. Sonra derleyici geçer ve içinde olması gereken herhangi bir koda dönüştürmek için bazı oldukça basit kuralları izler (Montaj, bayt kodu gibi ara kod, vb). Daha küçük ve daha küçük parçalara ayırırsanız, bu sonunda hiç göz korkutucu değildir.

İyi şanslar!

6
Jerr

Petzold'un kitabı Kod , ilk prensiplerden başlayarak hem teknik olmayan hem de tekniklere harika bir giriş niteliğindedir. Oldukça okunabilir ve çok fazla saplanmadan kapsamı çok geniştir.

Şimdi bunu yazdığıma göre, onu tekrar okumam gerekecek.

6
Kevin Won

Bu iş parçacığında mükemmel cevaplar var, ama sadece bir kez aynı soruya sahip olduğum için benimkini eklemek istedim. (Ayrıca, Joe-Internet tarafından önerilen kitabın mükemmel bir kaynak olduğunu belirtmek isterim.)

Birincisi, bir bilgisayarın nasıl çalıştığı sorusudur? İşte bu şekilde: Giriş -> Hesapla -> Çıkış.

İlk önce “Compute” kısmını düşünün. Girdi ve Çıktının daha sonra nasıl çalıştığına bakacağız.

Bir bilgisayar temel olarak bir işlemci (veya CPU) ve bir miktar bellek (veya RAM) içerir. Bellek, her biri sonlu sayıda bit saklayabilen konumların bir koleksiyonudur ve bu bellek konumlarının her birine bir sayı ile başvurulabilir, buna bellek konumunun adresi denir. İşlemci, verileri getirebilen bir gadget'tır. bellekten, verilere dayalı bazı işlemler gerçekleştirin ve bazı verileri belleğe geri yazın. İşlemci, verileri bellekten okuduktan sonra ne okuyacağını ve ne yapacağını nasıl anlar?

Bunu cevaplamak için bir işlemcinin yapısını anlamalıyız. Aşağıdakiler oldukça basit bir görüştür. Bir işlemci temel olarak iki bölümden oluşur. Bunlardan biri, işlemcinin içinde çalışan ve çalışan bellek görevi gören bir dizi bellek konumudur. Bunlara “register” denir. İkincisi, kayıtlardaki verileri kullanarak belirli işlemleri gerçekleştirmek için yapılmış bir grup elektronik makinedir. “Program Sayacı” veya bilgisayar ve “Talimat Kaydı” veya ir olarak adlandırılan iki özel kayıt vardır. İşlemci, belleğin üç bölüme ayrıldığını düşünür. İlk bölüm, yürütülmekte olan bilgisayar programını saklayan “program belleği” dir. İkincisi “veri belleği” dir. Üçüncüsü bazı özel amaçlar için kullanılır, daha sonra konuşacağız. Program Sayacı, Program Belleğinden okunacak bir sonraki talimatın yerini içerir. Komut Sayacı Gerçekleştirilen geçerli işlemi ifade eden bir sayı içerir. Bir işlemcinin gerçekleştirebileceği her işlem, işlemin opcode'u olarak adlandırılan bir sayı ile ifade edilir. Bir bilgisayarın temelde nasıl çalıştığı, Program Sayacı tarafından Talimat Kaydında başvurulan bellek konumunu okur (ve Program Sayacını bir sonraki talimatın bellek konumunu gösterecek şekilde arttırır). Daha sonra Talimat Kaydını okur ve istenen işlemi gerçekleştirir. Örneğin, bir kayıt defterine belirli bir bellek konumunu okumak veya bir kayıt defterine yazmak veya iki kayıt değerini kullanarak bir işlem gerçekleştirmek ve çıkışı üçüncü bir kayıt defterine yazmak olabilir.

Şimdi bilgisayar nasıl Giriş/Çıkış yapıyor? Çok basitleştirilmiş bir cevap vereceğim. Bakınız http://en.wikipedia.org/wiki/Input/output ve http://en.wikipedia.org/wiki/Interrupt . daha fazlası için. Hafızanın üçüncü kısmı ve Kesmeler adı verilen iki şey kullanır. Bilgisayara bağlı her aygıtın işlemci ile veri alışverişi yapabilmesi gerekir. Bunu, daha önce bahsedilen belleğin üçüncü bölümünü kullanarak yapar. İşlemci her aygıta bir dilim bellek ayırır ve aygıt ve işlemci bu bellek dilimi aracılığıyla iletişim kurar. Ancak işlemci, hangi cihazın hangi cihazı ifade ettiğini ve ne zaman bir cihazın veri alışverişi yapması gerektiğini nasıl bilebilir? Kesintiler devreye girer. Kesinti, işlemciye şu anda ne olduğunu duraklatmak ve tüm kayıtlarını bilinen bir konuma kaydetmek ve daha sonra başka bir şey yapmaya başlamak için bir işarettir. Birçok kesinti var, her biri benzersiz bir sayı ile tanımlanıyor. Her kesinti için, onunla ilişkili özel bir program vardır. Kesme gerçekleştiğinde, işlemci kesintiye karşılık gelen programı yürütür. Şimdi bios'a ve donanım cihazlarının bilgisayar anakartına nasıl bağlandığına bağlı olarak, her cihaz benzersiz bir kesme ve bir dilim bellek alır. İşletim sistemini bios yardımı ile başlatırken, her cihazın kesme ve bellek konumunu belirler ve cihazların düzgün şekilde işlenmesi için özel programlar kurar. Bu nedenle, bir cihazın bazı verilere ihtiyacı olduğunda veya bazı veriler göndermek istediğinde, bir kesinti sinyali verir. İşlemci yaptığı işi duraklatır, kesmeyi işler ve sonra yaptığı işe geri döner. Bunlar, hdd, klavye vb.Gibi birçok türde kesintidir. Önemli olan, düzenli aralıklarla bir kesinti başlatan sistem zamanlayıcısıdır. Ayrıca, yazılım kesintileri adı verilen kesintileri tetikleyebilen opcodlar da vardır.

Artık bir işletim sisteminin nasıl çalıştığını neredeyse anlayabiliyoruz. Açıldığında, işletim sistemi bir zamanlayıcı kesintisi ayarlar, böylece işletim sistemine düzenli aralıklarla kontrol sağlar. Ayrıca, diğer aygıtları vb. İşlemek için diğer kesintileri de kurar. Şimdi bilgisayar bir grup program çalıştırdığında ve zamanlayıcı kesintisi os olduğunda kontrol kazanır ve işlem yönetimi, bellek yönetimi vb. Gibi önemli görevleri yerine getirir. programların doğrudan cihazlara erişmesine izin vermek yerine donanım cihazlarına erişmesinin soyut bir yolu. Bir program bir aygıta erişmek istediğinde, os tarafından sağlanan ve daha sonra aygıtla konuşan bir kod çağırır. Bunlarda, eşzamanlılık, iş parçacıkları, kilitler, bellek yönetimi vb.

Şimdi, teorik olarak doğrudan opcodes kullanarak bir program yazabilirsiniz. Buna makine kodu denir. Bu çok acı verici. Şimdi işlemci için bir Montaj dili, bu opcodlar için anımsatıcılardan başka bir şey değildir, bu da program yazmayı kolaylaştırır. Basit bir derleyici, Mecliste yazılmış bir programı alan ve anımsatıcıları uygun opcode'larla değiştiren bir programdır.

İşlemci ve Montaj dili nasıl tasarlanır. Bilgisayar mimarisiyle ilgili bazı kitapları okumak zorunda olduğunuzu bilmek. (joe-internet tarafından atıfta bulunulan kitabın 1-7 bölümlerine bakınız). Bu, boole cebiri, ekleme, çarpma vb. İçin basit kombinatoryal devrelerin nasıl oluşturulacağı, bellek ve sıralı devrelerin nasıl oluşturulacağı, bir mikroişlemcinin nasıl inşa edileceği vb.

Şimdi nasıl bilgisayar dilleri yazıyor. Makine kodunda basit bir montajcı yazarak işe başlayabilirsiniz. Daha sonra C'nin basit bir alt kümesi için bir derleyici yazmak için bu derleyiciyi kullanın. Sonra C'nin daha eksiksiz bir sürümünü yazmak için C'nin bu alt kümesini kullanın. Son olarak python gibi daha karmaşık bir dil yazmak için C'yi kullanın. = veya C++ Tabii ki bir dil yazmak için önce onu tasarlamalısınız (bir işlemcinin desigh'ında olduğu gibi) Yine bu konuda bazı ders kitaplarına bakın.

Ve kişi nasıl bir işletim sistemi yazar? İlk önce x86 gibi bir platformu hedeflersiniz. Sonra nasıl önyükleme yaptığını ve işletim sisteminizin ne zaman çağrıldığını anlayacaksınız. Tipik bir bilgisayar bu şekilde önyükleme yapar. Çalışmaya başlar ve bios bazı testler yapar. Ardından bios, hdd'nin ilk kesimini okur ve içeriği bellekteki belirli bir konuma yükler. Ardından, yüklenen bu veriyi yürütmeye başlamak için cpu'yu kurar. Bu, os'un çağrıldığı noktadır. Bu noktada tipik bir işletim sistemi geri kalan belleğini yükler. Ardından cihazları başlatır ve başka şeyler ayarlar ve son olarak giriş ekranı ile sizi selamlar.

Bu yüzden bir işletim sistemi yazmak için “boot-loader” yazmalısınız. Sonra kesmeleri ve aygıtları işlemek için kod yazmalısınız. Daha sonra süreç yönetimi, cihaz yönetimi vb. İçin tüm kodları yazmalısınız. Daha sonra işletim sisteminizde çalışan programların cihazlara ve diğer kaynaklara erişmesini sağlayan bir api yazmalısınız. Son olarak, bir programı diskten okuyan, bir işlem olarak ayarlayan ve yürütmeye başlayan bir kod yazmalısınız.

Elbette cevabım açıkça sadeleştirilmiş ve muhtemelen çok az pratik kullanım. Savunmamda şu anda teoride yüksek lisans öğrencisiyim, bu yüzden bunların çoğunu unuttum. Ancak bu şeylerin çoğunu google'da yapabilir ve daha fazlasını öğrenebilirsiniz.

5
dubyaman

StackOverflow'daki bu mükemmel soruyu (ve cevapları) kontrol etmek isteyebilirsiniz: Bir Derleyici Yazmayı Öğrenme . Geniş bir kaynak listesi içerir.

5
Angry Lettuce

Sizinle benzer bir karışıklık durumundayken programlama kariyerimdeki bir noktayı hatırlayabiliyorum: Teoriyi biraz okumuştum, Ejderha kitabı, Kaplan kitabı (kırmızı), ama hala çok fazla bunların nasıl bir araya getirileceğine dair bir ipucu.

Onu birbirine bağlayan şey do için somut bir proje bulmaktı (ve sonra tüm teorinin sadece küçük bir alt kümesine ihtiyacım olduğunu bulmak).

Java VM bana iyi bir başlangıç ​​noktası sağladı: kavramsal olarak bir "işlemci" ama gerçek CPU'ların dağınık detaylarından oldukça soyutlanmış.) öğrenme sürecinin önemli ve sıklıkla gözden kaçan bir parçası: bir şeyleri tekrar bir araya getirmeden önce parçalara ayırmak (eski günlerde radyo setleri ile eskiden olduğu gibi).

Bir decompiler ve Java'daki Hello, World sınıfı ile oynayın. JVM spesifikasyonunu okuyun ve neler olduğunu anlamaya çalışın. Bu size derleyicinin ne olduğuna dair topraklı bir fikir verecektir yapıyor.

Sonra create Hello, World sınıfı koduyla oynayın. (Aslında, yalnızca Merhaba, Dünya diyebileceğiniz çok özel bir dil için uygulamaya özel bir derleyici oluşturuyorsunuz.)

Başka bir dilde yazılmış, aynı sınıftan çıktı alabilen Merhaba, Dünya'da okuyabilecek kod yazmayı deneyin. Bu dizeyi "Merhaba, Dünya" dan başka bir şeye değiştirebilmeniz için yapın.

Şimdi "2 * (3 + 4)" gibi bazı aritmetik ifadeleri hesaplayan bir sınıfı derlemeyi (Java'da) deneyin. Bu sınıfı ayırın, tekrar bir araya getirebilecek bir "oyuncak derleyici" yazın.

4
Morendil

1) Washington Üniversitesi'nden harika video dersleri:

CSE P 501 Derleyici İnşaatı - Sonbahar 2009 www.cs.washington.edu/education/courses/csep501/09au/lectures/video.html *

2) SICP http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/ Ve aynı adı taşıyan kitap. Bu aslında herhangi bir yazılım mühendisi için zorunludur.

3) Ayrıca, fonksiyonel programlama hakkında, Haskell, lambda hesabı, anlambilim (anlamsal dahil) ve fonksiyonel diller için derleyici uygulaması. Haskell'i zaten biliyorsanız, 2005-SS-FP.V10.2005-05-24.HDV'den başlayabilirsiniz. Uxx videolar cevaptır. Lütfen önce Vxx videoları izleyin.

http://video.s-inf.de/#FP.2005-SS-Giesl. (Cot) .HD_Videoaufzeichnung

(videolar İngilizce, diğer kurslar Almanca olsa da.)

  • yeni kullanıcılar en fazla iki köprü yayınlayabilir.
3
Zura

ANTLR iyi bir başlangıç ​​noktasıdır. Lex ve Yacc'a benzer bir dil üreten çerçeve. Süreci basitleştiren ANTLRWorks adlı bir gui var.

.NET dünyasında, .NET dünyasında kod oluşturmak için kullanılabilen Dynamic Language Runtime vardır. DLR kullanarak kod üreten Zentrum adlı bir ifade dili yazdım. Statik ve dinamik olarak yazılan ifadelerin nasıl ayrıştırılacağını ve yürütüleceğini gösterecektir.

3
Sean

Söylediğin her şey doğruysa, umut verici bir araştırmacının profiline sahipsin ve somut bir anlayış sadece bir yolla elde edilebilir: çalışma. Ve demiyorum ki " Tüm bu üst düzey bilgisayar bilimi kitaplarını okuyun (özellikle bunlar ) bunun tarafından yazılmıştır dahi !"; Demek istediğim: Charles Babbage, Alan Turing, Claude Shannon veya Dennis Ritchie gibi bir bilgisayar bilimcisi olabilmek için üst düzey insanlarla birlikte olmalısınız. Kendi kendini yetiştirmiş insanları hor görmüyorum (ben onlardan biriyim) ama dışarıda senin gibi çok insan yok. Ciddiye tavsiye ederim Sembolik Sistemler Programı (SSP) at Stanford Üniversitesi . Web sitelerinin dediği gibi:

Stanford Üniversitesi'ndeki Sembolik Sistemler Programı (SSP) bilgisayarlara ve zihinlere odaklanır: bilgiyi temsil etmek için semboller kullanan yapay ve doğal sistemler. SSP insan-bilgisayar ilişkisinin farklı yönleriyle ilgilenen öğrencileri ve fakültesi bir araya getirir ...

  • bilişsel bilim : insan zekasını, doğal dilleri ve beyni hesaplama süreçleri olarak incelemek;
  • yapay zeka : bilgisayarlara insan benzeri davranış ve anlayışa sahip olmak; ve
  • insan-bilgisayar etkileşimi : insan kullanıcıları ile iyi çalışan bilgisayar yazılımları ve arayüzler tasarlamak.
2
quantme

Sol alanın biraz dışında bir şey önereceğim: öğrenmek Python (veya belki Ruby, ama Python) Ve sadece onunla uğraşmakla kalmayın, aynı zamanda onu derin bir düzeyde tanımak.

Bunu önermemin birkaç nedeni var:

  1. Python son derece iyi tasarlanmış bir dildir. Birkaç siğil olsa da, diğer birçok dilden daha az IMHO'ya sahiptir. Eğer tomurcuklanan bir dil tasarımcısıysanız, kendinizi olabildiğince çok iyi dile maruz bırakmak iyidir.

  2. Python'un standart uygulaması (CPython) açık kaynaklıdır ve iyi belgelenmiştir, bu da dilin başlık altında nasıl çalıştığını anlamayı kolaylaştırır.

  3. Python, Assembly'den daha kolay anlaşılan ve tüm platformlarda aynı şekilde çalışan basit bir bayt koduna derlenmiştir Python çalışır.) Derleme hakkında bilgi edineceksiniz (Python kaynak kodunuzu bayt koduna derler) ve yorumlama (bu bayt kodu Python sanal makine) içinde yorumlandığı için).

  4. Python, numaralı PEP'lerde (Python Geliştirme Önerileri) belgelenmiş birçok yeni özelliğe sahiptir. Dil tasarımcılarının bir özelliği gerçekte nasıl yaptıklarını seçmeden önce nasıl uygulamayı düşündüklerini görmek ilginçtir. (Halen değerlendirilmekte olan KEP'ler bu konuda özellikle ilginçtir.)

  5. Python, çeşitli programlama paradigmalarının bir karışımına sahiptir, bu nedenle problem çözme yaklaşımlarına yaklaşmanın çeşitli yollarını öğrenecek ve kendi dilinize dahil olmak üzere daha geniş bir araç yelpazesine sahip olacaksınız.

  6. Python, dekoratörler, metasınıflar, ithalat kancaları, vb. İle dili çeşitli şekillerde genişletmeyi oldukça kolaylaştırır, böylece yeni dil özellikleriyle gerçekte dili terk etmeden bir ölçüde oynayabilirsiniz. (Bir yana: kod blokları Ruby'de birinci sınıf bir nesnedir, bu yüzden aslında döngüler gibi yeni kontrol yapıları yazabilirsiniz! Ruby programcıların mutlaka dikkate almaması gerektiği izlenimi edinirim) bu dili genişletirse, Ruby'de nasıl programladığınızdır. Ama oldukça havalı.)

  7. Python'da, derleyici tarafından üretilen bayt kodunu gerçekten parçalara ayırabilir, hatta kendi kodunuzu sıfırdan yazabilir ve yorumlayıcının yürütmesini sağlayabilirsiniz (bunu kendim yaptım ve zihin bükücü ama eğlenceliydi).

  8. Python ayrıştırma için iyi kütüphanelere sahiptir. Python kodunu soyut bir sözdizimi ağacına ayrıştırabilir ve daha sonra AST modülünü kullanarak işleyebilirsiniz. PyParsing modülü, diğerleri gibi rasgele dilleri ayrıştırmak için yararlıdır) Teorik olarak ilk dil derleyicinizi Python dilerseniz yazabilirsiniz (ve C, Assembly veya hatta Python çıktı) üretebilirsiniz.

Bu araştırmacı yaklaşım, çalıştığınız dilde okuduğunuz kavramları tanımaya başlayacağınız için, daha resmi bir yaklaşımla iyi gidebilir veya bunun tersi de geçerlidir.

İyi eğlenceler!

2
kindall

Derleyicilerin nasıl çalıştığı ve kendi programlama dilinizi nasıl oluşturacağınızla ilgili basit bir giriş için yeni kitabı http://createyourproglang.com OS/CPU iç kısımları, yani sözlükler, ayrıştırıcılar, tercümanlar vb.

Son zamanlarda popüler olan Coffee Script ve Fancy programlama dillerini oluşturmak için kullanılan araçların aynısını kullanır.

2
mythz

Kenneth Louden'in "Derleyici İnşaatı" adlı kitabına bakın

http://www.cs.sjsu.edu/~louden/cmptext/

Derleyici geliştirmeye daha iyi uygulamalı bir yaklaşım sağlar.

İnsanlar yaparak öğrenir. Sadece küçük bir sayı tahtada çizilen sembolleri görebilir ve teoriden uygulamaya hemen atlayabilir. Ne yazık ki, bu insanlar genellikle dogmatik, köktendinci ve en gürültülü insanlar.

1
Jarvis Jones

Bence, sorunuz "Bilgisayar bilimi derecesinin temel pratik kavramları nelerdir" ve yeniden cevap, elbette, Bilgisayar Bilimi alanında kendi lisansınızı almaktır.

Temel olarak, bir metin dosyasını okuyarak, ondan bilgi çıkararak ve ondan okuduğunuz baytlara dönüştürülene kadar, ondan okuduğunuz bilgilere dayanarak metinde dönüşümler gerçekleştirerek kendi programlama dili derleyicinizi oluşturursunuz. yükleyici (Levine'ye göre Bağlayıcılar ve Yükleyiciler). Önemsiz bir derleyici ilk kez yapıldığında oldukça titiz bir projedir.

Bir işletim sisteminin kalbi, kaynakları yöneten (ör. Bellek ayırma/ayırma) ve görevler/işlemler/programlar arasında geçiş yapan çekirdektir.

Bir birleştirici metin-> bayt dönüşümüdür.

Bu konularla ilgileniyorsanız, Linux'ta standart X86 Assembly'nin bazı alt kümelerini destekleyen bir X86 derleyicisi yazmanızı öneririm. Bu oldukça basit bir giriş noktası olacak ve sizi bu konulara tanıtacaktır. Bu bir bebek projesi değil ve size birçok şey öğretecek.

C yazma tavsiye ederim; C, bu çalışma seviyesi için ortak dildir.

1
Paul Nathan

İlk Meclis dilim olarak PDP-8'e maruz kaldığım için kutsanmıştım. PDP-8'in sadece altı talimatı vardı, bu kadar basitti ki aslında birkaç gizli bileşen tarafından uygulandıklarını hayal etmek kolaydı. Gerçekten "sihirli" bilgisayarlardan kaldırıldı.

Aynı vahiy için bir başka kapı, Knuth'un örneklerinde kullandığı "karma" Meclis dili. "Mix" bugün arkaik görünüyor, ama yine de DE-gizemli etkisi var.

1
ddyer

Derleyiciler ve programlama dilleri (ve bir tane inşa etmeyi içeren her şey - sonlu bir dilbilgisi tanımlamak ve Meclise dönüştürme gibi), bir bütün olarak sistemler hakkında çok fazla anlayış gerektiren çok karmaşık bir görevdir. Bu tür bir ders tipik olarak üniversitede 3./4. sınıf Comp Sci dersi olarak sunulur.

Önce genel olarak İşletim Sistemlerini ve mevcut dillerin nasıl derlendiğini/yürütüldüğünü (yani yerel olarak (C/C++), bir VM (Java) veya bir tercüman (Python/Javascript)).

İşletim Sistemleri dersimde (2. yılda) Abraham Silberschatz, Peter B. Galvin, Greg Gagne'ın İşletim Sistemi Kavramları kitabını kullandığımıza inanıyorum. Bu, bir işletim sisteminin her bileşeninin kapsamlı bir izlenimini veren mükemmel bir kitaptı - biraz pahalı ama buna değer ve eski/kullanılmış kopyalar etrafında yüzüyor olmalı.

0
plafond

Bu büyük bir konudur, ancak sizi bir "kitap oku, git" ile fırçalamak yerine, başınızı etrafına sarmanıza yardımcı olmak için size memnuniyetle göstereceğim.

Çoğu derleyici ve/veya tercüman şu şekilde çalışır:

Tokenize : Kod metnini tarayın ve bir jeton listesine bölün.

Bu adım zor olabilir, çünkü dizeyi boşluklara bölemezsiniz, if (bar) foo += "a string";'un 8 jetonun bir listesi olduğunu bilmelisiniz: Word, OPEN_PAREN, Word, CLOSE_PAREN, Word, ASIGNMENT_ADD, STRING_LITERAL, SONLANIRMA. Gördüğünüz gibi, kaynak kodunu boşluklara bölmek işe yaramaz, her karakteri bir sıra olarak okumalısınız, bu yüzden alfasayısal bir karakterle karşılaşırsanız, alfasayısal olmayan bir karaktere ve o dizgiye kadar karakterleri okumaya devam edersiniz. sadece okumak daha sonra sınıflandırılacak bir Word. Jetonunuzun ne kadar ayrıntılı olduğunu kendiniz belirleyebilirsiniz: _"a string"_ 'i daha sonra ayrıştırılmak üzere STRING_LITERAL adlı bir jeton olarak yutar mı, yoksa _"a string"_' i OPEN_QUOTE, UNPARSED_TEXT, CLOSE_QUOTE olarak görürse veya görmezse, kodlarken kendiniz karar vermeniz gereken birçok seçenekten sadece biridir.

Lex : Şimdi jeton listeniz var. Muhtemelen bazı belirteçleri Word gibi belirsiz bir sınıflandırma ile etiketlediniz çünkü ilk geçişte her karakter dizesinin içeriğini anlamaya çalışmak için çok fazla çaba harcamıyorsunuz. Şimdi kaynak jetonlarının listesini tekrar okuyun ve belirsiz jetonların her birini, dilinizdeki anahtar kelimelere dayalı olarak daha spesifik bir jeton türüyle yeniden sınıflandırın. Böylece, IF simgesi adı verilen özel anahtar kelimeler listenizde "if" ve "if" gibi bir Word'ünüz var, bu nedenle bu tokenin sembol türünü Word'den IF'ye ve özel anahtar kelimeler listenizde olmayan herhangi bir Word'e değiştirirsiniz Word foo gibi bir KİMLİK.

Ayrıştırma : Şimdi if (bar) foo += "a string"; şuna benzer bir lexed token listesi döndünüz: IF OPEN_PAREN IDENTIFER CLOSE_PAREN IDENTIFIER ASIGN_ADD STRING_LITERAL TERMINATOR. Adım, belirteç dizilerini ifade olarak tanımlamaktır. Bu ayrıştırma. Bunu aşağıdaki gibi bir dilbilgisi kullanarak yaparsınız:

STATEMENT: = ASIGN_EXPRESSION | IF_STATEMENT

IF_STATEMENT: = EĞER, PAREN_EXPRESSION, STATEMENT

ASIGN_EXPRESSION: = KİMLİK, ASIGN_OP, VALUE

PAREN_EXPRESSSION: = OPEN_PAREN, VALUE, CLOSE_PAREN

DEĞER: = KİMLİK | STRING_LITERAL | PAREN_EXPRESSION

ASIGN_OP: = EŞİT | ASIGN_ADD | ASIGN_SUBTRACT | ASIGN_MULT

"|" Kullanan yapımlar terimler arasında "bunlardan herhangi biriyle eşleştir", terimler arasında virgül varsa "bu terimler dizisiyle eşleş" anlamına gelir

Bunu nasıl kullanıyorsunuz? İlk jetondan başlayarak, jeton dizinizi bu prodüksiyonlarla eşleştirmeye çalışın. İlk olarak token listenizi STATEMENT ile eşleştirmeye çalışın, böylece STATEMENT kuralını okudunuz ve "STATEMENT ya bir ASIGN_EXPRESSION ya da IF_STATEMENT" diyor, bu yüzden önce ASIGN_EXPRESSION ile eşleşmeye çalışıyorsunuz, bu yüzden ASIGN_EXPRESSION için dilbilgisi kuralına bakıyorsunuz ve "ASIGN_EXPRESSION bir IDENTIFIER, ardından ASIGN_OP ve ardından bir VALUE gelir, bu nedenle IDENTIFIER için dilbilgisi kuralına bakıyorsunuz ve IDENTIFIER için bir dilbilgisi ruke olmadığını görüyorsunuz, bu da IDENTIFIER için bir" terminal "anlamına geliyor. Doğrudan jetonunuzla eşleştirmeyi deneyebilirsiniz, ancak ilk kaynak simgeniz bir IF'dir ve IF bir IDENTIFIER ile aynı değildir, bu yüzden maç başarısız oldu. Şimdi ne var? STATEMENT kuralına geri dönüp deneyin IF_STATEMENT araması, IF ile başlar, IF araması, IF bir terminaldir, terminali ilk simgenizle karşılaştırırsanız, IF token eşleşmeleri, müthiş devam eder, bir sonraki terim PAREN_EXPRESSION, PAREN_EXPRESSION araması değil bir terminal, ilk terim nedir, PAREN_EXPRESSION OPEN_PAREN ile başlar, OPEN_PAREN araması, bir terminal, OPEN_PAREN ile bir sonraki simgenizle eşleşir, eşleşir, vb.

Bu adıma yaklaşmanın en kolay yolu, eşleştirmeye çalıştığınız kaynak kodu belirtecini ve eşleştirmeye çalıştığınız dilbilgisi terimini ilettiğiniz parse () adlı bir işleve sahip olmanızdır. Dilbilgisi terimi bir terminal değilse, yinelersiniz: parse () öğesini yine aynı kaynak belirtecini ve bu dilbilgisi kuralının ilk terimini geçirerek çağırırsınız. Bu nedenle buna "özyinelemeli iniş ayrıştırıcısı" denir. Ayrıştırma () işlevi, kaynak belirteçlerini okumadaki geçerli konumunuzu döndürür (veya değiştirir), temel olarak eşleşen dizideki son belirteci geri gönderir ve sonraki çağrıyı devam ettirirsiniz. oradan ayrıştır ().

Parse () yöntemi ASIGN_EXPRESSION gibi bir üretimle her eşleştiğinde, bu kod parçasını temsil eden bir yapı oluşturursunuz. Bu yapı, orijinal kaynak belirteçlerine referanslar içerir. Bu yapıların bir listesini oluşturmaya başlarsınız. Tüm bu yapıya Soyut Sözdizimi Ağacı (AST) diyeceğiz

Derleme ve/veya Yürütme : Dilbilginizdeki bazı prodüksiyonlar için AST yapısı verildiğinde) işleyici işlevleri oluşturdunuz AST yığınını derler ya da yürütür.

Öyleyse AST) parçanıza bakalım. Yani bir tercüman olarak ASIGN_ADD_execute () fonksiyonunuz var. Bu fonksiyon AST _foo += "a string"_ için ayrıştırma ağacına karşılık gelir, bu nedenle bu işlev bu yapıya bakar ve yapıdaki ilk terimin bir IDENTIFIER olması ve ikinci terimin VALUE olduğunu bilir, bu yüzden ASIGN_ADD_execute () geçer bellekte değerlendirilen değeri temsil eden bir nesneyi döndüren bir VALUE_eval () işlevinin VALUE terimi, daha sonra ASIGN_ADD_execute () değişkenler tablonuzda "foo" araması yapar ve eval_value () işlevi tarafından döndürülene bir başvuru saklar .

Bu bir tercüman. Derleyici bunun yerine işleyici işlevlerinin yürütmek yerine AST bayt koduna veya makine koduna çevirmesini sağlar.

1-3 ve 4 numaralı adımlar Flex ve Bison gibi araçlar kullanılarak daha kolay hale getirilebilir. (diğer adıyla Lex ve Yacc) ancak sıfırdan bir tercüman yazmak, muhtemelen herhangi bir programcının başarabileceği en güçlendirici egzersizdir. Diğer tüm programlama zorlukları bu zirveden sonra önemsiz görünüyor.

Benim tavsiyem küçük başlamak: küçük bir dilbilgisi olan küçük bir dil ve birkaç basit ifadeyi ayrıştırmayı ve yürütmeyi deneyin, sonra oradan büyütün.

Bunları okuyun ve iyi şanslar!

http://www.iro.umontreal.ca/~felipe/IFT2030-Automne2002/Complements/tinyc.c

http://en.wikipedia.org/wiki/Recursive_descent_parser

0
snorkel

Bilgisayar alanı karmaşıktır çünkü birçok yönden gelişmek için zamanı olmuştur. Kalbinde sadece hesaplayan makinelerle ilgilidir.

En sevdiğim çok temel bilgisayar Harry Porter'ın Röle Bilgisayarı . Bir bilgisayarın temel seviyede nasıl çalıştığına dair bir lezzet verir. Ardından, diller ve işletim sistemleri gibi şeylerin neden gerekli olduğunu anlamaya başlayabilirsiniz.

Mesele şu ki, neye ihtiyacı olduğunu anlamadan hiçbir şeyi anlamak zordur . İyi şanslar ve sadece şeyleri okumayın. şeyler yapın.

0
Mike Dunlavey