Saya sedang menulis parser untuk bahasa markup yang telah saya buat (menulis dengan python, tapi itu tidak benar-benar relevan dengan pertanyaan ini - bahkan jika ini sepertinya ide yang buruk, saya akan menyukai saran untuk jalur yang lebih baik) .
Saya membaca tentang parser di sini: http://www.ferg.org/parsing/index.html , dan saya sedang mengerjakan penulisan lexer yang seharusnya, jika saya mengerti dengan benar, membagi konten menjadi token. Apa yang saya mengalami kesulitan memahami adalah apa jenis token yang harus saya gunakan atau cara membuatnya. Misalnya, jenis token dalam contoh yang saya tautkan adalah:
- TALI
- IDENTIFIER
- JUMLAH
- WHITESPACE
- KOMENTAR
- EOF
- Banyak simbol seperti {dan (dihitung sebagai jenis token mereka sendiri)
Masalah yang saya alami adalah bahwa jenis token yang lebih umum tampak agak arbitrer bagi saya. Sebagai contoh, mengapa STRING tipe token terpisah vs. IDENTIFIER. Sebuah string dapat direpresentasikan sebagai STRING_START + (IDENTIFIER | WHITESPACE) + STRING_START.
Ini mungkin juga ada hubungannya dengan kesulitan bahasa saya. Misalnya, deklarasi variabel ditulis sebagai {var-name var value}
dan digunakan dengan {var-name}
. Sepertinya '{'
dan '}'
harus menjadi token mereka sendiri, tetapi apakah VAR_NAME dan VAR_VALUE jenis token yang memenuhi syarat, atau apakah keduanya termasuk dalam IDENTIFIER? Terlebih lagi, VAR_VALUE dapat benar-benar berisi spasi putih. Spasi putih setelah var-name
digunakan untuk menandakan awal dari nilai dalam deklarasi .. spasi putih lainnya adalah bagian dari nilai. Apakah ruang putih ini menjadi tokennya sendiri? Whitespace hanya memiliki makna itu dalam konteks ini. Selain itu, {
mungkin bukan awal dari deklarasi variabel .. itu tergantung pada konteks (ada kata itu lagi!). {:
memulai deklarasi nama, dan{
bahkan dapat digunakan sebagai bagian dari nilai tertentu.
Bahasa saya mirip dengan Python dalam blok yang dibuat dengan lekukan. Saya membaca tentang bagaimana Python menggunakan lexer untuk membuat token INDENT dan DEDENT (yang berfungsi kurang lebih seperti apa {
dan }
akan dilakukan dalam banyak bahasa lain). Python mengklaim bebas konteks yang berarti bagi saya bahwa setidaknya lexer tidak peduli di mana ia berada di aliran saat membuat token. Bagaimana lexer Python mengetahui bahwa ia sedang membangun token INDENT dengan panjang tertentu tanpa mengetahui tentang karakter sebelumnya (misalnya bahwa baris sebelumnya adalah baris baru, jadi mulailah membuat spasi untuk INDENT)? Saya bertanya karena saya perlu tahu ini juga.
Pertanyaan terakhir saya adalah yang paling bodoh: mengapa lexer bahkan perlu? Sepertinya saya bahwa parser bisa pergi karakter demi karakter dan mencari tahu di mana itu dan apa yang diharapkan. Apakah lexer menambah manfaat kesederhanaan?