Girdiyi Belirteçlere Ayırma
Metni belirteçlere dönüştürün.
Girdiyi Belirteçlere Ayırma, CoddyKit'te ücretsiz bir C Academy dersidir. Bu, 4 dersinin 1. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, C Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. C Academy kursu toplamda 4 dersten oluşur.
Tokenizer Nedir?
Bir yorumlayıcı, ham metni belirteçlere dönüştürerek başlar; bunlar anlam taşıyan en küçük birimlerdir. 3 + 4 * 2 dizesi için tokenizer (veya lexer) sayılar ve işleçler üretir.
Bu aşama boşlukları kaldırır ve her karakter grubunu sınıflandırır; böylece ayrıştırıcı ham baytlarla hiç uğraşmaz.
Bir Belirteç Türü
Her belirteci bir enum etiketi ve bir yük ile modelleriz. Sayılar bir tamsayı değeri taşır; işleçler ve parantezler için yalnızca türleri gerekir.
Değeri struct içinde tutmak, kaynağı daha sonra yeniden taramaktan kaçınmamızı sağlar.
typedef enum {
TOK_NUM, TOK_PLUS, TOK_MINUS,
TOK_STAR, TOK_SLASH,
TOK_LPAREN, TOK_RPAREN, TOK_EOF
} TokKind;
typedef struct {
TokKind kind;
int value; /* used when kind == TOK_NUM */
} Token;Tarama Konumu
Lexer, kaynak üzerinde bir imleç işaretçisiyle ilerler. Küçük bir yardımcı, mevcut karakteri tüketmeden ona bakar ve son noktada '\0' döndürür.
İşaretçi aritmetiği tarayıcıyı hızlı ve basit tutar.
static const char *src;
static char peek(void) {
return *src;
}
static char advance(void) {
return *src++;
}Boşlukları Atlamak
Bir belirteci okumadan önce boşlukları ve sekmeleri atarız. <ctype.h> içindeki standart isspace, tüm boşluk karakterlerini işler.
Burada satır sonları da boşluk sayılır; dolayısıyla ifade birden çok satıra yayılabilir.
#include <ctype.h>
static void skip_ws(void) {
while (isspace((unsigned char)peek()))
advance();
}Sayıları Sözcüksel Olarak İşleme
İmleç bir rakamın üzerindeyken ardışık rakamları bir tamsayıda biriktiririz. Onla çarpıp her rakamı eklemek, değeri soldan sağa oluşturur.
Döngü ilk rakam olmayan karakterde durur ve imleci sonraki belirteç için hazır bırakır.
static int lex_number(void) {
int n = 0;
while (isdigit((unsigned char)peek())) {
n = n * 10 + (advance() - '0');
}
return n;
}next_token İşlevi
Temel yordam boşlukları atlar, ardından mevcut karaktere göre işlem dağıtır. Rakamlar bir TOK_NUM olur; her işleç kendi türüne eşlenir.
Sonlandırıcı NUL'a ulaşılması, durma sinyali olan TOK_EOF sonucunu üretir.
static Token next_token(void) {
skip_ws();
char c = peek();
if (c == '\0') return (Token){TOK_EOF, 0};
if (isdigit((unsigned char)c))
return (Token){TOK_NUM, lex_number()};
advance();
switch (c) {
case '+': return (Token){TOK_PLUS, 0};
case '-': return (Token){TOK_MINUS, 0};
case '*': return (Token){TOK_STAR, 0};
case '/': return (Token){TOK_SLASH, 0};
case '(': return (Token){TOK_LPAREN, 0};
case ')': return (Token){TOK_RPAREN, 0};
}
return (Token){TOK_EOF, 0};
}Lexer'ı Çalıştırma
Burada bir ifadeyi belirteçlere ayıran ve her belirteç türünü yazdıran eksiksiz bir program vardır. Sayılar ayrıca değerlerini de yazdırır.
TOK_EOF okunduğunda döngünün sona erdiğine dikkat edin.
#include <stdio.h>
#include <ctype.h>
typedef enum { TOK_NUM, TOK_PLUS, TOK_STAR, TOK_EOF } TokKind;
typedef struct { TokKind kind; int value; } Token;
static const char *src;
static char peek(void){ return *src; }
static char advance(void){ return *src++; }
static Token next_token(void){
while (isspace((unsigned char)peek())) advance();
char c = peek();
if (c=='\0') return (Token){TOK_EOF,0};
if (isdigit((unsigned char)c)){
int n=0; while(isdigit((unsigned char)peek())) n=n*10+(advance()-'0');
return (Token){TOK_NUM,n};
}
advance();
if (c=='+') return (Token){TOK_PLUS,0};
return (Token){TOK_STAR,0};
}
int main(void){
src = "12 + 3 * 4";
Token t;
do {
t = next_token();
if (t.kind==TOK_NUM) printf("NUM %d\n", t.value);
else if (t.kind==TOK_PLUS) printf("PLUS\n");
else if (t.kind==TOK_STAR) printf("STAR\n");
else printf("EOF\n");
} while (t.kind != TOK_EOF);
return 0;
}Tek Belirteçlik İleriye Bakış
Ayrıştırıcıların çoğu, yaklaşan belirteci tüketmeden önce incelemelidir. Bir belirteci genel current değişkeninde tutar ve her eşleşmeden sonra onu yenileriz.
Bu tek belirteçlik ileriye bakış, LL(1) gramerimiz için yeterlidir.
static Token current;
static void init_lexer(const char *s) {
src = s;
current = next_token();
}
static Token cur(void) { return current; }
static void bump(void) { current = next_token(); }Sözcüksel Hataları Bildirme
$ veya @ gibi bilinmeyen bir karakter sessizce yok olmamalıdır. Sağlam bir lexer, sorunlu baytı bildirir ve işlemi durdurur.
Lexer'da hızlıca başarısız olmak, sonraki aşamaların bozuk belirteçler görmesini engeller.
#include <stdio.h>
#include <stdlib.h>
static void lex_error(char c) {
fprintf(stderr, "lex error: unexpected '%c'\n", c);
exit(1);
}Birden Çok Karakterli İşleçler
Gerçek dillerde == veya <= gibi belirteçler bulunur. Bunları sözcüksel olarak işlemek için ilk karakterden sonra bir karaktere daha bakarız.
Sonraki bayt işleci tamamlıyorsa ikisini de tüketiriz; aksi halde tek karakterli biçimi üretiriz.
/* fragment: distinguish '=' from '==' */
if (peek() == '=') {
advance();
if (peek() == '=') { advance(); /* TOK_EQ */ }
else { /* TOK_ASSIGN */ }
}Belirteçler Neden Önemlidir
Karakterleri belirteçlere dönüştürerek ayrıştırıcı temiz ve türleri belirli bir akışla çalışır. İşleç önceliği, gruplama ve hatalar üzerinde düşünmek kolaylaşır.
Sırada bu belirteçleri özyinelemeli iniş ayrıştırıcısına aktarmak var.
Hızlı Kontrol
Gruplama sembolleri için lexer'ın ne ürettiğini düşünün.
Özet
Bir lexer oluşturdunuz: belirteç türü, tarama imleci, boşluk atlama, sayıların sözcüksel olarak işlenmesi ve tek belirteçlik ileriye bakışa sahip bir next_token dağıtıcısı.
Bu belirteçler, onlardan bir sözdizimi ağacı oluşturan ayrıştırmanın girdisidir.
Sıkça Sorulan Sorular
“Girdiyi Belirteçlere Ayırma” dersi ücretsiz mi?
Evet — “Girdiyi Belirteçlere Ayırma” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve C Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. C Academy kursu toplamda 4 dersten oluşur.
“Girdiyi Belirteçlere Ayırma” dersinde ne öğreneceğim?
Metni belirteçlere dönüştürün. C Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
C Academy öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te C Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 1. dersidir.
“Girdiyi Belirteçlere Ayırma” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu C Academy dersinde kod yazıp çalıştırabilir miyim?
Evet. Her C Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- Girdiyi Belirteçlere Ayırma
- İfadeleri Ayrıştırma
- Ağacı Değerlendirme
- Değişken Ekleme