BerandaComputers and TechnologyQuery-JSON: Sebuah cerita kompilasi silang dengan Reason

Query-JSON: Sebuah cerita kompilasi silang dengan Reason

query-json adalah implementasi ulang yang lebih cepat dan lebih sederhana dari bahasa jq dalam Alasan .

Ini adalah CLI untuk menjalankan program kecil melawan JSON, idenya sama dengan sed , tetapi untuk file JSON. Sebagai insinyur web adalah alat penting saat mengembangkan API.

Dimulai dengan tujuan untuk membuat sesuatu yang berguna dan belajar selama proses tersebut. Sangat tertarik untuk belajar tentang cara menulis parser dan kompiler menggunakan tumpukan OCaml: menhir dan sedlex , kompilasi ke arsitektur apa pun dan coba kompilasi ke JavaScript.

Posting ini menjelaskan proyek, bagaimana itu dibuat dan keputusan mana yang diikuti dan beberapa refleksi.

exploded view

Mengapa mempelajari parser / compiler

Saya memiliki sedikit ide tentang teori tersebut, tetapi sangat kabur dan tidak berguna dan merupakan waktu yang tepat untuk mempelajari lebih lanjut sejak saya membuatnya style-ppx yang merupakan file ppx (Pra P profesor E x yang memungkinkan CSS-in-Reason / OCaml. Perlu mengurai CSS dan memiliki backend yang dikompilasi ke bs-emosi .

Saya meminta bantuan untuk @EduardoRFS tentang menulis CSS Parser yang mendukung seluruh spesifikasi CSS3 yang ingin saya pahami, tingkatkan, dan pertahankan dari waktu ke waktu.

Bagaimana itu bekerja

  query-json  ". store.books | filter (.price> 10)"  stores.json  

Ini dibaca stores.json dan akses ke "toko" bidang, akses ke "buku" (karena ini adalah array) itu wil Saya menjalankan filter pada setiap item dan memfilter setiap item dengan "harga" yang lebih besar dari 10 dan terakhir, cetak daftar yang dihasilkan.

   [  {    "title": "War and Peace",    "author": "Leo Tolstoy",    "price": 12.0  },  {    "title": "Lolita",    "author": "Vladimir Nabokov",    "price": 13.0  }]   

Argumen pertama disebut pertanyaan dan itu ekspresi jq. Yang kedua disebut json atau payload , dan ini adalah file JSON yang valid.

Semantik dari jq terdiri dari satu set operasi pipa, di mana setiap keluaran dihubungkan ke masukan di mana masukan pertama adalah JSON itu sendiri. Beberapa pseudo-code untuk diilustrasikan:

  {/ json /} | filter | mengubah | menghitung

Untuk mengubah kueri ke satu set operasi yang berjalan melawan JSON, kami akan membagi masalah menjadi 3 langkah: mengurai , kompilasi dan Lari.

Parsing

Bertanggung jawab untuk mengubah string menjadi AST (Abstrak Syntax Tree) dan memberikan pesan kesalahan yang baik saat input cacat.

Salah satu keindahan jq adalah bahwa semua ekspresi disalurkan secara default, jadi . store | .books setara dengan . store.books . Saya merancang AST untuk merepresentasikan struktur pipa pada sifatnya. Jika Anda ingin tahu lebih banyak tentang bahasa jq, periksa wiki .

Mari selami sebuah contoh. Saat parser menerima . Store.books akan kembali:

   Pipa(     Kunci ("toko" )  ,      Kunci (  "buku"  )  )   

Semua operasi diubah menjadi konstruktor ini dari atas (Pipa, Kunci ). Konstruktor tersebut disebut Varian.

Varian model nilai yang mungkin mengasumsikan salah satu dari banyak variasi yang diketahui. Fitur ini mirip dengan enum dalam bahasa lain, tetapi setiap varian secara opsional dapat berisi data yang dibawa di dalamnya. Varian termasuk dalam kelompok besar tipe yang disebut ADT .

Seluruh query-json representasi program itu salah satu Varian rekursif besar.

Mengikuti contoh yang lebih kompleks, mari parse . Store.books | filter (.price> 10) :

 Pipa (     Pipa (         Kunci ("toko" )  ,          Kunci (  "buku"  )      )   ,      Saring (         Pipa (             Kunci ("harga" )  ,              Harfiah (Jumlah  (  10.  )  )          )      )  )   

Anda dapat melihat lebih banyak contoh di tes parsing

Menyusun

Langkah kompilasi menerima AST dan mengubahnya menjadi kode. Ini adalah kecocokan pola rekursif besar , yang merupakan fitur hebat lainnya dari Reason dan terlihat seperti ini:

   biarkan   rec  kompilasi = (ekspresi, json )  =>   {    sakelar   (ekspresi)  {    |   Kosong  =>  kosong    |   Kunci  =>  kunci  ( json )     |   Kunci( kunci ,  opt )  =>  anggota  ( kunci ,  opt ,  json )     |   Indeks( idx )  =>  indeks  ( idx ,  json )     |   Kepala  =>  kepala  ( json )     |   Ekor  =>  ekor  ( json )     |   Panjang  =>  panjang  ( json )     }   

Di sisi kiri didefinisikan semua kemungkinan Varian dan di sisi kanan operasi. Operasi tersebut mengubah JSON. Di sinilah peta , Saring, mengurangi, indeks, dll… diimplementasikan.

Berjalan

Bagian yang lebih mudah, langkah kompilasi memberi kita kembali fungsi curried yang mengharapkan json sebagai satu-satunya argumen, kita cukup menerapkan fungsi tersebut ke JSON ini dan mencetak hasilnya.

Contoh ini hanya mendeskripsikan happy path, pada kenyataannya langkah parsing dan kompilasi mengembalikan Jenis hasil yang memungkinkan penanganan kesalahan lebih dapat disusun.

Sekarang kita sudah membahas cara kerjanya secara internal dan sedikit gambaran umum arsitekturnya. Sekarang mari selami bagaimana pengembang dapat menggunakannya di mesin mereka.

Tapi pertama-tama, mari kita rekap tentang apa.

OCaml adalah bahasa pemrograman dari keluarga ML (“Meta Language”) dan terkenal karena sistem tipe statis dan tipe-inferensi mereka. OCaml memungkinkan untuk mengkompilasi ke kode biner yang sering dibandingkan dengan kinerja C / C ++.

BuckleScript adalah kompiler (cabang dari file OCaml compiler) yang mengeluarkan kode JavaScript, bukan biner. BuckleScript mendukung sintaks OCaml dan sintaks Reason.

Reason adalah bahasa yang dapat dikompilasi dengan kompiler OCaml atau BuckleScript.

Cara melakukan kompilasi silang ke binary

Semua proses build dan pengujiannya berjalan di CI kami di Github Actions, yang memungkinkan menjalankan Mac, Gambar Windows dan Linux. Setiap build dikompilasi dengan compiler OCaml untuk setiap arsitektur.

Setelah build dan pengujian berhasil, build akan memasukkan biner ke dalam Rilis Github dan registri npm.

Cara mengompilasi ke Web

Kompilasi ke JavaScript adalah bagian yang manis dari posting blog ini karena kami menggunakan OCaml (di bawah tenda saat menulis Alasan), dan memungkinkan kami untuk mengkompilasi langsung ke JavaScript menggunakan js_of_ocaml .

js_of_ocaml adalah kompiler yang dapat dihubungkan ke salah satu OCaml dan memungkinkan untuk menjalankan program OCaml murni ke dalam JavaScript . Seperti yang Anda lihat, query-json menggunakan menhir, sedlex dan yojson

Untuk menggunakannya di esy , manajer paket, saya hanya perlu menambahkan:

  esy  tambahkan  js_of_ocaml esy  tambahkan  js_of_ocaml-compiler  

dan memodifikasinya bukit pasir, sistem build:

   ( dapat dieksekusi   (  nama  Js )    ( mode js )    ( sumber perpustakaan console.lib yojson js_of_ocaml )  )   

Setelah menjalankan build, itu menghasilkan bundle.js!

Taman bermain buatan query-json

Setelah memiliki artefak JavaScript, saya dapat menjalankannya sebagai taman bermain di browser. Untuk mengajari orang cara menggunakannya tanpa menginstal biner atau untuk menguji versi baru pada setiap permintaan pull, nah, kemungkinan web tidak terbatas!

playground

Saya membangun situs web menggunakan Reason and BuckleScript yang menggunakan artefak JavaScript query-json untuk menjalankannya, Anda dapat mencobanya sendiri di sini:

Terakhir

Harap Anda menyukai proyek dan ceritanya, beri tahu saya jika Anda tertarik dengan topik tersebut. Saya selalu senang mengobrol dan membantu. Saya menjawab semua DM di Indonesia.

Sampai jumpa lagi 👋

Terima kasih semuanya telah mengulas postingan blog ini,
Javi , Enric dan [Gerard]

Read More

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments