Ayrıştırıcı Birleştiriciler (Parser Combinators)
Kaynak: Hacker News
İçindekiler 4 başlık
Ham metinleri yapılandırılmış veri nesnelerine dönüştürmek, yazılım geliştirmenin en temel ihtiyaçlarından biridir. Örneğin, "Hello, world!" gibi basit bir dizgeyi { greeting: "Hello", who: "world" } şeklinde anlamlı bir nesneye dönüştürmek istediğimizde devreye ayrıştırıcılar (parsers) girer. Parser Combinators (Ayrıştırıcı Birleştiriciler), küçük ve basit ayrıştırma fonksiyonlarını bir araya getirerek karmaşık metin yapılarını modüler bir şekilde işlememizi sağlayan güçlü bir fonksiyonel programlama tekniğidir.
Ayrıştırıcı (Parser) Nedir ve Nasıl Çalışır?#
Temel düzeyde bir Parser<T> tipi, girdi olarak bir metin (string) alan ve geriye iki elemanlı bir çift (tuple) döndüren bir fonksiyondur: [T, string]. Buradaki T ayrıştırılan hedef veriyi, ikinci eleman olan string ise metnin henüz işlenmemiş geri kalan kısmını temsil eder.
- Tekil Ayrıştırma (
pInteger): ÖrneğinpIntegerayrıştırıcısına"10 20 30"metnini verdiğimizde, metni"10"ifadesinden sonra keser. Sonuç olarak sayısal10değerini ve kalan" 20 30"metnini ([10, " 20 30"]) döndürür. - Zincirleme İşleme:
"Hello 100"metnini sırasıylapHello,pIgnoreWhitespacevepIntegerile işlediğimizi düşünelim. Her ayrıştırıcı bir öncekinin bıraktığı kalan metni devralır:pHelloçalışır:"Hello"değerini ve kalan" 100"metnini döndürür.pIgnoreWhitespaceboşluğu atlar:nullve kalan"100"metnini döndürür.pIntegerkalan metni alır:100sayısını ve boş metni""döndürür.
Birleştiriciler ile Karmaşık Yapılar Kurmak#
Ayrıştırıcıları tek tek elle zincirlemek yerine birleştirici (combinator) fonksiyonlar kullanarak yeni ayrıştırıcılar üretebiliriz:
- Sıralı Birleştirme (
pSeq):pSeq(pHello, pIgnoreWhitespace, pInteger)ifadesi, bu üç ayrıştırıcıyı birleştirerekParser<[string, null, number]>tipinde tek bir ayrıştırıcı (pHello100) üretir."Hello 100"girdisi verildiğinde doğrudan[["Hello", null, 100], ""]çıktısını verir. - Veri Dönüştürme (
pMap): Elde edilen diziyi istediğimiz veri modeline dönüştürmek içinpMapkullanılır.pGreetingayrıştırıcısı,["Hello", null, 100]çıktısını işleyerek{ greeting: "Hello", who: 100 }nesnesine dönüştürür. - Tekrarlayan Yapılar:
"10;20;30;"gibi tekrarlı bir metindepSeq(pNumber, pSemicolon)birleştiricisi ardışık olarak çalıştırılır. İlk adımda[10, ";"]ve kalan"20;30;", ikinci adımda[20, ";"]ve kalan"30;", son adımda ise[30, ";"]ve boş metin""elde edilir.
Gerçek Dünya Uygulaması: Ping Çıktısını Ayrıştırmak#
Bu küçük yapı taşları birleştirildiğinde, karmaşık terminal çıktıları bile kolayca yapılandırılmış JSON nesnelerine dönüştürülebilir. Örneğin standart bir PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data... komut satırı çıktısı;
- Header (Başlık): Hedef IP (
1.1.1.1), çözümlenen IP ve paket boyutlarını (56,84), - Packets (Paketler): Her bir satırdaki bayt sayısı (
64), sıra numarası (seq),ttl(52) ve süre (time) değerlerini içeren nesne dizisini, - Statistics (İstatistikler): İletilen/alınan paket sayısı (
8,7), paket kaybı (12.5%) vertt(min/avg/max/mdev) metriklerini barındıran kapsamlı bir veri nesnesine hatasızca ayrıştırılabilir.
Yazılım Geliştirme Açısından Pratik Çıkarımlar: Fold ve Unfold#
Yazılım geliştirme perspektifinden bakıldığında ayrıştırıcılar, dizilerdeki reduce (yani Fold) işleminin tam tersi (Unfold) olarak düşünülebilir:
- Fold (
reduce):["Hello", " ", 100]gibi yapılandırılmış bir listeyi alır ve birleştirerek"Hello 100"tekil metnine indirger. - Unfold (
Parser):"Hello 100"gibi düz bir metni alır vepSeq(...)yardımıyla onu["Hello", " ", 100]şeklinde yapılandırılmış parçalara açar.
Karmaşık düzenli ifadeler (Regex) yazmak yerine Parser Combinator yaklaşımını benimsemek; okunabilir, test edilebilir ve bakımı kolay metin işleme katmanları geliştirmenizi sağlar.
Kaynak ve atıf
Bu yazı, Hacker News üzerinde yayımlanan içerikten yararlanılarak Edumints tarafından yapay zekâ desteğiyle Türkçe hazırlandı. Ayrıntılar ve yazarların kendi anlatımı için orijinaline bakabilirsin:
- t3.at/blog/2026-10-17-parser-combinators