it-swarm.dev

LL ve LR ayrışmasının ana avantajları ve dezavantajları nelerdir?

Bir programlama diline ayrıştırıcı oluştururken ne kazanıyorum ve birini ya da diğerini seçerek ne kaybettim?

29
Maniero

LL ve LR'yi bir dizi ölçüt için karşılaştırırım:

Karmaşıklık

LL burada kazanır, eller aşağı. LL ayrıştırıcısını kolayca elle yazabilirsiniz. Aslında, bu yaygın olarak yapılır: Microsoft C # derleyici elle yazılmış bir özyinelemeli iniş ayrıştırıcısı (kaynak burada , Patrick Kristiansen tarafından yapılan bir yorum arayın - blog yazısı da çok ilginç).

LR ayrıştırma, bir metni ayrıştırmak için oldukça sezgisel bir yöntem kullanır. Çalışıyor, ama kafamı tam olarak nasıl çalıştığına sarmak biraz zaman aldı. Bu nedenle böyle bir ayrıştırıcıyı elle yazmak zordur: az çok bir LR ayrıştırıcı üretecini uygularsınız.

Genellik

LR burada kazanır: tüm LL dilleri LR dilleridir, ancak LL dillerinden daha fazla LR dili vardır (dil, LL ayrıştırıcısıyla ayrıştırılabilirse LL dilidir ve dil, ayrıştırılabilirse LR dilidir bir LR ayrıştırıcısı).

LL, hemen hemen herhangi bir programlama dili uygularken will sizi rahatsız eden birkaç sıkıntıya sahiptir. Genel bir bakış için burada adresine bakın.

LR dili olmayan belirsiz diller vardır, ancak bunlar oldukça nadirdir. Bu tür dillerle neredeyse hiç karşılaşmıyorsunuz. Ancak, LALR'ın birkaç sorunu vardır.

LALR, LR ayrıştırıcılarının tabloları küçültmesi için aşağı yukarı bir hack'tir. Bir LR ayrıştırıcısı için tablolar tipik olarak çok büyük olabilir. LALR ayrıştırıcıları, daha küçük tablolar karşılığında tüm LR dillerini ayrıştırma yeteneğinden vazgeçer. Çoğu LR ayrıştırıcısı aslında LALR kullanır (gizlice değil, genellikle tam olarak ne uyguladığını bulabilirsiniz).

LALR, vardiya azaltma ve azaltma-azaltma çatışmalarından şikayet edebilir. Bu tablo kesmek neden olur: çoğu girişi boş olduğu için çalışan benzer girişleri birlikte 'katlar', ancak boş olmadıklarında bir çakışma oluşturur. Bu tür hatalar doğal değildir, anlaşılması zordur ve düzeltmeler genellikle oldukça gariptir.

Derleyici hataları ve hata giderme

LL kazanır. LL ayrıştırmasında, özellikle elle yazılmış ayrıştırıcılarda yararlı derleyici hataları yayınlamak genellikle oldukça kolaydır. Bundan sonra ne beklediğinizi biliyorsunuz, bu yüzden ortaya çıkmazsa, genellikle neyin yanlış gittiğini ve en mantıklı hatanın ne olacağını bilirsiniz.

Ayrıca, LL ayrıştırmada hata kurtarma çok daha kolaydır. Bir giriş düzgün ayrıştırılmazsa, biraz ileri atlamaya çalışabilir ve girişin geri kalanının doğru ayrışıp ayrışmadığını anlayabilirsiniz. Örneğin, bazı programlama ifadeleri hatalı biçimlendirilirse, ileri atlayabilir ve bir sonraki ifadeyi ayrıştırabilirsiniz;.

Bir LR ayrıştırıcısı kullanmak çok daha zordur. Hatalı girişi kabul etmek ve işlerin yanlış gittiği alanlarda hatalar yazdırmak için dilbilginizi artırmaya çalışabilirsiniz, ancak bunu yapmak oldukça zordur. LR olmayan (veya LALR olmayan) bir dilbilgisi elde etme şansınız da artar.

Hız

Hız, girişinizi ayrıştırma şeklinizle (LL veya LR) değil, sonuçta ortaya çıkan kodun kalitesi ve tabloların kullanımı ile ilgili bir sorundur (hem LL hem de LR için tabloları kullanabilirsiniz). Dolayısıyla LL ve LR bu açıdan karşılaştırılabilir.

Bağlantılar

Here , LL ve LR ile de çelişen bir sitenin bağlantısıdır. En alta yakın bölümü arayın.

Burada farklarla ilgili bir konuşma bulabilirsiniz. Orada dile getirilen görüşlere eleştirel olarak bakmak kötü bir fikir değil, orada bir miktar kutsal savaş var.

Daha fazla bilgi için, burada ve burada , ayrıştırıcılar hakkındaki kendi yayınlarımdan ikisi, ancak LL ve LR arasındaki kontrastla ilgili değiller.

44
Alex ten Brink