Bir komut işleme uygulamasını nasıl uygulamalıyım?


9

Bir sayı alan ve daha sonra bu sayıdaki komutları işleyen basit, bir kavram kanıtı uygulaması (REPL) yapmak istiyorum.

Örnek: 1 ile başlıyorum. Sonra " add 2" yazıyorum , bana 3 veriyor. Sonra " multiply 7" yazıyorum , bana 21 veriyor. O zaman asal olup olmadığını bilmek istiyorum, bu yüzden " is prime" yazıyorum (geçerli sayıya - 21), bana yanlış verir. " is odd" bana gerçek olur. Ve bunun gibi.

Şimdi, birkaç komut içeren basit bir uygulama switchiçin, komutların işlenmesi için basit bir uygulama bile yapılabilir . Ancak genişletilebilirlik istersem, işlevselliği nasıl uygulamam gerekir? Komut şablonunu kullanabilir miyim? Dil için basit bir ayrıştırıcı / yorumlayıcı oluşturabilir miyim? " multiply 5 until >200" Gibi daha karmaşık komutlar istersem ne olur ? Yeniden derlemeden genişletmek (yeni komutlar eklemek) için kolay bir yol ne olabilir?

Düzenleme: birkaç şeyi açıklığa kavuşturmak için, son hedefim WolframAlpha'ya benzer bir şey yapmak değil, bir sayı (sayı listesi) işlemcisidir. Ama önce yavaşça başlamak istiyorum (tek sayılarla).

Bir liste işlemek için Haskell kullanmak gibi bir şey aklıma, ama çok basit bir sürümü. Komut kalıbı (veya eşdeğeri) gibi bir şeyin yeterli olup olmadığını mı yoksa hedeflerime ulaşmak için yeni bir mini dil ve ayrıştırıcı mı yapmam gerektiğini merak ediyorum?

Edit2: Tüm cevaplar için teşekkürler, hepsi bana çok yardımcı oldu, ama Emmad Kareem bana en çok yardımcı oldu, bu yüzden cevap olarak seçeceğim. Tekrar teşekkürler!


2
Downvotes alamadım. Bir dahaki sefere sorumu daha iyi formüle edebilmem için lütfen nedeninizi belirtin.
Nini Michaels

2
Bu soruyu gerçekten seviyorum. İnsanların ne önerdiğini görmek için sabırsızlanıyoruz. Özellikle nesne yönelimli bir tasarım mı arıyorsunuz (OO kalıbı olan komut kalıbından bahsediyorsunuz)?
Bjarke Freund-Hansen

teşekkür ederim :) evet, OOP tercih ederim, ama başka yöntemler önermek sorun olmaz!
Nini Michaels

2
Çok havalı bir programlama konusu olan Reverse Polish Notation'ın bir uygulaması gibi görünüyor !
Alberto De Caro

2
Muhtemelen dışına düşme olan kitap gelen fıkra ben gereken türden sorular ne değil burada sormak? SSS bölümünde, yani sorunuzu cevaplayan bir kitabın tamamını hayal edebiliyorsanız , çok fazla şey soruyorsunuz .
Mark Booth

Yanıtlar:


5

Bu bir tercüman gibi geliyor. Uygulama hakkında ayrıntılı işlevsellikten daha fazla endişeleniyorsunuz (sadece burada tahmin ediyorum). Bu proje uzatılırsa önemsiz bir görev değildir. Kapsamı açık bir şekilde incelediğinizden emin olun, çünkü bu sadece bazen çalışan 1000 yamalı bir ürün yerine güvenilir bir ürün elde etmek için geçici bir geliştirme yaklaşımı değil, mühendislik yaklaşımı gerektirir.

Bir sözdizimine karar verin ve ayrıştırmaya hazır olun ve gerekli sözdizimi kontrollerini yapın. Bu bağlantı size şu konuda yardımcı olabilir: Kendi ayrıştırıcınızı oluşturun .

Bir göz atın: işin farklı yönlerine dokunur gibi bu konu, ayrıca size yardımcı olabilir iyi bağlantılar vardır (özellikle RMK tarafından cevap) .: Bir Dil tercüman oluşturma . Biraz benzer olan güzel görünümlü bir proje örneği görmek isteyebilirsiniz: Ultimate Programmable Scientific Calculator . Komut satırı C # yorumlayıcısının kaynak kodunu ve çalışma programını burada bulabilirsiniz C -Komut Satırı-Uygulaması-# -Eğitim Yapımı . Derleyiciyi ayrıştırma ve değişken yazma gibi karmaşık görevleri yapmak için kullanmak, tüm bunları kendiniz yazmanın karmaşıklıklarından kaçmanın akıllıca bir yolu olabilir. Ayrıca, göz atmak isteyebileceğiniz bir kabuk kabuğu özelliği sunan Mono seçeneği de vardır: CsharpRepl .


Teşekkürler, bağlantılarınız gerçekten faydalı! Kolayca genişletmek istersem, bir tercüman en iyi seçim olacaktır.
Nini Michaels

Geri bildiriminiz için teşekkür ederiz, sanırım CodeProject bağlantısıyla başlamak iyi bir fikir olabilir.
NoChance

2

Gerçek ayrıştırıcıyı özellikle kendiniz yazmakla ilgilenmiyorsanız, ayrıştırıcı jeneratör çerçevelerinden birine göz atmanızı öneririm. C için var Yacc veya Bison , ancak dilerseniz diğer diller için başka alternatifler olmalı.

Bunlar karmaşık gramerleri ayrıştırmanın karmaşıklığını ortadan kaldırır ve yapmak istediğiniz göreve konsantre olmanızı sağlar. Tabii ki bu, soruda önerdiğiniz dilbilgisi için aşırıya kaçabilir, ancak daha karmaşık bir dilbilgisine genişletme seçeneğinden bahsettiğinizden, en azından bu çerçevelerden biraz ilham almaya değer.


1
Ayrıştırıcı üreticilerinin çoğundaki sorun, eserlerinin statik olması ve kendilerini genişletmeye kolayca borç vermemesidir. Ben OP daha iyi bir kural motoru gibi bir şey ile hizmet olacağını düşünüyorum, nerede "kurallar" (anahtar kelimeler ve sözdizimi) esnek bir veri yapısı içinde saklanır ve her girişten sonra değerlendirilir.
TMN

2

Açıkladığınız şey bir yığın diline çok yakın .

Mesela Factor ne anlatmak gibi yapacaktı

1
2 +
7 *
even? not

Veya kendi kelimelerinizi tanımlayabilir ve daha sonra bunları kullanabilirsiniz.

: add ( x y -- sum ) + ;
: multiply ( x y -- product ) * ;
: odd? ( n -- ? ) even? not ;

Bu tanımlarla yukarıdaki örnek

1
2 add
7 multiply
odd?

Genellikle yığın dilleri ayrıştırmak önemsizdir çünkü boşlukla ayrılmış tek sözcükler kullanırlar. Factor'a bir göz atmanızı öneririm - istediğiniz şey eaxctly olabilir. İhtiyacınız olan işlemleri yapan kelimeleri tanımlamak kolay olmalıdır.

EDIT : Aslında benzer bir dil tasarlamak istiyorsanız, yine de onlardan biriyle oynamanızı öneririm. Bir yığın dilinin ayrıştırılması önemsizdir - boş alanlara ayrılırsınız ve işlemin naif bir uygulaması kolaydır: sadece bir yığınta neler olduğuna dikkat etmeniz gerekir.


Bu oldukça kolay ve başlamak için iyi bir yer gibi görünüyor. Teşekkürler!
Nini Michaels

1

Ancak genişletilebilirlik istersem, işlevselliği nasıl uygulamam gerekir?

Yapmamalısın. Genişletilebilirlik, çok az kazanç için bir çok karmaşıklık yaratır. Bununla birlikte, mevcut duruma bir kanca sağlamanız gerekecek. Durumu görmenin, durumu değiştirmenin ve diğer sonuçları döndürmek için bir mekanizma sağlamanın bir yolu (ekrana yazdır). Çekirdek kodun modülleri keşfetmesi, yüklemesi ve bunlara komut göndermesi için bir yol gerekir.

Komut şablonunu kullanabilir miyim?

Yapabilirsiniz, ancak muhtemelen uygun değildir.

Tüm girdiyi alıp işlemek için göndermeyeceksiniz, bunun yerine girdiyi ayrıştırın, doğru işleyiciye gönderin ve işini yapmasına izin verin. Komut bu iletişimde değişiklik göstermez; yani komut düzeni yok.

Dil için basit bir ayrıştırıcı / yorumlayıcı oluşturabilir miyim?

Girişi jetonlara bölmek için bir şeye ihtiyacınız olacak. Genişletilebilir bir çözüm için muhtemelen daha fazlasını yapmayacaksınız. İyi tanımlanmış bir çözüm için, tam ayrıştırma ağacına sahip olmak daha iyi performans, hata işleme ve hata ayıklama yeteneği sağlar.

daha ziyade bir liste (sayı) işlemcisi

O zaman belki de LISt İşleme diline bakmalısınız . Kod ve verilerin bir arada konumlandırılması, tanımladıklarınıza tam olarak uymalıdır.


Önerileriniz için teşekkür ederiz. LISP'ye gelince, ona aşinayım ve Haskell'e daha fazla aşinayım, bu da bana bu fikirle ilham verdi. Ancak, tekerleği biraz yeniden keşfetmiş olmama rağmen, işlem komutları ve yorumlarla ellerimi kirletmek istiyorum. Bu yüzden gerçek "liste işleme" yanında bir eğitim amacı vardır :)
Nini Michaels

@NiniMichaels kesinlikle, ancak genişletilebilirlik için bir tasarım söz konusu olduğunda, lisp'in organizasyonunu / kod / veri zincirini kullanmak kötü bir seçenek değildir.
Telastyn
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.