Bagaimana saya harus mengimplementasikan aplikasi pemrosesan perintah?

9

Saya ingin membuat aplikasi sederhana, proof-of-concept (REPL) yang mengambil nomor dan kemudian memproses perintah pada nomor itu.

Contoh: Saya mulai dengan 1. Lalu saya menulis " add 2", ia memberi saya 3. Lalu saya menulis " multiply 7", ia memberi saya 21. Kemudian saya ingin tahu apakah itu prima, jadi saya menulis " is prime" (pada nomor saat ini - 21), itu memberi saya salah. " is odd" akan memberiku kebenaran. Dan seterusnya.

Sekarang, untuk aplikasi sederhana dengan beberapa perintah, bahkan yang sederhana switchakan dilakukan untuk memproses perintah. Tetapi jika saya ingin diperpanjang, bagaimana saya perlu menerapkan fungsi? Apakah saya menggunakan pola perintah? Apakah saya membuat parser / juru bahasa sederhana untuk bahasa ini? Bagaimana jika saya ingin perintah yang lebih rumit, seperti " multiply 5 until >200"? Apa cara mudah untuk memperpanjangnya (menambahkan perintah baru) tanpa mengkompilasi ulang?

Sunting: untuk memperjelas beberapa hal, tujuan akhir saya bukan untuk membuat sesuatu yang mirip dengan WolframAlpha, melainkan daftar (jumlah) prosesor. Tapi saya ingin memulai dengan lambat pada awalnya (pada nomor tunggal).

Saya memikirkan sesuatu yang mirip dengan cara orang menggunakan Haskell untuk memproses daftar, tetapi versi yang sangat sederhana. Saya ingin tahu apakah sesuatu seperti pola perintah (atau yang setara) akan mencukupi, atau jika saya harus membuat bahasa mini baru dan pengurai untuk mencapai tujuan saya?

Edit2: Terima kasih atas semua tanggapannya, semua sangat membantu saya, tetapi Emmad Kareem paling membantu saya, jadi saya akan memilihnya sebagai jawabannya. Terima kasih lagi!

Nini Michaels
sumber
2
Saya tidak mendapatkan downvotes. Harap sebutkan alasan Anda agar saya dapat merumuskan pertanyaan saya dengan lebih baik lain kali.
Nini Michaels
2
Saya sangat suka pertanyaan ini. Looking forward untuk melihat apa yang disarankan orang desain. Apakah Anda secara khusus mencari desain berorientasi objek (Anda menyebutkan pola perintah, yang merupakan pola OO)?
Bjarke Freund-Hansen
terima kasih :) ya, saya lebih suka OOP, tapi saya tidak akan keberatan jika metode lain disarankan!
Nini Michaels
2
Tampaknya implementasi Notasi Polandia Terbalik , subjek pemrograman yang sangat keren!
Alberto De Caro
2
Anda mungkin tidak menyukai klausa buku dari pertanyaan apa yang seharusnya tidak saya tanyakan di sini? di FAQ, yaitu Jika Anda dapat membayangkan seluruh buku yang menjawab pertanyaan Anda, Anda terlalu banyak bertanya .
Mark Booth

Jawaban:

5

Ini terdengar seperti juru bahasa. Sepertinya Anda lebih khawatir tentang implementasi daripada fungsionalitas terperinci (saya hanya menebak-nebak di sini). Proyek ini jika diperpanjang bukanlah tugas yang sepele. Pastikan Anda mempelajari ruang lingkup dengan jelas karena ini membutuhkan pendekatan teknik dan bukan pendekatan pengembangan ad-hoc untuk mendapatkan produk yang dapat diandalkan daripada produk dengan 1000 tambalan yang kadang-kadang hanya berfungsi.

Tentukan sintaks dan siap untuk menguraikannya dan melakukan pemeriksaan sintaksis yang diperlukan. Tautan ini dapat membantu Anda dengan ini: Buat parser Anda sendiri .

Lihatlah: topik ini karena menyentuh berbagai aspek pekerjaan, juga ada tautan bagus yang dapat membantu Anda (khususnya jawaban oleh RMK) .: Membuat juru bahasa . Anda mungkin ingin melihat contoh proyek yang terlihat bagus yang agak mirip di: Ultimate Scientific Calculator yang Dapat Diprogram . Anda dapat menemukan kode sumber dan program kerja untuk juru bahasa command line C # di sini Command-Line-Implementation-of-C # -Made-for-Teaching . Menggunakan kompiler untuk melakukan tugas-tugas kompleks untuk Anda seperti penguraian dan pengetikan variabel, dll. Mungkin merupakan cara cerdas untuk menghindari kompleksitas penulisan semua ini sendiri. Juga, ada opsi Mono yang menyediakan fitur charp shell yang mungkin ingin Anda lihat: CsharpRepl .

Tidak ada kesempatan
sumber
Terima kasih, tautan Anda sangat membantu! Jadi saya kira seorang juru bahasa akan menjadi pilihan terbaik jika saya ingin memperpanjangnya dengan mudah.
Nini Michaels
Terima kasih atas umpan baliknya, saya kira mulai dengan tautan ke CodeProject mungkin ide yang bagus.
NoChance
2

Kecuali jika Anda secara khusus tertarik untuk menulis parser yang sebenarnya untuk Anda sendiri, saya sarankan untuk melihat pada salah satu kerangka generator parser. Untuk C Anda memiliki YACC atau Bison , tetapi harus ada alternatif lain untuk bahasa lain jika Anda mau.

Ini menghilangkan kompleksitas tata bahasa kompleks parsing dan memungkinkan Anda berkonsentrasi pada tugas yang ingin Anda lakukan. Tentu saja ini mungkin berlebihan untuk tata bahasa yang Anda sarankan dalam pertanyaan, tetapi karena Anda menyebutkan memiliki pilihan untuk memperluas ke tata bahasa yang lebih kompleks nanti, setidaknya layak mendapatkan inspirasi dari kerangka kerja ini.

Harald
sumber
1
Masalah dengan kebanyakan generator parser adalah bahwa artefaknya statis, dan tidak mudah dipasangkan. Saya pikir OP akan lebih baik dilayani dengan sesuatu yang lebih seperti mesin aturan, di mana "aturan" (kata kunci dan sintaksis) disimpan dalam struktur data yang fleksibel dan dievaluasi setelah setiap input.
TMN
2

Apa yang Anda gambarkan sangat dekat dengan bahasa stack .

Misalnya dalam Faktor apa yang Anda gambarkan akan dilakukan

1
2 +
7 *
even? not

Atau Anda bisa mendefinisikan kata-kata Anda sendiri dan kemudian menggunakannya, seperti

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

Dengan definisi-definisi ini, contoh di atas menjadi

1
2 add
7 multiply
odd?

Biasanya bahasa stack sepele untuk diurai karena mereka menggunakan kata-kata tunggal yang dipisahkan oleh ruang. Saya sarankan Anda melihat Factor - mungkin apa yang Anda inginkan. Seharusnya mudah untuk mendefinisikan kata-kata yang melakukan pemrosesan yang Anda butuhkan.

EDIT : Jika Anda benar-benar ingin merancang bahasa yang serupa, saya sarankan Anda bermain dengan salah satu dari mereka. Mengurai bahasa tumpukan itu sepele - Anda terpecah pada ruang kosong, dan implementasi pemrosesan yang naif mudah: Anda hanya perlu mengurus apa yang terjadi pada tumpukan.

Andrea
sumber
Ini terdengar sangat mudah, dan tempat yang bagus untuk memulai. Terima kasih!
Nini Michaels
1

Tetapi jika saya ingin diperpanjang, bagaimana saya perlu menerapkan fungsi?

Anda seharusnya tidak. Extensibility menciptakan banyak kompleksitas untuk keuntungan yang sangat sedikit. Yang mengatakan, Anda harus memberikan pengait ke kondisi yang ada. Cara untuk melihat status, mengubah status, dan menyediakan mekanisme untuk mengembalikan hasil lainnya (cetak ke layar). Anda akan membutuhkan cara untuk kode inti untuk menemukan modul, memuatnya, dan mengirimkan perintah kepada mereka.

Apakah saya menggunakan pola perintah?

Anda bisa, tetapi kemungkinan tidak tepat.

Anda tidak akan mengambil seluruh input dan mengirimkannya untuk diproses, tetapi menguraikan input, kirim ke penangan yang benar dan biarkan ia melakukan tugasnya. Perintah itu tidak berbeda dalam komunikasi itu; jadi tidak ada pola perintah.

Apakah saya membuat parser / juru bahasa sederhana untuk bahasa ini?

Anda akan membutuhkan sesuatu untuk menangani pemecahan input menjadi token. Untuk solusi yang dapat dikembangkan, Anda mungkin tidak akan berbuat banyak lagi. Untuk solusi yang terdefinisi dengan baik, memiliki parse tree penuh akan memberikan kinerja yang lebih baik, penanganan kesalahan, dan kemampuan debug.

melainkan daftar (angka) prosesor

Maka mungkin Anda harus melihat ke dalam bahasa Pemrosesan LISt . Penjajaran kode dan data harus sesuai dengan apa yang Anda gambarkan.

Telastyn
sumber
Terima kasih atas sarannya. Sedangkan untuk LISP, saya akrab dengannya, dan bahkan lebih akrab dengan Haskell, yang menginspirasi saya dengan ide ini. Namun, meskipun saya mungkin menemukan kembali roda sedikit, saya ingin tangan saya kotor dengan memproses perintah dan menafsirkannya. Jadi ia juga memiliki tujuan pendidikan selain "pemrosesan daftar" yang sebenarnya :)
Nini Michaels
@NiniMichaels tentu saja, tetapi sejauh desain untuk ekstensibilitas berjalan, menggunakan organisasi / rantai kode / data lisp bukanlah pilihan yang buruk.
Telastyn