Y'de Z'ye bir X derleyicisi yazmak için genel kurallar


9

X'in giriş dili, Z'nin çıkış dili olduğunu, sonra f'nin Y dilinde yazılan derleyici olduğunu varsayalım.

f = X -> Z

F sadece bir program olduğundan, Y'nin herhangi bir dil olabileceğini düşünüyorum, değil mi? Yani her biri Y1, Y2 ile yazılmış f1, f2 derleyicilerine sahip olabiliriz.

f1 = f Y1    
f2 = f Y2

g = Z -> M
h = g . f    # We get a compiler X -> M

Örneğin cpython derleyicisini ele alalım, X Python, Z Python VM kodudur, Y C'dir.

cpython = Python -> PythonVMCode C
interpreter = PythonVMCode -> Nothing
interpreter2 = PythonVMCode -> MachineCode

Python kaynakları Python VM koduna, .pyc dosyalarına derlenir ve ardından yorumlayıcı tarafından yorumlanır. Uygulaması çok zor olsa da, doğrudan Python -> MachineCode yapabilen bir derleyici var gibi görünüyor:

   hardpython = interpreter2 . cpython 

Python -> PythonVMCode işini yapan başka bir derleyici yazabiliriz, başka bir dilde, Python'un kendisi.

mypython = Python -> PythonVMCode Python
mypython2 = Python -> PythonVMCode Ruby

Şimdi, karmaşık örnek PyPy. Ben sadece PyPy'nin bir acemisiyim, yanılıyorsam beni düzeltin:

PyPy doc http://doc.pypy.org/tr/latest/architecture.html#pypy-the-translation-framework

Amacımız dil uygulayıcıları sorununa olası bir çözüm sunmaktır: l dinamik diller için l * o * p tercümanları ve önemli tasarım kararlarına sahip p platformları yazmak zorunda kalmak.

L'nin X, p'nin Y olduğunu düşünebiliriz. Tüm RPython programlarını C'ye çeviren bir program var:

 rpython_compiler = RPython -> C  Python

 pypy = Python -> Nothing RPython

 translate = compile the program pypy written in RPython using rpython_compiler

 py2rpy = Python -> RPython  Python
 py2c = Python -> C Python 
 py2c = rpython_compiler . py2rpy

RPython programları tıpkı VM talimatları gibidir, rpython_compiler VM'dir.

q1. pypy yorumlayıcıdır, Python kodunu yorumlayabilen bir RPython programıdır, çıktı dili yoktur, bu yüzden onu derleyici olarak kabul edemeyiz, değil mi?

Katma:

  • Ben sadece çeviri sonra bile, pypy hala bir tercüman olduğunu, sadece bu sefer C ile yazılmış buldum.
  • Tercüman pypy'nin derinliklerine bakarsak, Python kaynaklarını bir AST'ye derleyen bir tür derleyici olması gerektiğine inanıyorum.

bunun gibi:

compiler_inside_pypy = Python -> AST_or_so

q2. Bütün Python programlarını RPython'a dönüştüren py2rpy derleyicisi var olabilir mi? Hangi dilde yazıldığı önemsiz. Evet ise, başka bir derleyici py2c alırız. Doğada pypy ve py2rpy arasındaki fark nedir? Py2rpy yazmak pypy'den daha mı zor?

q3. Bununla ilgili bazı genel kurallar veya teoriler var mı?

Daha fazla derleyici:

gcc_c = C -> asm? C  # not sure, gimple or rtl?
g++ =   C++ -> asm? C
clang = C -> LLVM_IR  C++
jython = Python -> JVMCode java
ironpython = Python -> CLI C#

q4. X ile yazılmış bir P programı olan f = X -> Z verildi. P'yi hızlandırmak istediğimizde ne yapabiliriz? Olası yollar:

  • P'yi daha verimli algoritmada yeniden yaz

  • daha iyi Z oluşturmak için f'yi yeniden yaz

  • Z yorumlanırsa, daha iyi bir Z tercümanı yazın (PyPy burada mı?)

  • Z ile yazılmış programları özyinelemeli olarak hızlandırma

  • daha iyi bir makine al

ps. Bu soru, bir derleyicinin nasıl yazılacağıyla ilgili teknik konularla ilgili değil, belirli bir tür derleyicinin yazılmasının fizibilitesi ve karmaşıklığı ile ilgilidir.


Doğrudan ilgili değil, ama benzer bir kavram: en.wikipedia.org/wiki/Supercompilation
SK-logic

1
Bu sorunun gerçekten Stack Overflow'a uyduğundan emin değilim, özellikle de çok fazla alt soru olduğu için, ama yine de buna giren düşünceye hayranım.

4
Size öğretilenlere rağmen, bir AST gerekli değildir - bu sadece bazı derleyicilerin kullandığı bir stratejidir.

1
Muhtemelen bu cstheory.stackexchange.com'a aittir
9000

3
PyPy'nin Python uygulaması, çoğu "tercüman" gibi, gerçekten bir bayt kodu derleyicisi ve bu bayt kodu biçimi için bir yorumlayıcıdır.

Yanıtlar:


4

q1. pypy yorumlayıcıdır, Python kodunu yorumlayabilen bir RPython programıdır, çıktı dili yoktur, bu yüzden onu derleyici olarak kabul edemeyiz, değil mi?

PyPy, CPython'a benzer, her ikisinin de bir derleyici + yorumlayıcısı vardır. CPython, C'de yazılmış ve Python'u Python VM bayt kodunu derleyen bir derleyiciye sahiptir ve daha sonra bayt kodunu C ile yazılmış bir yorumlayıcıda yürütür.

q2. Bütün Python programlarını RPython'a dönüştüren py2rpy derleyicisi var olabilir mi? Hangi dilde yazıldığı önemsiz. Evet ise, başka bir derleyici py2c alırız. Doğada pypy ve py2rpy arasındaki fark nedir? Py2rpy yazmak pypy'den daha mı zor?

Bir derleyici py2rpy mevcut olabilir mi? Teorik olarak evet. Turing tamlık garanti eder.

Yapı için bir yöntem py2rpybasitçe oluşturulan kaynak kodunda RPython yazılmış bir Python yorumlayıcısı kaynak kodunu eklemektir. Bash ile yazılmış py2rpy derleyicisine bir örnek:

// suppose that /pypy/source/ contains the source code for pypy (i.e. Python -> Nothing RPython)
cp /pypy/source/ /tmp/py2rpy/pypy/

// suppose $inputfile contains an arbitrary Python source code
cp $inputfile /tmp/py2rpy/prog.py

// generate the main.rpy
echo "import pypy; pypy.execfile('prog.py')" > /tmp/py2rpy/main.rpy

cp /tmp/py2rpy/ $outputdir

Şimdi bir Python kodunu RPython koduna çevirmeniz gerektiğinde, $ outputdir içinde bir RPython main.rpy, RPython'un Python Interpreter kaynak kodu ve ikili bir blob prog.py üreten bu komut dosyasını çağırırsınız. Ve sonra oluşturulan RPython betiğini çağırarak yürütebilirsiniz rpython main.rpy.

(not: rpython projesine aşina olmadığımdan, rpython yorumlayıcısını çağırmak için kullanılan sözdizimi, pypy'yi içe aktarma ve pypy.execfile yapma yeteneği ve .rpy uzantısı tamamen oluşturulmuştur, ancak bence bu konuyu anlamışsınızdır)

q3. Bununla ilgili bazı genel kurallar veya teoriler var mı?

Evet, herhangi bir Turing Complete dili teorik olarak herhangi bir Turing Complete diline çevrilebilir. Bazı dilleri çevirmek diğer dillerden çok daha zor olabilir, ancak soru "mümkün mü?" İse, cevap "evet" dir.

q4. ...

Burada soru yok.


Py2rpy derleyiciniz gerçekten zekidir. Beni başka bir fikre götürüyor. 1. Pypy'nin derleyicinizde RPython ile yazılması gerekiyor mu? Tek ihtiyacınız olan bir şey Python dosyalarını yorumlayabilir, değil mi? 2. os.system ('python $ inputfile'), RPython'da destekleniyorsa da çalışabilir. Hala derleyici olarak adlandırılıp adlandırılamayacağından emin değilim, en azından kelimenin tam anlamıyla değil.

Pypy hala Python VM kullanıyor mu? Şimdi açık. pypy_the_compiler = Python -> PythonVMCode RPython, pypy_the_interpreter = PythonVMCode -> Hiçbir şey RPython, cpython_the_compiler = Python -> PythonVMCode C cpython_the_interpreter = PythonVMCode -> Hiçbir şey C

@jaimechen: Does pypy have to be written in RPython in your compiler?Hayır, RPython'da yazılmasına gerek yoktur, ancak RPython'un bir Python kodu yürütmesi için "yardımcı yorumlayıcıya" / "çalışma zamanına" söyleyebilmesi gerekir. Evet, bu pratik anlamda bir "derleyici" değil, ancak yazmanın mümkün olduğuna dair yapıcı bir kanıt Python -> RPython. Is pypy still using the Python VM?Pypy'nin CPython'u hiç kullanmadığına inanıyorum (yanlış olabilirim), bunun yerine PyPy'nin RPython'da yazılmış kendi "Python VM" uygulaması vardır.
Yalan Ryan

@jaimechen: daha pratik bir derleyici, giriş dosyasını muhtemelen bunları nasıl derleyeceğini ve derleyeceğini bildiği kod dizileri ve "yeniden derlenmiş-RPython" Python ve "yorumlayıcı arasında ileri geri atlamanın bir yolu için analiz edebilir destekli "Python. Ayrıca, belirli bir girdinin RPython ve Python'un semantikindeki farklılıklar ve bu durumlarda yoruma geri dönüş nedeniyle farklı çıktı üretip üretemeyeceğini tespit etmek için JIT derlemesinde yaygın olarak kullanılan teknikleri kullanabilir. Bütün bunlar daha pratik bir Python -> RPythonderleyicide görülebilecek karmaşıklıklardır .
Yalan Ryan

Belki buraya bir kısıtlama eklenmelidir: durum makine X'i mevcut bir 3. makine yardımı olmadan durum makine Z'ye dönüştürün. Bu, X'in tamamen yeni olduğu, şimdiye kadar hiçbir derleyici veya tercüman bulunmadığı durumdur.
jaimechen

2

Sadece q2'ye cevap vermek için, William McKeeman tarafından, Y dili çıktı dili Z üreten X dilinde yazılmış derleyiciler teorisinin bir T-diyagram sistemi aracılığıyla araştırıldığı bir derleyici kitap vardır. 1970'lerde yayınlanan, el değil başlık, üzgünüm.


Evet, bu kadar, teşekkürler. en.wikipedia.org/wiki/Tombstone_diagram
jaimechen

1

q1. Genellikle, bir tercüman derleyici değildir. Derleyici ve yorumlayıcı arasındaki temel fark, bir yorumlayıcının her seferinde kaynak kodda kaynak kodla yeni başlamasıdır. Pypy'niz bunun yerine pyAST veya pyP-koduysa ve daha sonra bir AST veya P-kod yorumlayıcısına sahipseniz, pyAST'a bir derleyici diyebilirsiniz. Eski UCSD PASCAL derleyicisi bu şekilde çalıştı (ve birkaç tane daha): program çalıştırıldığında yorumlanan bazı P kodlarına derlediler. (Oluşturulan nesne kodunun kompaktlığı hızdan çok daha önemli olduğunda .NET bile böyle bir şey sağlar.)

q2. Evet tabi ki. Bkz. UCSD PASCAL (ve diğerleri).

q3. Bilgisayar bilimindeki klasik metinleri araştırın. Eşzamanlı PASCAL'de Per Brinch-Hansen tarafından (eğer bellek bana hizmet ediyorsa) okuyun. Derleyiciler ve kod üretimi hakkında çok şey yazıldı. Makineden bağımsız bir sözde kod oluşturmak genellikle makine kodu oluşturmaktan çok daha kolaydır: sözde kod genellikle gerçek makinelerin her zaman içerdiği tuhaflıklardan arındırılmıştır.

q4. Oluşturulan nesnenin daha hızlı çalışmasını istiyorsanız, daha iyi optimizasyon yapmak için derleyiciyi daha akıllı hale getirirsiniz. Nesneniz yorumlanırsa, daha karmaşık işlemleri ilkel sözde yapılara (CISC ve RISC analojisidir) itmeyi düşünürseniz, yorumlayıcınızdaki çatlamayı optimize etmek için elinizden gelenin en iyisini yaparsınız.

Derleyicinizin daha hızlı çalışmasını istiyorsanız, kaynak kodunuzu yeniden düşünmek de dahil olmak üzere HER ŞEY'e bakmanız gerekir. Derleyicinin kendisini yükledikten sonra, derlemenin en çok zaman alan kısmı her zaman derleyiciye kaynak kodunu okumaktır. (Örneğin C ++ 'ı düşünün. Diğer tüm şeyler nispeten eşittir, basit bir "Merhaba, Dünya" programını derlemek için 9.000 (veya belki 50.000) satırlık #include dosyasını parçalamak zorunda olan bir derleyici hiçbir zaman bu kadar hızlı olmayacaktır. yalnızca dört veya beş satır okuması gerekir.)

Nerede okuduğumu hatırlamıyorum, ancak ETH-Zürih'teki orijinal Oberon derleyicisinin oldukça sofistike bir sembol masa mekanizması vardı. Wirth'in derleyici performansı için ölçütü derleyicinin kendini derlemesi için geçen zamandı. Bir sabah içeri girdi, muhteşem çok bağlantılı ultra ağaç sembol tablosunu çıkardı ve basit bir doğrusal dizi ve düz doğrusal aramalarla değiştirdi. Grubundaki yüksek lisans öğrencileri ŞOKLENDİ. Değişiklikten sonra derleyici daha hızlıydı, çünkü derlediği modüller her zaman zarif canavarın doğrusal dizi ve doğrusal aramadan daha fazla toplam yük getirdiği kadar küçüktü.


1
Teşekkürler. Bir derleyici 'derler', bir tercüman 'yürütürken', türleri farklı olduğu gibi iki tür program hakkında daha fazla bilgi olabilir mi?
jaimechen

1

Belirttiğiniz sorular beni gerçekten istediğiniz / ihtiyacınız olan şeyin bir derleyicinin ne olduğunu, bir tercümanın ne olduğunu ve ikisi arasındaki farkların bir açıklaması olduğuna inanmamı sağlıyor.

Bir derleyici , X dilinde yazılmış bir programı Y dilinde yazılmış işlevsel olarak eşdeğer bir programla eşleştirir. Örneğin, Pascal'dan C'ye derleyici derleyebilir

function Square(i: Integer)
begin
    Square := i * i
end

için

int Square(int i)
{
    return i * i;
}

Çoğu derleyici 'aşağı' derler, bu nedenle üst düzey programlama dillerini alt düzey dillere derler, en üst düzey dil makine kodu olur.

Çoğu derleyici doğrudan makine kodunu derler, ancak bazı (özellikle Java ve .NET dilleri) 'bytecode' ( Java bytecode ve CIL ) derler . Bytecode'u varsayımsal bir bilgisayar için makine kodu olarak düşünün. Bu bayt kodu daha sonra çalıştırıldığında yorumlanır veya JIT'tir (daha sonra daha fazla).

Bir tercüman Z dilinde yazılmış bir programı yürütür. Bir tercüman bir programı yavaş yavaş okur ve devam ederken yürütür. Örneğin:

int i = 0;
while (i < 1)
{
    i++
}
return i;

Tercümanın o program hattına hat için baktığını, hattı incelediğini, ne yaptığını yürüttüğünü, bir sonraki satıra ve benzerlerine baktığını düşünün.

Bir tercümanın en iyi örneği bilgisayarınızın CPU'sudur. Makine kodunu yorumlar ve yürütür. CPU'nun çalışma şekli, fiziksel olarak nasıl oluşturulduğu ile belirlenir. Bir tercüman programının nasıl çalıştığı, kodunun nasıl göründüğüne göre belirlenir. Bu nedenle CPU tercüman programını yorumlar ve yürütür, bu da girişini yorumlar ve yürütür. Tercümanları bu şekilde zincirleyebilirsiniz.

JITter , Tam Zamanında bir derleyicidir. JITter bir derleyicidir. Tek fark, yürütüldüğü zamandır: çoğu program yazılır, derlenir, kullanıcılarına gönderilir ve sonra yürütülür, ancak Java bayt kodu ve CIL önce kullanıcılarına gönderilir ve daha sonra yürütülmeden önce makineye derlenirler kullanıcılarının kodu.

C # -> (derleme) -> CIL -> müşteriye sevk -> (yürütmeden hemen önce derleme) -> makine kodu -> (yürütme)

Hakkında bilmek isteyeceğiniz son şey Turing tamlığıdır ( link ). Bir programlama dili, bir ' Turing makinesinin ' yapabileceği her şeyi hesaplayabiliyorsa, Turing Complete'tir , yani en azından Turing makinesi kadar 'güçlü' demektir. Church-Turing tezi bir Turing makinesi, en azından şimdiye kadar oluşturabileceği herhangi makine kadar güçlü olduğunu belirtmektedir. Sonuç olarak, her Turing tam dili Turing makinesi kadar güçlüdür ve bu nedenle tüm Turing tam dilleri eşit derecede güçlüdür.

Başka bir deyişle, programlama diliniz Turing tamamlandığında (neredeyse hepsi), hangi dili seçtiğinizin bir önemi yoktur, çünkü hepsi aynı şeyleri hesaplayabilir. Bu aynı zamanda derleyicinizi veya tercümanınızı yazmak için hangi programlama dilini seçtiğinizin çok önemli olmadığı anlamına gelir. Son olarak, X ve Y'nin her ikisi de Turing tamamlanmışsa, her zaman X'den Y'ye bir derleyici yazabileceğiniz anlamına gelir.

Turing tamamlandığında, dilinizin etkili olup olmadığı veya CPU'nuzun ve diğer donanımınızın tüm uygulama ayrıntıları veya dil için kullandığınız derleyicinin kalitesi hakkında hiçbir şey söylemediğini unutmayın. Ayrıca, işletim sisteminiz programınızın bir dosyayı açma haklarına sahip olmadığına karar verebilir, ancak bu hiçbir şeyi hesaplama yeteneğinizi engellemez - Kasıtlı olarak bilgisayar tanımlamamıştım, çünkü bu başka bir metin duvarı gerektirecektir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.