Kullanıcı tanımlı etki alanına özgü dilleri ayrıştırmak istiyorum. Bu diller genellikle matematiksel gösterimlere yakındır (doğal bir dili ayrıştırmıyorum). Kullanıcılar DSL'lerini aşağıdaki gibi bir BNF notasyonunda tanımlar:
expr ::= LiteralInteger
| ( expr )
| expr + expr
| expr * expr
Like 1 + ( 2 * 3 )
girişi kabul edilirken, like girişi 1 +
yanlış olarak reddedilmeli ve like girişi 1 + 2 * 3
belirsiz olarak reddedilmelidir.
Buradaki merkezi zorluk, belirsiz gramerlerle kullanıcı dostu bir şekilde baş etmektir. Dilbilgisinin açık olmasını kısıtlamak bir seçenek değildir: dil bu şekilde olur - fikir şu ki, belirsizlikleri önlemek için gerekli olmadığında parantezleri atlamayı tercih ederler. Bir ifade belirsiz olmadığı sürece, onu ayrıştırmam gerekir ve eğer değilse, reddetmem gerekir.
Ayrıştırıcım, bağlam içermeyen herhangi bir dilbilgisi, hatta belirsiz olanlar üzerinde çalışmalı ve tüm açık girdileri kabul etmelidir. Kabul edilen tüm girdiler için ayrıştırma ağacına ihtiyacım var. Geçersiz veya belirsiz giriş için ideal olarak iyi hata mesajları istiyorum, ancak başlamak için alabileceğimi alacağım.
Genellikle ayrıştırıcıyı nispeten kısa girdilerle ve arada sırada daha uzun girdilerle çağıracağım. Bu nedenle asimptotik olarak daha hızlı algoritma en iyi seçim olmayabilir. 20 sembol uzunluğundan daha az% 80, 20 ila 50 sembol arasında% 19 ve% 1 nadir daha uzun giriş dağılımı için optimizasyon yapmak istiyorum. Geçersiz girişlerin hızı büyük bir endişe kaynağı değildir. Ayrıca, DSL'de her 1000 ila 100000 giriş arasında bir değişiklik bekliyorum; Dilbilgimi ön işleme almak için birkaç saniye harcıyorum, birkaç dakika değil.
Tipik girdi boyutlarım göz önüne alındığında hangi ayrıştırma algoritmalarını araştırmalıyım? Hata bildirimi seçimimde bir faktör olmalı mı, yoksa net olmayan girdileri ayrıştırmaya odaklanmalı ve muhtemelen hata geribildirimi sağlamak için tamamen ayrı, daha yavaş bir ayrıştırıcı çalıştırmalı mıyım?
(İhtiyacım olan projede (bir süre önce), uygulanması çok zor olmayan ve girdi boyutlarım için yeterince çalışan ancak çok hoş hatalar oluşturmayan CYK kullandım .)
x+y+z
?
+
, bu yüzden x+y+z
gerçekten de belirsiz.