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 switch
akan 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!
sumber
Jawaban:
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 .
sumber
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.
sumber
Apa yang Anda gambarkan sangat dekat dengan bahasa stack .
Misalnya dalam Faktor apa yang Anda gambarkan akan dilakukan
Atau Anda bisa mendefinisikan kata-kata Anda sendiri dan kemudian menggunakannya, seperti
Dengan definisi-definisi ini, contoh di atas menjadi
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.
sumber
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.
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.
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.
Maka mungkin Anda harus melihat ke dalam bahasa Pemrosesan LISt . Penjajaran kode dan data harus sesuai dengan apa yang Anda gambarkan.
sumber