Rumah > pembangunan bahagian belakang > Tutorial Python > Membuat semula DSL enjin peraturan

Membuat semula DSL enjin peraturan

Susan Sarandon
Lepaskan: 2024-12-01 09:36:10
asal
112 orang telah melayarinya

Beberapa tahun yang lalu, saya melaksanakan semula bahasa khusus domain (DSL) yang pada asalnya direka untuk enjin peraturan di tempat kerja. Pelaksanaan semula mainan telah ditulis dalam Javascript (asalnya dalam Python), dan dikeluarkan kepada GitHub. Saya tidak menjangkakan ia akan berbuat banyak, kerana ia direka khusus untuk kes penggunaan yang sangat khusus yang tidak sepatutnya saya dedahkan.

Remaking a rule-engine DSL
Gambar yang agak comel yang dimuntahkan oleh bing copilot

Matlamat utama reka bentuk adalah sesuatu yang boleh bersiri dengan mudah. Kelengkapan Turing tidak membimbangkan, kerana saya hanya memerlukannya untuk melakukan 2 perkara sahaja:

  1. Perbandingan boolean mudah (jika x ialah == kepada y)
  2. Dapatkan nilai daripada medan daripada kamus/cincang

Saya mula-mula mula menulis fungsi tanpa nama dalam Python. Walau bagaimanapun, apabila saya cuba menyebarkan kerja ke satu set benang/proses, jurubahasa mengadu bahawa lambdas tidak boleh bersiri. Pada masa itu, saya memerlukan logik untuk hidup di luar kod utama, jadi saya akhirnya mencipta DSL untuk tujuan tersebut.

Perkara pertama yang terlintas di fikiran ialah lisp, kerana saya suka bagaimana kod itu agak menyerupai tatasusunan/senarai. Persamaan adalah perkara yang baik, kerana saya telah menyimpan konfigurasi dalam YAML. Oleh itu, saya tidak perlu risau untuk mencipta cara baharu untuk mewakili logik.

Menyimpan bahasa sebagai senarai membawa kelebihan alternatif, saya tidak perlu mencipta parser dari awal, iaitu tidak perlu tokenize / melakukan analisis leksikal (lexer). Dengan kata lain, pengarang adalah lexer. Apa yang saya perlu laksanakan ialah mengambil senarai input, mencari sama ada ia adalah program (kami memanggilnya peraturan) dan melaksanakannya berkenaan dengan konteks.

const schema = ["condition.Equal", ["basic.Field", "foo"], ["basic.Field", "bar"]];

// returns a function that checks if context.foo === context.bar
const rule = ruler.parse(rule)

const context = {foo: "meow", bar: "woof"};
rule(context) // returns false
Salin selepas log masuk
Salin selepas log masuk

Semuanya berfungsi dengan baik dan seperti yang diharapkan. Kemudian beberapa hari yang lalu saya terjumpa artikel untuk melaksanakan skema dalam Python. Saya mungkin membaca artikel itu sebelum ini, ketika saya meluangkan banyak masa untuk mempelajari Clojure. Walau bagaimanapun, kali ini, saya memutuskan untuk melaksanakan semula perpustakaan sekali lagi, kembali dengan Python, dari awal.

Jadi kali ini saya perlu tokenize, dan melakukan lexer sendiri. Jika saya hanya berurusan dengan nombor, semuanya mudah, tetapi apabila ia datang kepada rentetan perkara menjadi lebih rumit. Saya mengikuti tutorial lain, dan menemui semula projek make-a-lisp. Akhirnya saya menyerah, dan menggunakan lexer yang disediakan oleh hy-lang.

Lexer mengambil ungkapan s dan mengembalikan struktur yang menyerupai pokok sintaks abstrak. Dari situ, saya membina penghurai saya dengan melintasi pokok, mengembalikan peraturan sebagai penutup yang mengambil kamus sebagai konteks.

const schema = ["condition.Equal", ["basic.Field", "foo"], ["basic.Field", "bar"]];

// returns a function that checks if context.foo === context.bar
const rule = ruler.parse(rule)

const context = {foo: "meow", bar: "woof"};
rule(context) // returns false
Salin selepas log masuk
Salin selepas log masuk

Tiada kelebihan sebenar untuk pelaksanaan baharu, kerana saya telah meninggalkan kerja selama beberapa tahun. Pelaksanaan yang saya tinggalkan mungkin masih berjalan dengan baik sehingga kini (lebih baik selepas begitu banyak lelaran yang membawa kepadanya). Walau bagaimanapun, saya masih belajar satu atau dua perkara sepanjang perjalanan ini. Jika anda rasa ini menarik, sila semak Javascript (di mana ia menjangkakan skema peraturan dalam tatasusunan), atau versi Python baharu (s-ungkapan).

Atas ialah kandungan terperinci Membuat semula DSL enjin peraturan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan