Forum: Diğer Konular RSS
Regex Nasıl Tasarlandı
Sayfa:  1  2  sonraki 
agora #1
Üye Tem 2013 tarihinden beri · 221 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: Regex Nasıl Tasarlandı
Python'da yazdığım şöyle bir Regex tanımlaması var:

(.*?) (.*?) \[(.*?)\] \"(.*?)\" (.*?) (.*?) (.*?) \"(.*?)\"

Bunlara "düzenli ifadeler" diyorlar. Pek düzenliymiş gibi durmuyor. Neyse tarihine bakınca 1956 yılına kadar gittiğini ve Stephen Cole Kleene tarafından tasarlandığını hatta Kleene's recursion theorem adında bir teorem olduğunu gördüm. Hatta işin içinde otomata teorisi de varmış.

Her şey tamam da ya bu düzenli ifadelerin kendisi bile zor iken lexer ve parser tarafında bu nasıl yazıldı kodlandı?

Her durum için if, else, while döngülerinden mi faydalanıldı?

Google bana istediğim cevabı da vermiyor ki okuyayım. Regex tabanlı lexer sonucu çıkıyor hep.

İşin esasında tree algoritmaları ve otomata teorileri mi yatıyor?

Örneğin RFC 2822 e-mail validator:

(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]) 

Böyle bir şeyi kim nasıl yazmış? (Yani şu yukarıdaki marsça gibi görünen şeyi yorumlayan lexer mı parser mı ne)
zafer #2
Üye Tem 2009 tarihinden beri · 700 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Güzel sorular, anlaşılan Regex'le bayağı bir çebelleşmissin :) Bir süredir bende karşılaşıyorum ama gözüm korktuğu için gördükçe kaçıyorum.
https://github.com/zafer06 - depo
Avatar
zekeriyadurmus #3
Kullanıcı başlığı: Talha Zekeriya Durmuş
Üye Eki 2012 tarihinden beri · 701 mesaj · Konum: Samsun/Türkiye
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #1
Lexer tokenize işlemi yapar. Parser ise lexer tarafından oluşturulan token ları işleyip AST çıktısını oluşturur.

Örnek vermek gerekirse

"100 + 200 * 4"

bu ifade önce parserın anlayacağı şekilde anlamlı parçalara dönüştürülmek üzere lexerdan geçiyor.
Anlayabileceği kelimelere çeviriyor da diyebiliriz.

Token("100", Number)
Token("+", Plus)
Token("200", Number)
Token("*", Times)
Token("4", Number)

Sonrasında çarpmanın işlem önceliğini ve oluşturulan dilin kuralları göz önünde bulundurularak AST (Abstract Syntax Tree oluşturuluyor)

bkz https://en.wikipedia.org/wiki/Abstract_syntax_tree

Zekeriya
Bilgi meraktan gelir...
Bu mesaj zekeriyadurmus tarafından değiştirildi; zaman: 2015-11-23, 10:14.
agora #4
Üye Tem 2013 tarihinden beri · 221 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Regex mantığı da bu mu oluyor yani?

Bir de konu ile alakasız ne zaman ing. wiki başlıklarında soldan dil seçeneğine gitsem vietnam var ama Türkçe yok. Üzücü.

Bu arada söylemeden edemeyeceğim regex gerçekten harika bir şey. Örneğin:

[title=Falanca]

[description=Açıklama]

[category=Falan Kategorisi]

[date=24.11.2015]

[content]
Hebele hübele hümbele hübübüle
Çok satırlı yazı bu bile
Fazladan
[/content]

gibi bir dosyayı regex ile parse edip gereken çıktıyı vermem 4-5 satır tuttu pythonda. Static site generatorler daha çetrefilli olsalar da işin asıl kısmı yazıyı yayına alma kısmı sanırım biraz basitmiş.
Bu mesaj agora tarafından değiştirildi; zaman: 2015-11-23, 15:46.
acehreli (Moderatör) #5
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Düzenli ifadeler bir domain specific language örneğidir (konuya özgün dil?). Dizgi, aslında bir dildir çünkü programcı ne olacağını tarif etmektedir, düzenli ifade düzeneği de o dili yorumlayarak isteneni gerçekleştirmektedir.

Hiç bilmeyen arkadaşlar için bir örnek: "([a-z]+):([0-9]+)" dizgisi şu anlama gelir:

  • [a-z] ASCII küçük harf olacak
  • + Onlardan en az bir adet olacak
  • (...) Eğer uyarsa, o uyan bölüme dizi indeksiyle erişebileceğim (Bu, ilk parantez çifti olduğundan, indeksi 1 olacak. (0 bütün uyan bölümü verir.))
  • : Ondan sonra iki nokta üst üste gelecek
  • [0-9] Rakam olacak
  • + Onlardan en az bir adet olacak
  • (...) Eğer uyarsa, o uyan bölüme dizi indeksiyle erişebileceğim (Bu, ikinci parantez çifti olduğundan, indeksi 2 olacak)

Aşağıdaki programdaki üç satırdan yalnızca ikisi uyar:
import std.regex;
import std.stdio;
 
void main() {
    auto r = regex("([a-z]+):([0-9]+)");
 
    immutable satırlar = [
        "merhaba:123",
        "uymayan:bir_satır",
        "dunya:456" ];
 
    foreach (satır; satırlar) {
        auto uyum = satır.match(r);
 
        if (uyum) {
            writeln("Uyan bir satır bulundu");
 
            foreach (eleman; uyum) {
                /* Düzenli ifadede iki çift parantez (seçim) kullandığımızdan,
                 * 'uyum' üç elemandan oluşur. */
                writeln("  Bütün satır  : ", eleman[0]);
                writeln("  Birinci seçim: ", eleman[1]);
                writeln("  İkinci seçim : ", eleman[2]);
            }
        }
    }
}
Çıktısı:


Uyan bir satır bulundu
  Bütün satır  : merhaba:123
  Birinci seçim: merhaba
  İkinci seçim : 123
Uyan bir satır bulundu
  Bütün satır  : dunya:456
  Birinci seçim: dunya
  İkinci seçim : 456

D'nin derleme zamanında kod işletebilme yeteneği onu domain specific language konusunda üstün bir yere koyuyor. Normalde, yukarıdaki r değişkeni program çalışmaya başladıktan sonra oluşturulur, kendisine verilen düzenli ifade dizgisi çalışma zamanında taranır, sonuçta asıl işi görecek olan düzenek çalışma zamanında kurulmuş olur. Oysa, yukarıdaki örnekte de görüldüğü gibi, düzenli ifade dizgileri çoğu zaman derleme zamanında bilinir. Yani, ifade dizgisinin kendisini çalışma zamanında oluşturmayız.

D'nin ctRegex olanağı, ifade dizgisi derleme zamanında bilindiğinde hız artışı sağlar. (ctRegex, bütün diller arasında bilinen en hızlı düzenli ifade düzeneğini oluşturur. Bunun benzerini json konusunda da yaşadık: En hızlı json okuyucusu da D'de yazılıyor.):
    enum r = ctRegex!"([a-z]+):([0-9]+)";

Ali
agora #6
Üye Tem 2013 tarihinden beri · 221 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Eğer D ve Regex kullanımını anlayabilirsem şablonları dışarı HTML olarak aktarma işini belki D ile yapabilirim.

Örneğin yazi-linki-var.df gibi bir dosya oluşturacağım. O da onu yazi-linki-var.html gibi aktaracak. Denemek faydalı :p
acehreli (Moderatör) #7
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Giriş ve çıkış dosyalarının örneklerini gösterir misin. (Küçük olsun! :))  Belki fikir verebiliriz.

Ali
agora #8
Üye Tem 2013 tarihinden beri · 221 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Hocam basit test mantığında ilerliyorum. İçinde bir sürü bad practice içeriyor olabilir :p

Bu main.py dosyası. Konsoldan ./main.py ilk-yazi-bu.df şeklinde çağırırsanız geliyor. Aşağıdakiler Python kodları. Bunu D diline çevirmeye çalışıyorum. Belki content'i regex ile alırken sıkıntı olmuş olabilir. Harf sayısı kadar adım sayıyor.

Ayrıca D'nin Json işlemini de kullanacağım nikola, pelican, octopress gibi bir yapı düşünüyorum :)

Hocam dosyaların tamamı bu kadar küçük olmasından kastınız :( Anlayamadım pek onu.

#!/usr/bin/python3
 
import re
import sys
import time
 
if len(sys.argv) != 2:
    print('Usage: ./main.py file-name.df')
    sys.exit(1)
 
file_from_cli = sys.argv[1]
 
art_title = re.compile(r'\[title=(.*?)\]')
art_desc = re.compile(r'\[description=(.*?)\]')
art_cat = re.compile(r'\[category=(.*?)\]')
art_date = re.compile(r'\[date=(.*?)\]')
art_content = re.compile(r'\[content\]([\s\S]*?)\[\/content\]')
now = time.strftime("%d %B %y -- %X")
 
file_name = file_from_cli
if file_name.lower().endswith(".df"):
    access_log_file = open(file_name, "r").read()
else:
    print("Ups! File extension must be '.df'")
    sys.exit(1)
 
title_read = desc_read = cat_read = date_read = content_read = access_log_file
title_show = re.search(art_title, title_read)
desc_show = re.search(art_desc, desc_read)
cat_show = re.search(art_cat, cat_read)
date_show = re.search(art_date, date_read)
content_show = re.search(art_content, content_read)
 
title = title_show.group(1)
desc = desc_show.group(1)
cat = cat_show.group(1)
content = content_show.group(1)
date = date_show.group(1)
 
if not title:
    print("Title can't be empty")
    sys.exit(1)
 
if not desc:
    print("Description can't be empty")
    sys.exit(1)
 
if not cat:
    cat = "Uncategorized"
 
if date != "now":
    now = date
 
if not date:
    now = time.strftime("%d %B %y -- %X")
 
if not content.strip('\n'):
    print("Content can't be empty")
    sys.exit(1)
 
link_from_title = title_show.group(1).lower().replace(" ", "-")
file_to = '%s.html' % link_from_title
 
with open(file_to, 'a') as the_file:
    the_file.write("<html>\n\t")
    the_file.write("<head>\n\t\t")
    the_file.write("<meta charset='utf8' />\n\t\t")
    the_file.write("<title>%s</title>\n\t" % title)
    the_file.write("</head>\n\t")
    the_file.write("<body>\n\t\t")
    the_file.write("<h1>%s</h1>\n\t\t" % title)
    the_file.write("<span>%s</span>\n\t\t" % desc)
    the_file.write("<p>%s</p>\n\t\t" % cat)
    the_file.write("<abbr title='{0}'>{0}</abbr>\n\t\t".format(now))
    the_file.write("\n\t\t<blockquote>\n\t\t\t\t%s\n\t\t</blockquote>\n\t" % content)
    the_file.write("</body>\n")
    the_file.write("</html>\n")
 
print("The", file_to, "file is created...")

Bu da ilk-yazi-bu.df dosyası:

[title=Oldu Tamam]
 
[description=Bu Bir Açıklama]
 
[category=Python]
 
[date=25 Kasım 2015 Saat 01:54]
 
[content]test
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean in nibh eu risus finibus consectetur imperdiet nec lectus. Donec in interdum libero, non pretium orci. Ut pulvinar ante sit amet nibh auctor, id eleifend neque fringilla. Interdum et malesuada fames ac ante ipsum primis in faucibus. Cras varius leo nunc, vel tincidunt tortor sollicitudin congue. Nulla pretium sed elit at lacinia. Phasellus nunc quam, commodo at elit non, bibendum porttitor libero. In ipsum tellus, viverra at tellus eget, pellentesque semper est.
 
Mauris semper faucibus neque, vitae elementum diam vehicula et. Duis rhoncus interdum est sed ultrices. Nulla non sollicitudin dolor. Nam efficitur, augue vel varius hendrerit, mauris orci hendrerit nunc, et auctor metus leo nec justo. Quisque auctor nunc magna, eu dapibus erat vestibulum non. Praesent suscipit odio at tincidunt eleifend. Fusce vel nulla rutrum, vulputate purus vitae, blandit leo. In sapien diam, blandit in ultricies nec, tempus accumsan nisl. Nulla laoreet fermentum feugiat. Aliquam a est vel tortor efficitur pretium. Donec ultricies vulputate diam, sagittis pellentesque arcu suscipit ut.
 
Donec faucibus viverra ligula, sed pellentesque ante luctus quis. Proin auctor tortor id gravida fringilla. Duis auctor metus eu consequat scelerisque. Pellentesque ipsum nibh, sollicitudin quis nisi ac, tincidunt sollicitudin lectus. Ut ultrices justo eu pretium convallis. Quisque urna lorem, vestibulum a tellus ut, aliquet volutpat dui. Nulla sapien nisi, rutrum in augue a, semper dapibus dolor. Nulla ut orci diam. Vestibulum iaculis gravida nisl, quis luctus mi varius sed. Quisque justo risus, fermentum et posuere eget, porttitor eget risus. In rhoncus vestibulum tempor. Fusce tellus velit, commodo eget libero eu, sagittis faucibus enim. Donec eget rhoncus justo.
 
Vivamus congue vulputate gravida. Suspendisse viverra condimentum nisi, id ornare felis malesuada vitae. Fusce vestibulum justo erat, eget congue nunc congue id. Etiam ultrices felis non viverra venenatis. Phasellus urna lectus, porttitor sed massa in, fermentum lacinia velit. Nam erat justo, mollis eget nunc eu, cursus fringilla ante. Phasellus tincidunt lacinia iaculis. Aenean sit amet scelerisque sapien. In et porta odio.
 
Proin pharetra urna lectus, et accumsan justo luctus sed. Cras ac interdum arcu, a commodo felis. Fusce sed semper neque, in egestas est. Pellentesque sed lorem non odio facilisis mattis. Nulla velit eros, luctus quis nisi non, facilisis mattis turpis. Nullam tristique aliquam libero, sed eleifend quam porta quis. Proin ac diam varius, sollicitudin nibh vel, mollis purus. Nulla facilisi. Phasellus scelerisque arcu ipsum, a molestie tellus porttitor ut. Integer maximus tortor fringilla nibh elementum, eu efficitur odio egestas.
[/content]
acehreli (Moderatör) #9
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yani, giriş dosyasının düzeni ilk-yazi-bu.df'te olduğu gibiymiş ve çıkış dosyası da HTML oluyormuş. Anladım. :) O zaman D'ye çevirmek için biraz kendin uğraş, takıldığın yer oldukça sorarsın.

Ali
agora #10
Üye Tem 2013 tarihinden beri · 221 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Ali hocam. Konu ile ilgilenirken algım biraz daha farklı noktalara kaydı. Bazı şeyler düşünüyorum. Python ile yapmaktı ilk hedefim ama yavaşlayabilir diye düşündüm. Örneğin şöyle bir içerik var:

(begin
    (users
        id => 1
        level => 1
        user => "Ali"
        password => "test1"
    )
    (articles
        id => 1
        title => "Article Title"
        content => "This is Article Content"
    )
end)

(begin end) kısımları iç bloklardan bağımsız, temel yapı taşları. sadece içerideki bloklar farklı. sabit olmayacaklar. Buraları regex ile alabilirim sanırım. Ama mantığımın almadığı nokta şu. Burada satır mantığı nasıl işleyecek?

Böyle bir veri saklama formatı düşünüyorum kısacası bununla uğraşayım. D ile regex işleminde biraz zorlandım açıkcası. Daha sonra ise bu verileri geri döndürmek var :P Onun içinse şunu yapayım diyorum:

veri_islevi(tabloAdi, alanAdi/(hepsi ya da spesifik), kaç satır/(ya da hepsi));

SQL'den veri çekmek gibi. Bu işin yapabilme seviyesi nedir hocam?
acehreli (Moderatör) #11
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Bu gibi dosyalar veri tabanı olarak kullanılmaya elverişli değildir. Veri tabanı gerekiyorsa veri tabanı kullanmanı öneririm. Çoğu durumda SQLite yetiyor. Nerede bulabileceğini hatırlatıyorum:

  http://code.dlang.org/

Bu dosyalar veri tabanı olarak değil de HTML dosyası oluştururken kullanmak üzere ise, önerdiğin gibi düzenler kullanılabilir. O durumda da JSON veya YAML gibi yaygın düzenlerden birisini kullanmanı öneririm. (Gösterdiğin düzeni tanımıyorum; belki o da yaygın bir düzendir. :) )

Ali
agora #12
Üye Tem 2013 tarihinden beri · 221 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Aslında o benim kendi düzenim olacaktı :( yine de regex için deneyeceğim.
İbrahim #13
Üye Eki 2015 tarihinden beri · 156 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Merhaba, bu konudaki yorumları okuyunca aklıma şu sorular geldi:

1) Derleyici (örn. C++ derleyicisi) veya yorumlayıcılarda (örn. python yorumlayıcısı) bulunan regex kütüphaneleri nasıl bu kadar hızlı çalışıyorlar? Çünkü mesela ben bir regex yorumlayıcısı yapmak istesem bir sürü döngü ve yineleme içine girerim ve bu da bana performans sorunu oluşturuyor. Tüm dillerin (derlenen veya yorumlanan) regex ayrıştırıcıları nasıl bu kadar hızlı çalışıyorlar? (Ya da ben öyle zannediyorum :) ).

2) Github'da kabaca bir kaç derleyici ve yorumlayıcı kodlarına göz gezdirdim (HHVM, gcc, ruby, python falan felan), bunların hiçbiri de istenilen kod kurallarını regex kullanarak ayrıştırmamış (parse). Sorum ise bu regex bu kadar kolay, hızlı ayrıştırma işlemi yapmasına rağmen neden dil tasarlamada kullanılmıyor? Kullanılmamasındaki sebep nedir? (Bu soru yalnızca sözdizimi kurallarını kontrol etmeyi kasteder.)

Teşekkürler!
Alper# #14
Üye Haz 2015 tarihinden beri · 8 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Regex abartıldığı kadar optime çalışmıyor. Çok karmaşık bir patternde kafayı yedirtecek kadar olasılığı hesaplamaya çalışıyor. Günümüzün bilgisayarları bunu çok rahat halledecek seviyede. Sadece biz olan biteni çok küçük seviyede algılamamız çok zor.

Yukarıda python kodunu kaç kere işleme girdiğini hesaplayacak birşey olsa herşey çok net anlaşılacak. Online olarak Regex uygulamaları var. Hazırladığım küçük bir patterni uzun bir texte aratınca ortala 500 kere döngüye sokuluyor. İşi biraz daha kızştırınca iş işten geçiyor.

https://github.com/google/re2/tree/master/re2 güzel bir kaynak buldum sanırsam. Zamanı olan inceler.

Regex işin kolayı kaçmaktır. Eğer amacınız siteyi komple taratıp, veri çekip ve ayıklamaksa kullanmak için en basit yöntem oluyor. İşe yaradığıda doğrudur.

Şimdi aklıma bir yöntem geldi işe yararmı bilemeyeceğim.

const int a = 0x0001
const int b = 0x0002
const int c = 0x0004
const int d = 0x0008
const int e = 0x0016
const int f = 0x0032
const int g = 0x0064
const int h = 0x0128

örnek metin: acdasdfgghas
örnek pattern [a-d] diyelim. a ve d harfleri arasındaki bölümleri çıkartacak.

acdasdfgghas

a | b | c | d = 15

a | c | d | a = 15

Burada tek tek karekterlere değer verip (sürekli iki kat artacak) ve bitwise | işemi yapıp bileşkesini almak olur.
Böylece acda kısmını çıkartırıp, sonraki s harfi bileşkeyi bozacağı için onu dahil etmeden önceki kısmı veri olarak alabilir.

Bissürü yöntemi var denemek size kalmış. Regex yerine şifreleme algoritmasıyla kafa patlatılsa daha yararlı :)
Alper# #15
Üye Haz 2015 tarihinden beri · 8 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #13
İbrahim:
Merhaba, bu konudaki yorumları okuyunca aklıma şu sorular geldi:

1) Derleyici (örn. C++ derleyicisi) veya yorumlayıcılarda (örn. python yorumlayıcısı) bulunan regex kütüphaneleri nasıl bu kadar hızlı çalışıyorlar? Çünkü mesela ben bir regex yorumlayıcısı yapmak istesem bir sürü döngü ve yineleme içine girerim ve bu da bana performans sorunu oluşturuyor. Tüm dillerin (derlenen veya yorumlanan) regex ayrıştırıcıları nasıl bu kadar hızlı çalışıyorlar? (Ya da ben öyle zannediyorum :) ).

2) Github'da kabaca bir kaç derleyici ve yorumlayıcı kodlarına göz gezdirdim (HHVM, gcc, ruby, python falan felan), bunların hiçbiri de istenilen kod kurallarını regex kullanarak ayrıştırmamış (parse). Sorum ise bu regex bu kadar kolay, hızlı ayrıştırma işlemi yapmasına rağmen neden dil tasarlamada kullanılmıyor? Kullanılmamasındaki sebep nedir? (Bu soru yalnızca sözdizimi kurallarını kontrol etmeyi kasteder.)

Teşekkürler!

1) Python koca gövdeli kütüphanesiyle hızlı çalışmıyor. Biz öyle sanıyoruz. C/C++ hızlı olması doğasında olan birşey.

2) Hızlı olmak zorundalar. Derleyici(beklenirde) yada yorumlayıcı(bu siteye neden girmiyor yav xD) yavaş çalışırsa programcının vay haline. Farklı bir yöntem kullandıkları kesin ama nasıl olduğuna hiç bakmadım.

Regex her zaman doğru cevap vermez. Hata yapmamak için yapılmış birşey olması gerekli. Hele yorumlamalı diller. Her seferinde bir hata verip ve yavaş kalırsa iş çığırından kopar.
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Sayfa:  1  2  sonraki 
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-18, 22:36:39 (UTC -08:00)