2016-10-25 9 views
0

나는 여기에서 this 질문을 보았지만, 내가 특별히 염두에 두었던 것에는 대답하지 않는다. Go 또는 C++ 11 같은 언어가 Damas-Milner와 같은 추론 알고리즘을 사용하지 않는다면 정확히 무엇을합니까?C++ 11이나 Go 같은 언어로 타입 유추가 어떻게 구현됩니까?

5 + 3.4 

어떻게 컴파일러가 어떤 종류의를 해독 것이다 : 나는 당신이 뭔가를했다면 때문에 오른쪽에있는 종류를 고려하기로 간단하게 생각하지 않습니다?

if left is integer and right is float: 
    return float; 
if left is float and right is integer: 
    return float; 
etc... for every possible pattern 

단순한 용어로 설명 할 수 있다면 간단한 알고리즘이 있습니까? 필자는 컴파일러 생성이나 이론적 인 주제를 상세하게 연구하지는 않고 함수형 언어 나 복잡한 수학 표기법을 사용하지 않습니다.

+0

더 자세히는 다음과 같습니다. * "왼쪽이 정수이고 오른쪽이 부동이며 왼쪽으로 변환하여 두 개의 부동을 추가합니다"*. 표현식에서 각 2 진 연산자에 대한 변환이 필요에 따라 완료되며 결과는 표현식에서 가장 높은 순위 유형이됩니다. – user3386109

답변

4

나는 그것이 형태 auto var = some_expression;의 기본 형식 유추를 들어 오른쪽

의 종류를 고려하기로 간단하게 생각하지 않습니다, 그것은 정확하게 간단하다. 잘 형식화 된 모든 표현식은 정확히 하나의 유형을 가지며 해당 유형은 var 유형입니다. 표현식 유형에서 다른 유형으로의 암시 적 변환은 수행되지 않습니다 (명시 적 유형을 var에 지정한 경우).

당신이 뭔가가 있다면 :

5 + 3.4 

문제 "? 5 + 3.4의 유형은 무엇입니까" C++ 컴파일러는 형식 유추가 도입되기 전에도 항상이 질문에 대답해야했습니다.

그럼 다시 걸음을하고 C++ 컴파일러가 문을 some_type var = some_expression;을 typechecks 방법에 대해 살펴 보자

첫째는 some_expression의 유형을 결정합니다. 따라서 코드에서 Type exp_type = type_of(exp);과 같은 것을 상상할 수 있습니다. 이제 exp_typesome_type과 같거나 exp_type에서 some_type으로의 암시 적 변환이 있는지 확인합니다. 그렇다면 문은 형식이 잘 지정되어 var이 유형으로 some_type 인 것으로 환경에 도입됩니다. 그렇지 않으면 그렇지 않습니다. 우리는 형식 유추를 소개하고 auto var = some_expression; 같은 방정식의 변화를 쓸 때

지금 : 우리는 여전히 대신하여 다른 유형과 비교 또는 암시 적 변환을 적용, Type exp_type = type_of(exp);을, 우리는 대신에 단순히 var의 유형으로 exp_type 설정 .

이제 5 + 3.4으로 돌아가 보겠습니다. 유형은 무엇이며 컴파일러는 어떻게 결정합니까? C++에서 그 타입은 double입니다. 산술 표현식의 유형을 결정하는 규칙은 C++ 표준에 나열되어 있습니다 ("일반적인 산술 변환"을 찾으십시오). 그러나 기본적으로이 두 가지 유형 중 더 큰 범위의 값을 나타낼 수있는 것을 선택하십시오. 형식이 int보다 작 으면 두 피연산자를 모두 int으로 변환하고 두 피연산자를 선택한 형식으로 변환하십시오.

코드에서이 같은 일을 각 숫자 형식을 변환 순위를 할당하고 이것을 구현하는 것 :

Type type_of_binary_arithmetic_expression(Type lhs_type, Type rhs_type) { 
    int lhs_rank = conversion_rank(lhs_type); 
    int rhs_rank = conversion_rank(rhs_type); 
    if(lhs_rank < INT_RANK && rhs_rank < INT_RANK) return INT_TYPE; 
    else if(lhs_rank < rhs_rank) return rhs_type; 
    else return lhs_type; 
} 

은 아마도 이동에 대한 규칙은 다소 다르지만, 동일한 원칙이 적용됩니다.