Symbol table — kompilyator, interpreter yoki boshqa til vositasi dasturdagi nomlar haqida ma’lumot saqlaydigan tuzilma. Unda o‘zgaruvchi, funksiya, sinf, modul va parametr nomi uning turi, ko‘lami, e’lon qilingan joyi, xotira manzili yoki boshqa semantik atributlar bilan bog‘lanadi. Parser sintaktik tuzilmani yaratgach, symbol table nomlarning ma’nosini aniqlashda asosiy vosita bo‘ladi.
Yozuv tarkibi
Har bir symbol uchun barcha maydon bir xil bo‘lishi shart emas. Mahalliy o‘zgaruvchida type, scope, mutability va stack offset kerak bo‘lishi mumkin. Funksiya yozuvi parameter turlari, return type, visibility va calling conventionni saqlaydi. Class symbol esa field, method, parent type va generic parameterlarga havola beradi.
Source location diagnostic uchun muhim. Ikki marta e’lon qilingan nom yoki topilmagan identifikator xatosida compiler foydalanuvchiga aniq fayl va qatorni ko‘rsatadi. IDE qo‘shimcha ravishda hujjat, completion va “go to definition” ma’lumotlarini shu indeks bilan bog‘laydi.
Ko‘lamlar iyerarxiyasi
Lexical scope odatda ichma-ich table yoki parent pointerli muhit sifatida ifodalanadi. Nom qidirilganda avval joriy blok, keyin tashqi funksiya, modul va global scope tekshiriladi. Ichki e’lon tashqi nomni yashirsa, shadowing yuz beradi. Til qoidasi bunga ruxsat berishi, warning chiqarishi yoki ayrim holatda xato deb hisoblashi mumkin.
Quyidagi soddalashtirilgan kodda ikkita x alohida symbol hisoblanadi:
let x: Int = 1
if condition {
let x: String = "ichki"
print(x)
}
Ichki blok tugagach uning x yozuvi lookup zanjiridan chiqadi. Closure tashqi o‘zgaruvchini ushlasa, compiler symbolga capture turi va saqlash usulini qo‘shishi mumkin.
Yaratish va tekshirish
Ba’zi compiler birinchi pass’da declarationlarni yig‘ib, ikkinchi pass’da reference’larni resolve qiladi. Bu funksiya ta’rifidan oldin chaqirish yoki o‘zaro rekursiyani qo‘llashga yordam beradi. Bir passli tizim e’lon tartibiga ko‘proq cheklov qo‘yadi. Import va namespace mavjud bo‘lsa, nomni to‘liq kvalifikatsiya qilish ham resolution jarayoniga kiradi.
Data structure sifatida hash table tez lookup beradi. Tartibli tree deterministic iteration yoki prefix qidiruvi uchun foydali. Symbol’ga integer ID berish keyingi compiler bosqichlarida uzun matn nomini qayta-qayta solishtirishni kamaytiradi. Parallel compilationda shared global table contention keltirishi mumkin; modul bo‘yicha alohida table va keyinchalik linking ishlatiladi.
Keyingi bosqichlardagi roli
Type checker operand va chaqiruv turlarini symbol yozuvlari orqali topadi. Intermediate representation generatsiyasida source nom register yoki xotira joyiga aylantiriladi. Optimizer alias, constant va visibility ma’lumotidan foydalanadi. Linker darajasidagi symbol table object fayldagi export va importlarni manzil bilan bog‘laydi; bu source compiler table’iga o‘xshash bo‘lsa-da, formati va vazifasi torroq.
Debug ma’lumoti optimallashtirilgan machine code’ni original nom va qatorlar bilan bog‘laydi. Release binary’da symbol olib tashlansa hajm kamayadi, ammo crash stackni o‘qish uchun alohida symbol fayli saqlanishi mumkin. U maxfiy source nomlarini ochishi ehtimoli sabab himoyalangan joyda turadi.
Incremental vositalarda saqlash
IDE har tugma bosilishida butun loyiha symbol table’ini qayta qurmaydi. O‘zgargan fayl va unga bog‘liq modullar qayta tahlil qilinadi, qolgan yozuvlar cache’dan olinadi. Cache kaliti source hash, compiler versiyasi va konfiguratsiyani qamrab oladi. Stale symbol completion’da mavjud bo‘lmagan nomni ko‘rsatishi yoki xatoni yashirishi mumkin, shu sabab dependency graph va invalidation aniqligi tezlik qadar muhimdir.
Bog‘liq tushunchalar
Compiler, Identifier, Scope, Name resolution, Type checking, Linker, Abstract Syntax Tree