Proses parsing akan memvalidasi token yang sudah ada menjadi sebuah AST (Abstract Syntax Tree), AST yaitusebuah pohon yang berisikan Expression dari token yang ada seperti pada gambar diatas.
Untuk parser kita akan menggunakan teknik Pratt Parser yang berdasarkan Recursive Descent. Pratt Parser dan Recursive Descent mengambil paradigma dari Top Down Precedence Parsing menerapkan leftmost derivation yaitu akan memproses dari root atau akarnya kemudian dari kiri ke kanan.
Disini kita akan menggunakan nilai left binding power dari sebuah token seperti yang ada di kode token.rs
Pertama kita akan membuat sebuah file expression.rs yaitu representasi dari AST.
Tambahkan kode berikut ini:
Untuk enumExpression terutama dibagian yang menggunakan Box dimanaberisikanenumExpressionitu sendiri (Recursive structure) kita membutuhkan Box<T>. Untuk Recursive structure dibutuhkan sebanyak apa alokasi ukuran/size yang dibutuhkan di memory, contoh dibawah ini tidak akan bisa dicompile:
pub enum Expression {
...
Unary(Token, Expression),
// disini compiler tidak tahu seberapa banyak alokasi yang dibutuhkan
// dengan menggunakan Box yang dimana sudah ditentukan ukurannya
// maka untuk `Unary` kita akan tahu berapa ukuran yang dibutuhkan
}
Box adalah smart pointer yang mengalokasikan data ke dalam heap dengan nilai bertipe data T, Box termasuk smart pointerdikarenakan ketikaBoxsudah tidak digunakan lagi maka otomatisdestructoruntukBoxtersebut akan dipanggil dan object yang ada didalamnya akan dihapus serta memory di heapakan dihapus/freed.
Parser
Untuk selanjutnya buat file parser.rs dan tambahkan kode berikut:
StructParser berisikan tokens yang akan diproses untuk menjadi sebuah Expression. Disini kita membuat Iterator dari tokens tersebut sama seperti input di bagian 1 Lexer.
Tambahkan kode berikut ini setelah fungsi handle_next()
Nud atau null denotation adalah fungsi yang akan memproses sebuah token prefix disinilah yang hanya memproses sebuah literal dalam contoh ini sebuah number dan variable sedangkan Led atau Left Denotation yang akan memproses sebuah token infix dalam contoh ini adalah operator Binary.
Fungsi nud akan menentukan setiap token akan menjadi Expression yang sudah ditentukan, untuk hal branching atau if saat ini kita akan membatasi hanya 1 level jadi kita tidak akan bisa melakukan if didalam if.
selanjutnya untuk fungsi led tambahkan kode berikut setelah fungsi nud diatas:
Selanjutnya tambahkan fungsi expr setelah fungsi led, fungsi expr inilah yang akan mengevaluasi setiap token dan memanggil fungsi sebelumnya yaitu fungsi nud dan led. Berikut kodenya:
Test Parser
Jangan lupa untuk meambahkan test untuk parser.rs, tambahkan kode berikut dibagian paling bawah:
Main
Setelah menambahkan beberapa kode diatas, saatnya untuk mencoba menjalankan program dengan menggunakan parser yang telah kita buat.
Tambahkan kode berikut ini di file main.rs
Disini kita menambahkan 2 file yaitu expression.rs dan parser.rs
Untuk melihat hasilnya jalankan program dengan perintah sebagai berikut:
cargo run
Input kode berikut ini
a = 1 * 2 + 3 * 4
Maka kode diatas akan menghasilkan AST berupa expression sebagai berikut