Catatan: Ketika saya menggunakan "complex" dalam judul, maksud saya bahwa ekspresi memiliki banyak operator dan operan. Bukan berarti ungkapan itu sendiri rumit.
Saya baru-baru ini bekerja pada kompiler sederhana untuk perakitan x86-64. Saya telah menyelesaikan ujung depan utama kompiler - lexer dan parser - dan sekarang saya dapat menghasilkan representasi Pohon Sintaksis Abstrak dari program saya. Dan karena bahasa saya akan diketik secara statis, saya sekarang sedang melakukan tahap selanjutnya: ketik memeriksa kode sumber. Namun, saya sampai pada masalah dan belum bisa menyelesaikannya dengan baik.
Perhatikan contoh berikut:
Parser kompiler saya telah membaca baris kode ini:
int a = 1 + 2 - 3 * 4 - 5
Dan mengubahnya menjadi AST berikut:
=
/ \
a(int) \
-
/ \
- 5
/ \
+ *
/ \ / \
1 2 3 4
Sekarang harus mengetik periksa AST. itu dimulai dengan pertama-tama memeriksa =
operator. Pertama-tama memeriksa sisi kiri operator. Itu melihat bahwa variabel a
dinyatakan sebagai integer. Jadi sekarang harus memverifikasi bahwa ekspresi sisi kanan mengevaluasi ke integer.
Saya mengerti bagaimana ini bisa dilakukan jika ekspresi itu hanya nilai tunggal, seperti 1
atau 'a'
. Tetapi bagaimana ini akan dilakukan untuk ekspresi dengan berbagai nilai dan operan - ekspresi kompleks - seperti yang di atas? Untuk menentukan nilai ekspresi dengan benar, sepertinya pemeriksa tipe harus mengeksekusi ekspresi itu sendiri dan mencatat hasilnya. Tapi ini jelas nampaknya mengalahkan tujuan memisahkan fase kompilasi dan eksekusi.
Satu-satunya cara saya membayangkan ini bisa dilakukan adalah dengan memeriksa secara rekursif daun setiap subekspresi di AST dan memverifikasi semua jenis daun sesuai dengan jenis operator yang diharapkan. Jadi dimulai dengan =
operator, pemeriksa tipe kemudian akan memindai semua AST sisi kiri dan memverifikasi bahwa semua daun adalah bilangan bulat. Kemudian akan mengulang ini untuk setiap operator di subekspresi.
Saya sudah mencoba meneliti topik dalam salinan "The Dragon Book" saya , tetapi sepertinya tidak masuk ke banyak detail, dan hanya mengulangi apa yang sudah saya ketahui.
Apa metode yang biasa digunakan ketika kompiler mengetik ekspresi memeriksa dengan banyak operator dan operan? Apakah ada metode yang saya sebutkan di atas yang digunakan? Jika tidak, apa metode dan bagaimana cara kerjanya?
double a = 7/2
akan mencoba menafsirkan sisi kanan sebagai ganda, karenanya akan mencoba menafsirkan pembilang dan penyebut sebagai ganda dan mengubahnya jika diperlukan; sebagai hasilnya a = 3.5
. Bottom-up akan melakukan pembagian integer dan mengkonversi hanya pada langkah terakhir (penugasan), jadi a = 3.0
.
int a = 1 + 2 - 3 * 4 - 5
tetapi untukint a = 5 - ((4*3) - (1+2))