SLR, LALR ve LR ayrıştırıcılarının tümü, tamamen aynı masa tabanlı makine kullanılarak uygulanabilir.
Temel olarak, ayrıştırma algoritması bir sonraki giriş belirteci T'yi toplar ve ne yapılacağına karar vermek için mevcut durum S'ye (ve ilişkili önden, GOTO ve azaltma tablolarına) danışır:
- SHIFT: Mevcut tablo T belirteci üzerinde SHIFT diyorsa, çift (S, T) ayrıştırma yığınına itilir, durum GOTO tablosunun geçerli simge için söylediğine göre değiştirilir (örneğin, GOTO (T) ), başka bir giriş belirteci T 'getirilir ve işlem tekrar eder
- AZALT: Her eyalette 0, 1 veya eyalette meydana gelebilecek birçok olası azaltma vardır. Ayrıştırıcı LR veya LALR ise, belirteç, durum için tüm geçerli azaltmalar için önden okuma kümelerine göre kontrol edilir. Belirteç, dilbilgisi kuralı G = R1 R2 .. Rn için bir azaltma için önden okuma kümesiyle eşleşirse, bir yığın azaltma ve kaydırma gerçekleşir: G için anlamsal eylem çağrılır, yığın n (Rn'den) kez atılır, çift ( S, G) yığın üzerine itilir, yeni S 'durumu GOTO (G)' ye ayarlanır ve döngü aynı token T ile tekrarlanır. Ayrıştırıcı bir SLR ayrıştırıcısı ise, için en fazla bir azaltma kuralı vardır. durum ve böylece indirgeme eylemi, hangi indirimin geçerli olduğunu görmek için arama yapmadan körü körüne yapılabilir. Orada olmadığını bilmek bir SLR ayrıştırıcı için yararlıdır olduğunubir azalma ya da değil; bu, her devletin kendisiyle ilişkili azaltma sayısını açıkça kaydettiğini ve pratikte L (AL) R versiyonları için bu sayının gerekli olup olmadığını anlamak kolaydır.
- HATA: SHIFT veya REDUCE mümkün değilse, sözdizimi hatası bildirilir.
Öyleyse, hepsi aynı makineyi kullanıyorlarsa, ne anlamı var?
SLR'de sözde değer, uygulamadaki basitliğidir; Önden okuma setlerini kontrol ederek olası azaltmaları taramanıza gerek yoktur çünkü en fazla bir tane vardır ve bu durumdan SHIFT çıkışı yoksa tek uygulanabilir eylemdir. Hangi indirgemenin geçerli olduğu duruma özel olarak bağlanabilir, bu nedenle SLR ayrıştırma makinesinin bunun peşine düşmesi gerekmez. Uygulamada, L (AL) R ayrıştırıcıları, yararlı bir şekilde daha büyük bir dil kümesini idare eder ve uygulamak için çok az fazladan iştir ki, akademik bir alıştırma dışında hiç kimse SLR'yi uygulamaz.
LALR ve LR arasındaki fark tablosu ile ilgisi var jeneratör. LR ayrıştırıcı üreteçleri, belirli durumlardan olası tüm azaltmaları ve bunların hassas önden okuma setini takip eder; her indirgemenin, sol bağlamından yola çıkarak tam önden ayarlıyla ilişkili olduğu durumlar elde edersiniz. Bu, oldukça büyük devlet kümeleri oluşturma eğilimindedir. LALR ayrıştırıcı üreteçleri, GOTO tabloları ve indirgeme için bakma kafası kümeleri uyumluysa ve çakışmıyorsa durumları birleştirmeye isteklidir; bu, LR'nin ayırt edebileceği belirli sembol dizilerini ayırt edememe pahasına, önemli ölçüde daha az sayıda durum üretir. Bu nedenle, LR ayrıştırıcıları, LALR ayrıştırıcılarından daha büyük bir dil kümesini ayrıştırabilir, ancak çok daha büyük ayrıştırıcı tablolarına sahiptir. Uygulamada, durum makinesinin boyutunun optimize edilmeye değer olduğu hedef dillere yeterince yakın olan LALR gramerleri bulunabilir;
Yani: Üçü de aynı makineyi kullanıyor. SLR, makinenin küçük bir parçasını görmezden gelebileceğiniz anlamında "kolay" dır, ancak bu zahmete değmez. LR daha geniş bir dil kümesini ayrıştırır, ancak durum tabloları oldukça büyük olma eğilimindedir. Bu, LALR'ı pratik bir seçim olarak bırakır.
Tüm bunları söyledikten sonra, GLR ayrıştırıcılarının herhangi bir bağlamdan bağımsız dili, daha karmaşık makineler kullanarak, ancak tam olarak aynı tabloları (LALR tarafından kullanılan daha küçük sürüm dahil) ayrıştırabileceğini bilmeye değer . Bu, GLR'nin LR, LALR ve SLR'den kesinlikle daha güçlü olduğu anlamına gelir; hemen hemen standart bir BNF dilbilgisi yazabilirseniz, GLR buna göre ayrıştırır. Mekanizmadaki fark, GLR'nin GOTO tablosu ve / veya önden okuma setleri arasında çelişkiler olduğunda birden fazla ayrıştırmayı denemeye istekli olmasıdır. (GLR'nin bunu nasıl verimli bir şekilde yaptığı, katıksız bir dahidir [benim değil] ama bu SO gönderisine uymuyor).
Bu benim için son derece yararlı bir gerçek. Program çözümleyicileri oluşturuyorum ve kod dönüştürücüleri ve ayrıştırıcılar gerekli ama "ilginç değil"; ilginç çalışma, ayrıştırılmış sonuçla yaptığınız şeydir ve bu nedenle odak, ayrıştırma sonrası çalışmayı yapmaktır. GLR kullanmak, LALR kullanılabilir forma girmek için bir grameri hacklemeye kıyasla nispeten daha kolay çalışan gramerler oluşturabileceğim anlamına geliyor. Bu, C ++ veya Fortran gibi akademik olmayan dillerle uğraşmaya çalışırken çok önemlidir; burada kelimenin tam anlamıyla tüm dili iyi idare etmek için binlerce kurala ihtiyaç duyarsınız ve hayatınızı dilbilgisi kurallarını kırmaya çalışmakla geçirmek istemezsiniz. LALR (veya hatta LR) sınırlamalarını karşılar.
Ünlü bir örnek olarak, LALR ayrıştırması yapan adamlar tarafından C ++ 'nın ayrıştırılması son derece zor kabul edilir. C ++, C ++ referans kılavuzunun arkasında sağlanan kuralları hemen hemen kullanarak GLR makinelerini kullanarak ayrıştırmak için basittir. (Kesinlikle böyle bir ayrıştırıcım var ve sadece vanilya C ++ 'yı değil aynı zamanda çeşitli satıcı lehçelerini de işliyor. Bu sadece pratikte mümkün çünkü bir GLR ayrıştırıcı, IMHO kullanıyoruz).
[DÜZENLEME Kasım 2011: Ayrıştırıcımızı tüm C ++ 11'i işleyecek şekilde genişlettik. GLR bunu çok daha kolay hale getirdi. Ağustos 2014'ü DÜZENLE: Artık tüm C ++ 17'yi işliyor. Hiçbir şey kırılmadı ya da kötüleşmedi, GLR hala kedinin miyavı.]