5

Bir hesap makinesi dili için bir LL (1) yukarıdan aşağı çözümleyici kullanmaya çalışıyordum. Sadece sayıları toplamanıza, çıkarmamıza, bölmemize ve çarpmamıza izin verir. Parantez yok. Bu dilbilgisi bir LL (1) ayrıştırıcı için uygun değildir gibiSol birleştirici bir işleç, yukarıdan aşağı LL (1) ayrıştırıcılarının anlayabileceği şekilde ifade edilebilir mi?

S -> A 

A -> B + A 
    | B - A 
    | B 

B -> int * B 
    | int/B 
    | int 

, bunu biraz değiştirmek zorunda:

S -> A 

A -> B A' 
A'-> + A 
    | - A 
    | λ 

B -> int B' 
B'-> * B 
    |/B 
    | λ 

sorun şimdi dilbilgisi için ilişkisel kalmaması olduğunu Gösterilen 4 operatör ve buna ihtiyacım var. Bu problem nasıl çözülür? Bunu başarmak bile mümkün mü?

+1

Sanırım cevabı "LL (1) ayrıştırıcısı kullanmayın", sonra ":). Ama bu gerçek: 'LL (1)' parsers ayrıştırma ifadeleri için iyi bir eşleşme değildir; Herhangi bir nedenden 'LR (1)' kullanmak istemiyorsanız, bir Pratt ayrıştırıcısı veya bir operatör önceliği ayrıştırıcısı yazın (bkz. "Şantlı Yard algoritması") – rici

+1

Eh, sadece ayrıştırıcıları öğreniyorum. Birkaç çeşit parseer için basit bir hesap dili kullanmaya çalışmayı planladım. LL (1) ile bir hesap makinesinin yapılmasının mümkün olmadığını mı söylüyorsunuz? –

+0

Bunun imkansız olduğunu belirtmiyorum, sadece önemsiz değil. Değiştirilen dilbilgisi için bir ayrıştırma ağacı oluşturmak için LL (1) ayrıştırıcısını kullanarak yapabilir ve sonra özgün dilbilgisi için ayrıştırma ağacı oluşturmak üzere ayrıştırma ağacındaki dönüşümü tersine çevirebilirsiniz. – rici

cevap

6

Yinelemeyi yinelemeli olarak değiştirerek sol ilişkiyi alabilirsiniz. Aşağıdaki sıralama-türkodu kodu, sadece basitlik için değerleri doğrudan hesaplar, ancak aynı yöntemi kullanarak bir ayrıştırma ağacı oluşturabilirsiniz.

function A() { 
    val = B(); 
    t = peek(); 
    while (t=='+' || t=='-') { 
    match(t); 
    val1 = B(); 
    if (t=='+') 
     val = val + val1; 
    else 
     val = val - val1; 
    t = peek(); 
    } 
    return(val) 
} 
peek() yemekten sonraki belirteci döndürür

ve match() sonraki jetonu yiyor. B() için de aynısını yaparsın.

İlgili konular