İf () tembel değerlendirmesi nasıl yapılır


10

Şu anda aşağıdakilere dayalı bir ifade değerlendiricisini (formül gibi tek satır ifadeleri) kullanıyorum:

  • girilen ifade, değişmez booleanları, tam sayıları, ondalıkları, dizeleri, işlevleri, tanımlayıcıları (değişkenleri) ayırmak için tokenleştirilir
  • Parantezden kurtulmak ve operatörleri iyi bir önceliğe sahip bir şekilde sipariş vermek için Shunting-yard algoritmasını (değişken değişkenli fonksiyonları işlemek için hafifçe değiştirildi) uyguladım
  • manevra alanım basitçe (simüle edilmiş) bir token kuyruğu üretir (bir dizi aracılığıyla, Powerbuilder Klasik dilim nesneleri tanımlayabilir, ancak sıralı olarak değerlendirdiğim yalnızca yerel depolama olarak dinamik dizilere sahiptir - gerçek liste değil, sözlük yok) basit yığın makinesi

Değerlendiricim iyi çalışıyor, ancak hala bir eksikim if()ve nasıl devam edeceğimizi merak ediyorum.

Benim manevra sonrası düzeltilmiş ve yığın tabanlı değerlendirme if()ile, doğru ve yanlış parçaları ile başka bir işlev olarak eklerseniz , tek bir if(true, msgbox("ok"), msgbox("not ok"))göstermek istiyorum iken tek bir her iki iletileri gösterecektir. Çünkü bir işlevi değerlendirmem gerektiğinde, tüm argümanları zaten değerlendirilmiş ve yığına yerleştirilmiştir.

if()Tembel bir şekilde uygulamak için bana bir yol verebilir misiniz ?

Bunları bir tür makro olarak işlemeyi düşünüyorum, ama erken zamanda henüz durum değerlendirmesi yapmadım. Belki de koşulu ve doğru / yanlış ifadeleri ayrı tutmak için sıradan başka bir yapı kullanmam gerektiğini mi? Şimdilik ifade değerlendirmeden önce ayrıştırılıyor, ancak aynı zamanda ara gösterimi gelecekteki değerlendirme için önceden derlenmiş ifade olarak saklamayı da planlıyorum.

Düzenleme : sorun olsa bazı sonra, ben kolayca bir ya da başka bir dalı görmezden olabilir benim ifade (doğrusal bir belirteci akışı yerine bir AST) bir ağaç temsili inşa edebilirsiniz düşünüyorum if().

Yanıtlar:


9

Burada iki seçenek var.

1) ifFonksiyon olarak uygulama . Özel semantik ile bir dil özelliği yapın. Yapması kolay, ancak her şeyin bir işlev olmasını istiyorsanız daha az "saf".

2) Çok daha karmaşık olan "derleme adı" anlambilimini uygulayın, ancak derleyici büyüsünün ifbir dil öğesi yerine bir işlev olarak tutarken tembel değerlendirme problemine bakmasına izin verir . Bu böyle devam ediyor:

ifher ikisi de "ada göre" olarak bildirilen iki parametre alan bir işlevdir. Derleyici bir adla parametresine bir şey ilettiğini gördüğünde, oluşturulacak kodu değiştirir. İfadeyi değerlendirmek ve değeri iletmek yerine, ifadeyi değerlendiren bir kapatma oluşturur ve bunun yerine geçer. Ve işlevin içinde bir by-name parametresi çağırırken, derleyici kapatmayı değerlendirmek için kod üretir.


Emin değilim, ama "kapatma" "thunk" olmalı mı? Hmm, belki değil; wikipedia sayfasına baktım: "thunk parametresiz bir kapanış".

"İsme göre çağrı" derken küresel olarak mı bahsediyorsunuz? Alternatif olarak adlandırmaya göre arama sadece bir kapatma türü uyguluyorsa, if işlevi yalnızca 3 kapatma alır ve ikisini değerlendirir (koşul ve sonra veya başka), ancak her şeyin tam arama gibi bir kapatma olarak algılanması gerekmez. anlambilim
Jimmy Hoffa

@Matt: "Thunk" terimi programlama bağlamında başka şeyler anlamına gelebilir ve bunu duyduğumda ilk düşündüğüm "parametresiz kapatma" değildir. "Kapanış" çok daha açık.
Mason Wheeler

1
@JimmyHoffa: "Adıyla çağır" dediğimde, isteğe bağlı olması gereken bir işlev bağımsız değişkeni oluşturma konusunda belirli bir stile başvuruyorum. Birçok mevcut dil gibi, bir parametre by-value veya referans olarak geçmeyi seçmenize izin verecektir, bu senaryo için isimle geçme seçeneğine ihtiyacınız vardır.
Mason Wheeler

"İsme göre çağrı" anlambilimiyle ilgili önerileriniz bana bazı ilginç noktalar göstermekle birlikte, işlev çağrıları tek satırlık olduğu için (MS-excel formüllerini düşünün) tam bir derleyici olmayan değerlendiricim için biraz abartılı. Çağıran ağacın çıkarılması için yığının sahte bir değerlendirmesini yaparak belirteçlerin sıraya alınmasından sonra bir adım ekleyebileceğimi düşünüyorum. Ağaçtan dalların atılması daha kolay olmalıdır.
Seki

3

İmzaya sahip işlev yerine:

object if(bool, object, object)

İmzayı verin:

object if(bool, object function(), object function())

Daha sonra ifişleviniz duruma göre uygun işlevi çağıracak ve bunlardan sadece birini değerlendirecektir.


1

Her şeyi tembel bir şekilde derlerseniz oldukça kolaydır. Bir değerin önceden değerlendirilip değerlendirilmediğini veya daha fazla değerlendirmeye ihtiyacı olup olmadığını görmek için bazı araçlara sahip olmanız gerekir.

Sonra aşağıdakileri yapabilirsiniz: Değişmez veya değişkense (bunlara sahip misiniz?, Yani işlevlerin adları?), Yığını yığının üzerine itin. Bir işlevin uygulamasıysa, ayrı olarak derleyin ve yığındaki giriş noktasını itin.

Bu durumda, bir programın yürütülmesi, yalnızca yığının üst kısmı değerlendirilinceye kadar döngü yapar ve bir işlev değildir. Değerlendirilmezse veya bir işlev değilse, yığının üst kısmının işaret ettiği kodu arayın.

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.