Çalışan bir algoritma tanımlayacağım. Çalışma süresi çok kötü olmamalı. Bunun bir kısmını önceden hesaplayabilirsiniz.
Bunu varsayıyoruz (muhtemelen kolay bu durumda uyum olsa) nonterminallerin içermez ve bilmediklerini x , y veya türetilmesini bir . Ayrıca dilbilginizin hiçbir türevde hiç kullanılmayan yapımları içermediğini varsayacağım ( örneğin A → A ).axyaA→A
Ana konu gerçekten ayrıştırmak için sen sona devletlerin tür bilmek istiyorum gibi takip edebilirsiniz biliyorum bu yüzden, bir . Bu x'i bilmediğiniz kadar kolay değil .aax
Earley'in algoritmasının bir uyarlamasını kullanıyoruz . Önce bu algoritmayı anlamak isteyeceksiniz. Başlatma ve tamamlama adımlarımız farklı olmadıkça algoritmamız neredeyse aynı şekilde çalışır.
Başlatma için, her geçtiği için bir Earley öğe ile bizim ilk seti tohum (ilk karakterin bir senin dilbilgisi herhangi üretiminde). Bu öğenin arka işaretçisini geçersiz bir değer olan -1 olarak ayarladık. Değiştirilmiş tamamlamamızda bu önemlidir. Aslında -1 'bu üretimin nereden başladığı hakkında hiçbir fikrim yok' anlamına geliyor.a1a
Şimdi, Earley algoritmasını olası ilk Earley öğeleri için ayrı ayrı gerçekleştiriyoruz. Ayrıştırmaları birbirine müdahale edebileceğinden, hepsini aynı anda yapamayız. Burada geri izlemekten daha hızlı bir yöntem göremiyorum.
Tamamlama adımı için, yalnızca -1 geri işaretçisi işlemek için bir değişiklik yapmamız gerekir. Kökeni bilmediğimiz bir prodüksiyonu tamamladığımız için başımız belada. Bununla birlikte, Pennello ve DeRemer tarafından L A L R ( 1 ) önden okuma kümelerini hesaplamak için kullanılan yöntemLALR(1) bizi kurtarır: burada ihtiyacımız olan tam olarak L A L R ( 1 ) önden okuma setleri. Bu ileri okuma setlerindeki her öğenin dilbilgisinde karşılık gelen bir konumu vardır ve bu da tamamlanmış üretimin olası bir devamına karşılık gelir.LALR(1)
LALR(1)
a
Düzenleme: Ben geri izleme tarafından getirilen havai çoğunu kaldıran yöntemi buldum düşünüyorum. Her Earley öğesiyle, bu tanımlayıcıların öneklerini kullanmamız gerektiğinden, dizeler olan bir dizi tanımlayıcı ile ilişkilendiriyoruz. Başlatma sırasında, tüm başlangıç öğelerini Earley setine ekler ve her setle benzersiz bir tanımlayıcı ilişkilendiririz.
Tarayıcı ve öngörücü adımlar üzerinde tanımlayıcılar yeni öğelere taşınır. Aynı Earley setindeki yalnızca tanımlayıcılarında farklılık gösteren earley öğeleri, tanımlayıcıları birleştirilerek birleştirilir. Bu adımı her bir tanımlayıcı için ayrı ayrı yapmak zorunda kalmadan, bu yeni öğeler üzerinde tanımlayıcılarla tarayıcı ve öngörücü adımlar gerçekleştirebileceğimizi unutmayın.
LALR(1)
Temel olarak, geri tanımlamayı bu tanımlayıcıları kullanarak yapıyoruz, böylece tarayıcı ve öngörücü adımlarda çift çalışma yapmıyoruz.