Ketika melihat melalui tata bahasa BNF C, saya pikir itu aneh bahwa aturan produksi untuk deklarasi terlihat seperti ini (menurut https://cs.wmich.edu/~gupta/teaching/cs4850/sumII06/The%20syntax%20of% 20C% 20di% 20Backus-Naur% 20form.htm ):
<declaration> ::= {<declaration-specifier>}+ {<init-declarator>}* ;
Mengapa menggunakan *
quantifier (artinya nol atau lebih kejadian) untuk init-declarator
? Ini memungkinkan pernyataan seperti int;
atau void;
menjadi valid secara sintaksis, meskipun secara semantik tidak valid. Tidak bisakah mereka menggunakan +
kuantifier (satu kejadian atau lebih) daripada *
dalam aturan produksi?
Saya mencoba mengkompilasi program sederhana untuk melihat apa yang dihasilkan oleh kompiler dan yang dilakukannya hanyalah mengeluarkan peringatan.
Memasukkan:
int main(void) {
int;
}
Keluaran:
test.c: In function ‘main’:
test.c:2:5: warning: useless type name in empty declaration
int;
^~~
c
language-lawyer
context-free-grammar
rafaelfp
sumber
sumber
int
sebagai tipe pengembalian untukmain
dan jangan gunakan()
sebagai daftar jenis parameter dalam fungsi tetapi(void)
sebagai gantinya.Jawaban:
declaration-specifier
termasuktype-specifier
, yang termasukenum-specifier
. Konstruk sepertivalid
declaration
dengan noinit-declarator
.Konstruksi seperti
int;
dikesampingkan oleh kendala di luar tata bahasa :Saya kira ada alasan kompatibilitas di belakang kompiler Anda hanya mengeluarkan peringatan.
sumber
Deklarasi tanpa deklarasi init:
tidak berbahaya untuk daftar specifier deklarasi yang bukan satu
enum
/struct
/union
specifier dan berguna sesuai dengan yang ada.Dalam setiap kasus, tata bahasa yang disajikan juga akan secara keliru mencocokkan deklarasi seperti
int struct foo x;
ataudouble _Bool y;
(memungkinkan beberapa penspesifikasi untuk mencocokkan hal-hal sepertilong long int
), tetapi semua ini dapat dideteksi kemudian, dalam pemeriksaan semantik.Tata bahasa BNF itu sendiri tidak akan menyingkirkan semua konstruksi ilegal.
sumber