C'nin BNF dilbilgisi neden boş bir init-declarator dizisi içeren bildirimlere izin veriyor?


28

C'nin BNF gramerine bakarken, bir deklarasyon için üretim kuralının böyle görünmesinin garip olduğunu düşündüm ( https://cs.wmich.edu/~gupta/teaching/cs4850/sumII06/The%20syntax%20of% uyarınca 20C% 20in% 20Backus-Naur% 20form.htm ):

<declaration> ::=  {<declaration-specifier>}+ {<init-declarator>}* ;

Neden bir *nicelik belirteci (sıfır veya daha fazla tekrarlama anlamına gelir) init-declarator? Bu, anlamsal olarak geçersiz olmalarına rağmen int;veya gibi ifadelerin void;sözdizimsel olarak geçerli olmasına izin verir . Üretim kuralı +yerine bir nicelik belirteci (bir veya daha fazla tekrar) kullanamazlar mıydı *?

Derleyicinin çıktılarını görmek için basit bir program derlemeyi denedim ve tüm yaptığı uyarı.

Giriş:

int main(void) {
    int;
}

Çıktı:

test.c: In function main’:
test.c:2:5: warning: useless type name in empty declaration
     int;
     ^~~

2
Fark, BNF'nin sadece sözdizimini tanımlamasıdır. Oldukça fazla şeye sözdizimsel olarak izin verilir, ancak yine de geçersiz (veya saçma) C.
larkey

7
Ah ve lütfen işlevler intiçin bir dönüş türü olarak mainkullanın ()ve işlevlerde bir parametre türleri listesi olarak (void)kullanmayın.
larkey

1
Kavramsal olarak , bununla ilgili gerçekten yanlış bir şey yok, biraz komik görünmesi dışında: temelde bilgisayara "sıfır int değişkenleri istiyorum, lütfen: [emptyset]." Diye soruyor. Sonuçta birinden sıfır elma isteyebilirsiniz (muhtemelen bir tane istemekten biraz daha ilginç bir tepki ortaya çıkarsa da, doğal olarak saçma bir ifade değildir). Peki neden C'de sembolik olmamalı? Bu tür bir gramerde yanlış bir şey yok.
The_Sympathizer

Zaten boş (veya belki vakum?) Davayı dahil ettiğimizde, işler çok daha iyi çalışır.
The_Sympathizer

Bazen bir program yazan bir insan değil, başka bir programdır. Böyle bir program bazen "int" ve ardından ihtiyaç duyduğumuz isimler için virgülle ayrılmış bir liste ve ardından ";" ve ilk önce söz konusu listenin boş olup olmadığını kontrol etmemeniz gerekir.
Hagen von Eitzen

Yanıtlar:


29

declaration-specifieriçeren type-specifieriçerir, enum-specifier. Gibi bir yapı

enum stuff {x, y};

, declarationno ile geçerlidir init-declarator.

Gibi int;yapılar , dilbilgisinin ötesindeki kısıtlamalar tarafından göz ardı edilir :

Static_assert bildirimi dışında bir bildirim, en az bir bildirici (bir işlevin parametreleri veya bir yapı veya birleşimin üyeleri dışında), bir etiket veya bir numaralandırma üyeleri bildirir.

Derleyicinizin arkasında sadece uyarı veren geriye dönük uyumluluk nedenleri olduğunu tahmin ediyorum.


14

Başlangıç ​​bildiricisi olmayan bir bildirim:

<declaration> ::=  {<declaration-specifier>}+ {<init-declarator>}* ;

tek olmayan bildirim belirteci listeleri için zararsızdır enum / struct/ unionbelirteci ve olanlarla uyumludur.

Her halükarda, sunulan dilbilgisi de, int struct foo x; veyadouble _Bool y; (bu gibi şeyleri eşleştirmek için birden fazla belirleyiciye izin verir long long int), ancak tüm bunlar daha sonra bir semantik kontrolde tespit edilebilir.

BNF dilbilgisi, tüm yasadışı yapıları ayıklamayacak.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.