CodeBlanks Logo Icon CodeBlanks

TokenStream

TokenStream ile akış halinde kod üretirsin.

TokenStream

TokenStream, kaynak kodun derleyicinin gördüğü biçimdir: bir belirteç ağaçları (token tree) dizisi. Dört tür belirteç vardır: Ident (ad, anahtar kelime), Punct (:, +, ->), Literal (42, "metin") ve Group (parantez, köşeli ya da süslü parantez içindeki alt dizi):

fn kare(x: i32)
// Ident(fn) Ident(kare) Group(( Ident(x) Punct(:) Ident(i32) ))

Boşluklar ve yorumlar belirteç değildir; makro onları görmez.

Küçük bir belirteçleyici

Derleyicinin ilk adımı metni belirteçlere ayırmaktır. Basit bir sürümü: harf, rakam ve alt çizgiden oluşan dizileri birleştir, diğer işaretleri tek tek ayır, boşlukları atla:

fn belirtecler(s: &str) -> Vec<String> {
    let mut sonuc = Vec::new();
    let mut ad = String::new();
    for c in s.chars() {
        if c.is_alphanumeric() || c == '_' {
            ad.push(c);
            continue;
        }
        if !ad.is_empty() {
            sonuc.push(std::mem::take(&mut ad));
        }
        if !c.is_whitespace() {
            sonuc.push(c.to_string());
        }
    }
    if !ad.is_empty() {
        sonuc.push(ad);
    }
    sonuc
}

Uygulama Belirteçlere ayır

Yukarıdaki belirtecler fonksiyonunu yaz. "fn kare(x: i32)" için sonucu {:?} ile yazdır.

Başlangıç kodu

main.rs
fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
fn belirtecler(s: &str) -> Vec<String> {
    let mut sonuc = Vec::new();
    let mut ad = String::new();
    for c in s.chars() {
        if c.is_alphanumeric() || c == '_' {
            ad.push(c);
            continue;
        }
        if !ad.is_empty() {
            sonuc.push(std::mem::take(&mut ad));
        }
        if !c.is_whitespace() {
            sonuc.push(c.to_string());
        }
    }
    if !ad.is_empty() {
        sonuc.push(ad);
    }
    sonuc
}

fn main() {
    println!("{:?}", belirtecler("fn kare(x: i32)"));
}

Beklenen çıktı

["fn", "kare", "(", "x", ":", "i32", ")"]

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 Bildirimsel makrolardaki <code>$x:tt</code> neyi eşler?

  • Bir tür
  • Bir ifade
  • Bir satır
  • Tek bir belirteç ağacı: bir belirteç ya da parantezli bir grup Doğru cevap

Açıklama: tt en esnek fragmandır; $($t:tt)* ile her şeyi olduğu gibi aktarmak mümkündür.

2 Değeri al ve boşalt

Soru
sonuc.push(std::mem::____(&mut ad));
Cevap
sonuc.push(std::mem::take(&mut ad));

Açıklama: mem::take değeri alır ve yerine varsayılanı (boş String) bırakır.

3 Belirteç ve türü

Kavram Anlamı
kare Ident
: Punct
42 Literal
( x: i32 ) Group

İleri seviye bölümündeki tüm dersler