2016-04-07 38 views
1

Bazı gramer kurallarım ile ilgili bir sorunum var.GPPG-Dilbilgisi - Bir kural hiç kullanılmayacak

gramer aşağıdaki gibidir: Input ile

defLINES : carrRet 
     | defLine carrRet 
     | defLines defLine carrRet 
     ; 

defLine : error carrRet        {yyerrok();} 
     | "DEF" kwType attrbt ID 
     | "DEF" kwType ID fieldSuff 
     ; 

kwType : "INT" 
     | "REAL" 
     ; 

fieldSuff: "[" expr "]" 
     | "[" expr "," expr "]" 
     ; 

attrbt : /* nothing */ 
     | "PHU" intValue 
     ; 

kontrol etmek: Bu Girişi için

DEF INT testvar1 
DEF REAL testvar2 

kafa "defLine" ile üretimin ikinci kural kullanılmalıdır.

Neden değil? Üçüncü kural her zaman

Unexpected 'carRet', '[' expected. 

Teşekkür yardım için bir sürü Alex kullanılan ve bir hata atar edilecek gramer mutlaka en az bir vardiya/üretim attrbt: /* nothing */ olduğuna dair bir uyarı ile birlikte çatışma azaltmak üretilen Yani

cevap

1

Çatışma yüzünden işe yaramaz. (Bu durum söz konusu değilse, GPPG'nin birçok uyarıyı bizon olarak vermemesidir. Ama eminim ki en azından bu değişikliği vardiya/çakışmayı azaltacaktır.)

Çatışma, kurallarda ortaya çıkar:

defLine : "DEF" kwType attrbt ID 
defLine : "DEF" kwType ID fieldSuff 

attrbt boş olabilir, ancak ikinci kural ID önce olamaz çünkü. Ayrıştırıcının DEF INT ile karşılaştığını ve sonraki sembolün ID olduğunu varsayalım. Bu noktada, ayrıştırıcı, defLine için hangi iki üretimden hangisinin kullanılacağını bilmez, ancak fark önemlidir. İlk durumda, ayrıştırıcı ID'u değiştirmeden önce boş bir attrbt'u azaltmalıdır. İkinci durumda, attrbt oluşturmak bir hata olur.

Yacc benzeri ayrıştırıcı jeneratörler, her zaman, kaydırma önceliklerini (öncelikli bildirimler olmadıkça) kayma lehine kaydırır/azaltır; bu durumda, ID her zaman kaydırılır. Bu, attrbt: /* nothing */ üretimini asla düşürmenin imkansız olduğu anlamına gelir. (Bison, en azından, bu gerçeği hakkında sizi uyarır.

Dahası, ID vardiya bu durumda oluşacak beri ayrıştırıcı ID takip etmek fieldStuff gerektirecektir yüzden, defLine için yalnızca ikinci üretim, satışa sunulacak ve fieldStuff[ ile başlamalıdır. karşılaşabileceğiniz Dolayısıyla ayrıştırma hatası.

Bunu düzeltmek için, itilaftan azaltmak/vardiya kaldırmak gerekir. Bir basit bir yolu hem defLine üretimlerde attrbt izin olacaktır (eğer algılayabilir semantik eylemde hata) Başka bir olasılık attrbt için boş üretimi kaldırmak ve açıkça izin vermek eksik:

attrbt : "PHU" intValue 

defLine : "DEF" kwType ID 
     | "DEF" kwType attrbt ID 
     | "DEF" kwType ID fieldSuff 
+0

Tamam, yardımlarınız için teşekkürler! Sorunu semantik Eylemde çözmeye karar verdim ve attrbt'e izin verdim. Teşekkürler ... =) – Alex