Forum: Ders Arası RSS
Parantezler Sembol Değil mi ?
std.uni
Avatar
huseyin #1
Üye Haz 2012 tarihinden beri · 363 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: Parantezler Sembol Değil mi ?
Merhaba

Ben lexerimde kullandığım "(" ve ")" parantezlerini isSymbol ile okumaya çalışıyorum ancak bir çıktı yok acaba onlar ayrı kategoride mi değerlendiriliyor ?
Teşekkürler
Huseyin
Avatar
Salih Dinçer #2
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Sanırım, noktalama ile ilgili 1076. satırdaki bool isPunctuation(dchar c) @safe pure nothrow işlevini kullanman gerekiyor. Çünkü parantez aç/kapanın koduna listede baktığımda 28 ve 29 olduğunu görüyorum. O ise tablePs ve tablePe'de duruyor. Hatta unittest'i de varmış:
    assert(isPunctuation('\u0028'));
    assert(isPunctuation('\u0029'));
Eğer UTF ile çok boğuşmayacaksan bence bunları kullanmana gerek yok. Kendin 'lookup table' yaparsan daha hızlı olacaktr. Baksana ne kadar çok kod üzerinde binary search yapıyorlar. Hatta parantez aç bir tabloda, kapası diğer tabloda. Gereksiz bunlar...:)

Hatta bak benim yeni öğrendiğim yöntem sizlerin çok işine yarayabilir. Geçen gün BufferStack için bir araştırma yapayım dedim. Bugüne kadar Viki'nin yığın maddesini hiç okumamıştım. Bir baktım hazine değerinde bilgiler ile dolu! Şu başlık ilgimi çekti ve zannedersem bu yöntem Talha'nın da ilgisini çekecektir:

Evaluation_of_an_infix_expression_that_is_fully_parenthesized

Hoş, belki de benzer bir şekilde siz zaten yapıyorsunuzdur. Ama kendi uygulamanız için bir yığın sınıfı geliştirip çok güzel ayrıştırma (parser) yapılabilir diye düşünüyorum.
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Bu mesaj Salih Dinçer tarafından değiştirildi; zaman: 2013-05-11, 06:04.
Değişiklik nedeni: Uzun Wikipedia maddesi düzeltildi...
Avatar
huseyin #3
Üye Haz 2012 tarihinden beri · 363 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Hmm o zaman kendim bir fonk üretip bool döndürsem yeterli olacaktır :)

O yöntemi duymuştum ama nasıl yapılacağı konusunda bilgi eksikliği var inceleyeceğim
Huseyin
Avatar
Salih Dinçer #4
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Belki aynı yöntemi kullanman hoş olabilir. Sonuçta dili geliştirenler bunun hızlı olduğu neticesine varmışlar. Öyleyse daha sade bir lookup table ile çok daha fazla hız elde etmen mümkün. Modülün en sonunda private olan şu işlevi kullanabilirsin:
bool binarySearch(alias table)(dchar c) @safe pure nothrow
{
    static @property bool checkTableEntry(alias table)()
    {
        foreach(i, entry; table)
        {
            assert(table[i][0] <= table[i][1]);
            if(i < table.length - 1)
                assert(table[i][1] < table[i + 1][0]);
        }
        return true;
    }
    static assert(checkTableEntry!table);
 
    return binarySearch2(c, table);
}
 
bool binarySearch2(dchar c, immutable dchar[2][] table) @safe pure nothrow
{
    // Binary search
    size_t mid;
    size_t low;
    size_t high;
 
    low = 0;
    high = table.length - 1;
    while(cast(int)low <= cast(int)high)
    {
        mid = (low + high) >> 1;
 
        if(c < table[mid][0])
            high = mid - 1;
        else if(c > table[mid][1])
            low = mid + 1;
        else
            goto Lis;
    }
    Lisnot:
        return false;
    Lis:
        return true;
}
Yukarıda 2 işlev var ve bunlardan ilki yardımcısı, diğer asıl işi yapıyor. Yardımcısı da demeyelim, tabloyu test ediyor. Zaten ikinci işlev de bildiğimiz binary search algorithm. Bunu ise şu şekilde statik bir tablo oluşturarak kullabilirsin:
 static immutable dchar[2][] tablomuz = [ //... ]; 
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Avatar
huseyin #5
Üye Haz 2012 tarihinden beri · 363 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Bende basit bir işlev olsun diyerekten
dchar[] tablo=['(',')','.'];
Yapıp bunu aşağıdaki şekilde ara dedim ancak
kod[i] in tablo

Error: rvalue of in expression must be an associative array, not dchar[]
Diye bir hata aldım :)
Huseyin
acehreli (Moderatör) #6
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ı
Aslında o kadar küçük tablada if-else-if daha hızlı olacaktır.

Hata doğru söylüyor: in'i ancak eşleme tablolarında kullanabiliyoruz. (Senin yaptığını isteyen başkaları da olmuştu.)

true'lara hiç bakılmayacak olduğu için saçma olsa da şu olur:
bool[dchar] tablo=['(':true,')':true,'.':true];

Sonra:
    if (kod in tablo) {
Ama tabii kapama tarafıyla da eşleyeceğin için başka çözümlere bakman gerekecek.

Ali
Avatar
huseyin #7
Üye Haz 2012 tarihinden beri · 363 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Ben şöyle bir çözüm buldum ama siz de bir görün sağlıklı bir çözüm mü acaba ?
bool Sembol(dchar c)
{
    dchar[] tablo=['(',')','.'];
    for(int j=0;j<tablo.length;j++)
    {
        if(c==tablo[j]){goto tr;break;}
    }
    return false;
    tr:
    return true;
    
}
Huseyin
acehreli (Moderatör) #8
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ı
Çözüm sağlıklı ama çok daha iyi olabilir. Öncelikle o break hiçbir zaman işletilemez. Ayrıca goto gibi karmaşıklıklar oluşturmak yerine if'in içine doğrudan 'return true' yazılıyor.

Ama daha kolayı var. std.algorithm.find zaten sırayla arar (ama kendisine sortedRange verilirse ikili arar). Tek satır olarak:
    return !find("().", c).empty;
Eğer amaç yalnızca içinde bulunup bulunmadığını anlamaksa canFind daha da kolay:
    return canFind("().", c);
Ama bu tür aramalar işine yarayacak mı gerçekten? Örneğin, herhangi bir sembol olmasından başka, açma parantezine karşılık kapama parantezinin geldiğinden emin olmak isteyeceksin herhalde.

Ali
Avatar
huseyin #9
Üye Haz 2012 tarihinden beri · 363 mesaj · Konum: Ankara
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
evet ben bunu parser e almayı düşünmüştüm eğer sizce uygunsa

if(token[s].tip==Tip.lParen && token[s+1].tip==Tip.rParen)
Şeklinde birşeyler düşündüm umarım doğrudur
Huseyin
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:
Forum: Ders Arası RSS
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-19, 19:42:57 (UTC -08:00)