2

일부 프로그래밍 언어 허용 매개 변수는 함수 호출에서 기본값을 가지거나 구조체의 특성에서 기본값을가집니다. 파이썬이나 자바 스크립트와 마찬가지로 함수 호출에서 일부 매개 변수를 생략하면 함수에서 기본 값이 대체됩니다 (struct가 속성에도 기본값을 가질 수 있음). 그렇다면 컴파일러는 실제로 이것을 어떻게 처리합니까? 특히 기호 테이블에? 기본 값을 가리키는 포인터에 대한 하나 이상의 추가 특성을 추가하는 것도 기본 값이 런타임에 스택에 푸시 된 것 같아요? 제가 맞는지 알려주세요. 감사.컴파일러가 기호 테이블의 기본값을 처리하는 방법

업데이트 : 프로그램 파라미터 b 다음 내가 파이썬에서 말하는 의미 여기에 기본 값이 기본값 0 있습니다.

def foo(a, b=0): 
    return a+b 
print foo(1) 
print foo(1, 1) 

우리가 얻을 01을 발생합니다. 컴파일러가 런타임이나 컴파일 타임에 어떻게 처리합니까?

답변

1

함수 호출의 인수 목록이 평가되면 코드 생성기는 목록을 기호 테이블에 저장된 함수 서명과 비교하여 누락 된 인수를 알 수 있습니다. 어떤 인수를 대체해야 하는지를 알게되면 인수 레지스터 (또는 스택 프레임)에 기본값을 던지는 것만 큼 문제가됩니다. OO 언어를 다루고 있으며 형식 매개 변수가 객체 인 경우 스택의 다음 단어에 0 (NULL)을 입력 할 수 있습니다. 매개 변수가 기본 제공 프리미티브이면 언어에서 지정하는 기본값을 그대로 사용합니다.

물론 컴파일러는 다양 할 수 있지만 단순한 것으로서 심볼 테이블에 기본값을 연결하는 것은 절대적으로 필요하지 않습니다. 먼저, 심볼 테이블이 모든 변수 선언을 기록한다는 것을 명확히 밝힙니다. 이러한 선언에 대한 정보 (예 : 클래스, 메서드, 유형, 라인, char 등)를 저장해야하지만, 몇 가지 유형 만있을 때 각 변수에 대한 기본값을 기록 할 필요가 없으므로 가능한 기본값.

일부 언어 (Java/C++)는 초기화되지 않은 객체 속성이있는 클래스의 기본값이 NULL임을 지정합니다. 이와 같이 구현할 때 코드 생성기가 클래스 생성자를 생성하면 해당 속성에 매핑 된 객체 메모리에 0을 배치하는 코드를 생성해야합니다 (모든 것이 포인터 기반이라고 가정). 생성자를 생성하고 클래스 속성 목록 (AST 노드)을 반복하면서 해당 속성에 대한 초기화 표현식이 없으면 기본값을 수행 할 메소드를 호출합니다.

private void genConstructor(int classId) { 

    //allocate new object 

    codeGen.write("li $a0, "+classId); 
    codeGen.write("jal Runtime.newObject"); 

    //call parent constructor 

    codeGen.write("move $a0, $v0"); 
    codeGen.write("jal ParentInit"); 

    //initialize the attributes this class has declared 

    for(Attributes a: getAttributes(classId)) { 

     //provide default value 
     if(a.getInitExpr() == null) 
      doDefault(a.getType(), a.getNum()); 
     else 
      doInit(a.getInitExpr(), a.getNum()); 
    } 
} 

// An 'Int' default value is 1, everything else is 0 (Objects included) 
// $t0 has the object address 
// attributes start at the 5th word of each object 
private void doDefault(String type, int attrNum) { 
    switch(type) { 
      case "Int": { 
       codeGen.write("sw $one, "+(5+attrNum)+"($t0)"); 
      } 
      default: { 
       codeGen.write("sw $zero, "+(5+attrNum)+"($t0)"); 
      } 
    } 
} 

업데이트 :

내가 컴파일러는 프로그래머 대신 "클래스"또는 "종류"를 "기본"으로 설정 한 기본 값을 처리하는 방법을 궁금해하고있다.

저는 C++ 생성자에서 기본 args와 비슷한 것을 말하고 있다고 가정합니다. 이 경우, Ira가 언급했듯이, 기호 테이블 레코드에서 필드를 만드는 것이 가장 간단한 방법입니다. 누락 된 인수에 대한 코드를 생성 할 때 테이블에서 기본값을 찾으십시오.

+0

다시 한 번 감사드립니다. 당신이 내 다른 질문에 답한 것을 기억합니다. 컴파일러가 "클래스"또는 "유형"대신 "기본값"대신 프로그래머가 설정 한 기본값을 처리하는 방법에 대해 궁금합니다. 감사. –

+0

@SimonGuo : 업데이트되었습니다. – blackcompe

3

어떻게 수행하든 관계없이 기본값을 특정 식별자와 연결해야합니다.

매개 변수 목록과 구조체 멤버는 작은 네임 스페이스를 형성하며 일반적으로 컴파일러는 네임 스페이스에 대한 기호 테이블을 작성하고 네임 스페이스와 관련된 더 큰 기호 테이블을 작성하여이를 추적합니다.

컴파일러는 이미 기호 (예 : 모든 유형 정보)와 다른 정보를 연결하는 작은 네임 스페이스에 기호 테이블 항목을 가지고 있기 때문에 매우 자연스러운 장소입니다.

초기 값을 정확히 기록해야하는지에 대한 질문이 있습니다. 쉬운 일은 초기/기본값을 나타내는 AST에 대한 포인터를 기록하는 것입니다. 이와 함께 표현을 평가해야하는 상황 (예 : '환경')을 기록해야합니다. 이 문맥은 구조체/매개 변수가 정의 된 컨텍스트와 일반적으로 동일하므로 암시 적으로 남겨질 수 있으며 그 정보는 모든 것을 함께 연결하는 큰 기호 테이블에 저장됩니다.

관련 문제