C의 BNF 문법이 빈 init-declarator 시퀀스를 가진 선언을 허용하는 이유는 무엇입니까?


28

C의 BNF 문법을 살펴볼 때 선언의 생산 규칙이 다음과 같이 이상하다고 생각했습니다 ( https://cs.wmich.edu/~gupta/teaching/cs4850/sumII06/The%20syntax%20of% 20C % 20in % 20Backus-Naur % 20form.htm ) :

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

?에 대해 *수량자를 사용하는 이유 (0 번 이상 발생) init-declarator? 이는 의미 상 유효하지 않지만 구문 과 같은 int;또는 void;구문이 유효한 구문을 허용합니다 . 생산 규칙 +대신 수량 자 (한 번 이상 발생)를 사용할 수 없었 *습니까?

컴파일러가 무엇을 출력하는지 확인하기 위해 간단한 프로그램을 컴파일하려고했는데 경고가 발생했습니다.

입력:

int main(void) {
    int;
}

산출:

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

2
차이점은 BNF가 구문 만 정의한다는 것입니다. 상당히 많은 것들이 문법적으로 허용되지만 여전히 유효하지 않습니다.
Larkey

7
아, 함수 int의 반환 유형으로 main사용 ()하고 (void)대신 매개 변수 유형 목록으로 사용하십시오.
Larkey

1
개념적으로 , 이것에 약간의 재미가있는 것 외에는 아무런 문제가 없습니다. 기본적으로 컴퓨터에 "제로 int 변수를 원합니다, 이름 : [emptyset]." 결국 누군가에게 사과를 제로에게 요청할 수 있습니다 (물론 사과를 요구하는 것보다 조금 더 흥미로운 반응을 이끌어 낼 수는 있지만 본질적으로 무의미한 진술은 아닙니다). 따라서 왜 C에서 문법적이지 않아야합니까? 이런 종류의 문법에는 아무런 문제가 없습니다.
The_Sympathizer

어쨌든 공허한 (혹은 진공?) 사례를 포함 할 때 종종 상황이 훨씬 더 잘 작동합니다.
The_Sympathizer

때로는 프로그램을 작성하는 사람이 아니라 다른 프로그램을 작성하는 경우가 있습니다. 이러한 프로그램은 때때로 "int"뒤에 쉼표로 구분 된 목록 (필요한 evarname과 ";")을 인쇄하려고 할 수 있습니다. 해당 목록이 비어 있는지 확인할 필요가 없습니다.
Hagen von Eitzen

답변:


29

declaration-specifier포함 ( type-specifier포함) enum-specifier. 같은 구조

enum stuff {x, y};

declarationno 로 유효합니다 init-declarator.

문법 과 같은 제약 조건에int; 의해 다음 과 같은 구문 이 제외됩니다 .

static_assert 선언 이외의 선언은 최소한 선언자 (함수의 매개 변수 또는 구조체 또는 공용체의 멤버 제외), 태그 또는 열거 형 멤버를 선언해야합니다.

컴파일러 뒤에 경고를 발행하는 호환성 문제가 있다고 생각합니다.


14

초기화 선언자가없는 선언 :

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

단일 enum/ struct/ union지정 자가 아닌 선언 지정자 목록에는 무해하며 유용합니다.

원하는 경우, 제시된 문법은 잘못 선언을 일치 int struct foo x;하거나 double _Bool y;(이 같은 일을 일치시키기 위해 여러 지정자를 할 수 있습니다 long long int)하지만, 이러한 모든 의미 론적 점검, 나중에 검출 될 수있다.

BNF 문법 자체가 모든 불법 구문을 제거하지는 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.