대부분의 프로그래밍 언어는 숫자로 시작하는 식별자를 선언 할 수 없도록 설계되었습니다. 나는 그 이유를 알고 싶어했습니다. 이미 웹을 검색했지만 만족스러운 설명을 찾을 수 없습니다.
대부분의 프로그래밍 언어는 숫자로 시작하는 식별자를 선언 할 수 없도록 설계되었습니다. 나는 그 이유를 알고 싶어했습니다. 이미 웹을 검색했지만 만족스러운 설명을 찾을 수 없습니다.
답변:
C / C ++에서 숫자 다음에 문자가 오는 것은 숫자 상수로 간주되며 다음에 오는 문자열은 상수 유형을 규정합니다. 예를 들어 (VC ++는 표준인지 확실하지 않습니다).
그것은 렉서 쉽게 임) 그래서 다니엘은 해당 제품이 사용 된 이후뿐만 아니라 B)가 명시 적으로 구분하지 말했듯이 있습니다 변수가 될하지만 0U은 결코 것입니다. 또한 "i64"와 같은 다른 한정자는 "l"또는 "u"보다 늦게 추가되었으며 필요한 경우 옵션을 더 추가 할 수있는 옵션을 유지하려고합니다.
렉서를 구현하는 사람들의 편의성. (아니오, 진지하게, 그것은 그것에 관한 것입니다. 다양한 언어에는 다른 이유가 있지만 궁극적으로 그에 따릅니다.)
0flu
리터럴이고 0glu
로컬 식별자 인 경우 매우 어색합니다 .
int 0u = 5; unsigned int x = 0u;
그러나이 코드의 해석을 정의하도록 선택하면 (예 : x == 0 또는 x == 5) 사람들은 혼란스러워합니다. 모호성 때문에 이런 식으로 컴파일러를 구현하는 것이 사소한 일이지만 훌륭한 디자이너는 그렇게하지 않을 것입니다.
다음 두 가지 경우를 고려하십시오.
식별자가 숫자로 시작할 수 있다고 가정합니다.
따라서 식별자는 1 문자 이상을 가질 수 있으므로 아래와 같은 문장이 유효합니다.
int 3;
프로그램에서 위의 변수를 사용하려고하면 컴파일러 모호성이 발생합니다.
int 3, a;
3 = 5;
a = 3;
진술 a=3
에서 3의 역할은 무엇입니까 (값 5의 변수입니까, 아니면 숫자 3입니까)?
위의 예와 달리, 언어는 숫자로 시작하는 식별자를 실제로 식별자로 사용하는 것을 허용하지 않고 숫자로 시작하는 식별자를 실제로 허용한다고 가정합니다. 다음과 같은 문제가 발생할 수 있습니다.
변수에 대한 언어 규칙은 변수가 1 개 이상의 문자로 구성 될 수 있음을 나타내는 다음과 같은 복잡한 규칙으로 다시 정의되어야합니다. 변수는 하나 이상의 문자를 가질 수 있으며 변수가 숫자로 시작하지 않으면 고유해야합니다. 숫자 등으로 시작할 때 단일 문자 길이를 사용할 수 없습니다.
컴파일러는 모든 숫자 (예 : 333)와 유효한 알파벳 접미사 (예 : 34L)를 변수 이름으로 사용하는 경우 오류 사례를 확인하고보고해야합니다. 변수를 선언하지 않고 즉석에서 변수를 사용할 수있는 Python 및 JS와 같이 느슨하게 입력 된 언어에서는 모든 숫자와 관련된 특수한 경우를 확인하는 것이 불가능할 수도 있습니다. 예를 들어 if (33==5)
, 33은 사용자가 선언 한 잘못된 선언되지 않은 변수 일 수 있습니다. 그러나 컴파일러는이를 식별하고 오류를보고 할 수 없습니다.
이 제한을 설정하면 프로그래머가 숫자를 식별자 이름으로 사용하지 못하게됩니다.
int char = float
이 될지 상상이 되십니까 ?
int
는 식별자가 아닌 키워드를 어떻게 알 수 있습니까? 글쎄, int
숫자 형 exemes와 마찬가지로 우선 순위가 높습니다.
int 3,a; 3=5; a=3;
하십시오. a = 3 명령문에서 3은 식별자 또는 숫자로 해석됩니까? 모호함이 발생합니다. 그것이 분명하기를 바랍니다.
대부분의 경우 이것은 컴파일러 작성자와 구문 분석 효율성을 쉽게 만드는 것과는 관련이 없지만 명확하고 읽기 쉽고 명확한 코드를 장려하는 구문을 설계하는 것과 관련이 있습니다.
언어 디자이너는 숫자 1과 같은 숫자 리터럴을 평범한 1 로 쓸 수 있으면 좋을 것이라고 생각했습니다 .
숫자 리터럴이 tildas와 같은 방식으로 인용되는 언어 구문을 설계하는 것이 가능하므로 숫자 1의 숫자 리터럴은 ~ 1 ~ 로 인코딩되고 키워드가 아니며 따옴표로 묶지 않은 것은 변수 이름으로 취급됩니다 .
따라서 다음과 같은 명령문을 코딩 할 수 있습니다.
1 = ~2~
two = 1 * ~2~
또한 :
2 = ~3~
six = 2 + 2
모호하고 따르기 어려운 구문을 선택하는 것은 피할 수 없습니다.
C 언어와 C의 하위 "대괄호"언어는 프로그래머가 8 진 및 16 진 리터럴을 직접 코딩하고 이것이 중요한 경우 리터럴 유형을 지정할 수 있도록하는 것이 좋습니다. 그래서
010 // Octal 10 = 8;
0x10 // Hexadecimal 10 = 16;
5l // long integer with decimal value 5
2.0d // double float with value 2
따라서 변수 이름이 숫자로 시작하고 하나 이상의 문자를 포함하는 숫자와 문자의 조합으로 시작하더라도 프로그래머가 주어진 그룹이 변수 이름 또는 숫자 리터럴을 형성하는지 여부를 결정하는 문제를 제시하게됩니다.
2lll = 22 // OK
2ll = 2 // compiler error
이러한 모호성은 프로그램을 쓰거나 읽는 사람에게는 도움이되지 않습니다.
밀접하게 관련된 실제 예를 들어, 디자이너가 키워드를 변수 이름으로 사용할 수 있다고 생각한 PL / 1 언어를 보면 다음과 같습니다.
IF THEN THEN THEN = ELSE; ELSE ELSE = THEN;
IF IF THEN ELSE = IF; ELSE THEN = ELSE;
DO WHILE (WHILE = DO); END = WHILE + DO; END;
컴파일하고 실행하는 유효한 코드입니다.
포트란은 후기 언어가 어떻게 설계되었는지에 큰 영향을 미쳤다. 초기에 (이러한 문제 중 일부는 수정되었으므로) Fortran에는 식별자에 부여 할 수있는 이름을 제한하는 규칙 이 거의 없었습니다. 이로 인해 컴파일러와 프로그래머 모두 언어를 구문 분석하기가 매우 어려워졌습니다. 전형적인 예가 하나 있습니다 :
if if .eq. then then = else else else = endif endif
K I K K I I K I I K
여기서는 "언어 키워드"를 K와 식별자 (변수 이름)로 표시했습니다. 철자에 차이가없는 것을 감안할 때, 이것이 어떻게 혼동 될 수 있는지 이해할 수있을 것입니다. 물론 이것은 극단적 인 예이며, 의도적으로 이와 같은 코드를 작성한 사람은 거의 없습니다. 때때로 사람들 은 식별자 이름으로 언어 키워드를 "재활용"했습니다. 많은 경우에 간단한 오타로 인해 언어 사양이 전혀 의도되지 않았더라도 이러한 방식으로 구문 분석되어야한다는 코드가 생성 될 수 있습니다. 다른 잘 알려진 예를 보려면 다음을 비교하십시오.
do 10 i = 1,10
이에:
do 10 i = 1.10
첫 번째는 do 루프입니다. 코드 블록을 10 번 반복합니다. 그러나 두 번째는 쉼표가 소수점으로 바뀌 었으므로 값 1.10
을 변수에 할당합니다 do 10 i
.
이것은 또한 포트란 파서를 작성하는 것이 상대적으로 어렵다는 것을 의미했습니다 do
. 줄의 시작 부분이 줄의 끝에 도달 할 때까지 실제로 핵심 단어 임을 확신 할 수 없었 습니다. do
루프가 존재했습니다. 파서는 일반적으로 처음부터 줄을 다시 파싱하여 실제로 존재했던 것에 대한 "올바른"(그러나 종종 의도하지 않은) 대답에 도달하도록 "역 추적"할 준비가되어 있어야했습니다.
이 몇 년 후, 언어 디자이너는 (그들의 대부분 어쨌든) 반대의 극단으로 갔다 - 불평하는 사용자없이 가능한 한만큼 언어에 대한 거의 모든 제한 이 너무 많이.
예를 들어 초기 BASIC은 기본적으로 키워드의 일부 를 식별자의 일부로 사용할 수 없다고 말했습니다. 예를 들어, 할당이 아닌 루프 의 시작과 fora=1
같이 구문 분석됩니다 . 그것은 오래 가지 못했던 충분한 불만을 제기 한 것 같습니다. 숫자로 식별자를 시작하는 규칙은 많은 불만을 발생시키지 않았으므로 계속 사용됩니다 (적어도 대부분의 언어에서).for a = 1
for
프로그래밍 언어에는 논리적으로 필요한 규칙이 아니라 많은 언어 디자이너가 사용하는 규칙 일뿐입니다.
식별자에 모든 문자를 허용하는 완전히 다른 언어를 디자인 할 수 있습니다. 모든 코드 행에서 처음 20 자 문자는 명령문 유형을 설명하고 다음 20 자 문자는 명령문의 첫 번째 기호를 정의하며 다음 20 자 문자는 명령문의 피연산자입니다. 이 언어는 스택 프로세서에서 실행됩니다.
01234567890123456789 01234567890123456789 01234567890123456789
decl symbol 12345
assign value 12345 12345
decl symbol 99999
assign value 99999 12345
push 12345
push 99999
add
print top
이 코드는 다음과 같이 C로 번역 될 수 있습니다.
int i12345 = 12345;
int i99999 = 12345;
printf("%d", i12345+i9999);
그게 다야. 의미가없고 번호가없는 수 규칙도 논리적으로 무의미합니다.
이 질문에 대한 답은 오토마타 또는 정규식을 정의하는보다 정확한 유한 오토마타에 있습니다. 규칙은 ... 컴파일러가 구문 분석하는 모든 문자를 결정하기 위해 정확한 알고리즘이나 규칙이 필요하다는 것입니다. 식별자가 숫자로 시작하도록 허용되면 컴파일러는 토큰의 성격에 대해 수정됩니다. 숫자 또는 식별자가 될 것입니다. 컴파일러는 이전 위치로 되돌릴 수 없습니다. .so .. 다가오는 토큰이 정확하게 식별자 또는 숫자라는 것을 컴파일러에게 분명히하기 위해 ...이 제한이 있습니다 ... 이것의 coz ... 컴파일러는 다가오는 토큰이라는 첫 문자를 스캔하여 알 수 있습니다. 식별자 또는 숫자입니다.