이름 확인(프로그래밍 언어)

Name resolution (programming languages)

프로그래밍 언어에서 이름 분해능은 프로그램 표현식 내의 토큰을 의도된 프로그램 구성요소로 분해하는 것이다.

개요

컴퓨터 프로그램의 표현식은 변수, 데이터 유형, 함수, 클래스, 객체, 라이브러리, 패키지 및 기타 실체를 이름별로 참조한다. 이러한 맥락에서 이름 결정이란 필요 없이 고유하지 않은 이름들과 의도된 프로그램 실체의 연관성을 말한다. 이러한 식별자가 특정 상황에서 언급하는 것을 결정하는 알고리즘은 언어 정의의 일부분이다.

이러한 알고리즘의 복잡성은 언어의 정교함에 영향을 받는다. 예를 들어, 어셈블리 언어의 이름 결정에는 보통 간단한 테이블 검색 하나만 포함되지만, C++의 이름 확인에는 다음이 수반되므로 매우 복잡하다.

  • 식별자가 연관된 네임스페이스에 따라 다른 의미를 가질 수 있도록 하는 네임스페이스
  • 범위: 식별자가 서로 다른 범위 수준에서 다른 의미를 가질 수 있고 다양한 범위 재정의 및 숨기기 규칙을 포함하는 범위. 가장 기본적인 수준의 이름 해상도에서 일반적으로 가장 작은 범위 내에서 바인딩을 찾으려고 시도하여 예를 들어 로컬 변수가 글로벌 변수를 대체한다. 이를 섀도잉이라고 한다.
  • 특정 네임스페이스 또는 범위의 식별자를 현재 컨텍스트에서 볼 수 있는지 여부를 결정하는 가시성 규칙
  • 단일 네임스페이스 또는 스코프에서조차 식별자가 어떻게 사용되는지에 따라 다른 의미를 가질 수 있도록 하는 과부하
  • 다른 시각적 범위에서 식별자가 실제로 액세스 가능한지 여부를 결정하고 이름 확인 프로세스에 참여한다.

정적 대 동적

프로그래밍 언어에서 이름 확인은 컴파일 또는 런타임에 수행될 수 있다. 전자를 정적 이름 확인이라고 하고, 후자를 동적 이름 확인이라고 한다.

다소 일반적인 오해는 동적 타이핑이 동적 이름 확인을 내포한다는 것이다. 예를 들어 Erlang은 동적으로 입력되지만 정적 이름 해상도를 가지고 있다. 그러나 정적 타이핑은 정적 이름 확인을 의미한다.

정적 이름 분해능은 컴파일 시 범위에 포함되지 않는 변수의 사용을 포착하여 프로그래머 오류를 방지한다. 동적 범위 해상도를 가진 언어는 더 많은 유연성을 위해 이 안전성을 희생시킨다. 그들은 일반적으로 런타임에 동일한 범위에서 변수를 설정하고 얻을 수 있다.

예를 들어 Python 대화형 RET에서 다음을 수행하십시오.

>>> 번호를 매기다 = 99 >>> first_first = "problems" >>> 제2의 = "hound" >>> # 런타임에 어떤 변수를 사용할지 결정 >>> 인쇄하다(f"알았다. {번호를 매기다} {first_first} a에 지나지 않다 {제2의} 아니잖아.") 나는 99개의 문제를 가지고 있지만 사냥개는 그렇지 않다. 

그러나, 코드의 동적 이름 결정에 의존하는 것은 파이썬 커뮤니티에 의해 좌절된다.[1][2] 이 기능은 Python의 이후 버전에서도 제거될 수 있다.[3]

정적 이름 해상도를 사용하는 언어의 로는 C, C++, E, Erlang, Haskell, Java, Pascal, Scheme, Smalltalk 등이 있다. 동적 이름 해상도를 사용하는 언어의 예로는 일부 Lisp 방언, Perl, PHP, Python, REBOL, Tcl 등이 있다.

이름 마스킹

마스킹은 겹치는 어휘 범위에서 서로 다른 실체에 동일한 식별자를 사용할 때 발생한다. 변수 수준(이름 대신)에서는 이를 변수 그림자(variable shadowing)라고 한다. 두 조건이 충족될 때 식별자 I'(변수 X의 경우)이 식별자 I(변수 X의 경우)을 마스킹한다.

  1. 나는 나와 이름이 같다.
  2. I'는 I의 범위의 하위 집합인 범위에서 정의된다.

외부 변수 X는 내부 변수 X'에 의해 그림자로 표시된다고 한다.

예를 들어, 매개변수 "foo"는 다음과 같은 공통 패턴에서 로컬 변수 "foo"를 그림자로 표시한다.

사유의 인트로 foo;  // "foo" 이름이 외부 범위에 선언됨  공중의 공허하게 하다 setFoo(인트로 foo) {  // 이름 "foo"는 내부 범위에서 선언되며 함수 로컬이다.     이것,.foo = foo;  // "foo"는 "가장 내부" 범위에서 처음 발견(그리고 해결)되므로,                      // 속성 "foo"의 저장된 값을 성공적으로 덮어쓰려면                      // 수신 매개변수 "foo"의 새로운 값으로 구분                      // "this.foo"(개체 속성)와 "foo"(기능 파라미터) 사이.   }  공중의 인트로 getFoo() {     돌아오다 foo; } 

이름 마스킹은 일부 언어의 스코프(특히 C++)에서 과부하가 발생하지 않아 기능 과부하합병증을 유발할 수 있으므로 과부하된 모든 기능을 다시 닫거나 지정된 네임스페이스로 명시적으로 가져와야 한다.

이름 확인을 사소한 것으로 만들기 위한 알파 이름 변경

변수 이름 에 반영되지 않는 어휘 범위 지정으로 프로그래밍 언어에서, α-변환(또는 α-renaming)을 사용하여 어떤 변수 이름도 포함하는 범위에서 다른 이름을 마스킹하지 않도록 하는 대체물을 찾아 이름 확인을 쉽게 할 수 있다. 알파 이름 변경은 알파 이름 변경자만이 언어의 범위 지정 규칙을 이해하면 되기 때문에 정적 코드 분석을 더 쉽게 할 수 있다.

예를 들어, 이 코드에서:

계급 포인트 { 사유의:   곱절로 하다 x, y;  공중의:   포인트(곱절로 하다 x, 곱절로 하다 y) {  // 여기서 선언된 x 및 y는 권한 마스크     setX(x);     세티(y);   }    공허하게 하다 setX(곱절로 하다 뉴옥스) { x = 뉴옥스; }   공허하게 하다 세티(곱절로 하다 뉴리의) { y = 뉴리의; } } 

의 범위 내에서 생성자, 클래스 변수xy는 동일한 이름의 로컬 변수에 의해 음영 처리된다. 이것은 다음과 같이 알파 이름:

계급 포인트 { 사유의:   곱절로 하다 x, y;  공중의:   포인트(곱절로 하다 a, 곱절로 하다 b) {     setX(a);     세티(b);   }    공허하게 하다 setX(곱절로 하다 뉴옥스) { x = 뉴옥스; }   공허하게 하다 세티(곱절로 하다 뉴리의) { y = 뉴리의; } } 

새 버전에서는 마스킹이 없기 때문에 어떤 용도가 어떤 선언에 해당하는지 즉시 알 수 있다.

참고 항목

참조

  1. ^ "[Python-Ideas] str.format utility function". 9 May 2009. Retrieved 2011-01-23.
  2. ^ "8.6. Dictionary-based string formatting". diveintopython.org. Mark Pilgrim. Retrieved 2011-01-23.
  3. ^ "9. Classes - Python documentation". Retrieved 2019-07-24. It is important to realize that scopes are determined textually: the global scope of a function defined in a module is that module’s namespace, no matter from where or by what alias the function is called. On the other hand, the actual search for names is done dynamically, at run time — however, the language definition is evolving towards static name resolution, at “compile” time, so don’t rely on dynamic name resolution! (In fact, local variables are already determined statically.)