해결한 사람
0
명
정답률
0.00
%
시간 제한
2000
ms
메모리 제한
245
MB
Programmer Vasya는 새로운 프로그래밍 언어 &K를 공부하고 있다. &K 언어의 문법은 C 계열 언어의 문법과 비슷하다. 하지만 이 언어는 더 강력하므로 실제 C- 계열 언어의 규칙은 여기에 적용되지 않는다. 문제를 완전히 이해하려면 아래의 언어 설명을 주의 깊게 읽고, 실제 프로그래밍 언어의 비슷한 규칙이 아니라 이 설명을 따라야 한다.
&K*에는 매우 강력한 포인터 체계가 있다. 기존 타입 X의 오른쪽에 별표를 추가하면 새로운 타입 X * 가 된다. 이를 포인터 정의 연산이라고 한다. 또한 그 반대의 역할을 하는 연산도 있다. 포인터인 임의의 타입 X에 앰퍼샌드를 추가하면 X가 가리키는 타입 &X가 된다. 이를 역참조 연산이라고 한다.
&K* 언어에는 기본 자료형이 void와 errtype뿐이다. 또한 이 언어에는 typedef와 typeof 연산자가 있다.
void 타입을 역참조하려고 하면 오류가 발생하여 특수 자료형 errtype이 된다. errtype에 대해서는 다음 등식이 성립한다. errtype* = &errtype = errtype. 이전에 정의되지 않은 자료형을 사용하려고 해도 errtype이 된다.
typedef를 사용하면 하나의 타입을 여러 번 정의할 수 있다. 모든 정의 중 마지막 정의만 유효하다. 하지만 이 타입을 사용하여 이전에 정의한 모든 타입은 변하지 않는다.
또한 역참조 연산의 우선순위는 포인터 연산보다 낮다. 다시 말해 &T * 는 항상 T와 같다.
연산자들은 하나씩 차례대로 실행된다는 점에 유의하라. 두 연산자 "typedef &void a"와 "typedef a* b"가 있다면, 먼저 a가 errtype가 되고, 그다음 b가 errtype* = errtype가 되며, &void* = void가 되는 것은 아니다(예제 2 참고).
Vasya는 아직 이 강력한 기술을 완전히 이해하지 못했기 때문에 여러분에게 도움을 요청했다. 이 연산자들을 분석하는 프로그램을 작성하라.
첫째 줄에 연산자의 개수를 나타내는 정수 n (1 ≤ n ≤ 100)이 주어진다. 이어서 연산자가 담긴 n개의 줄이 주어진다. 각 연산자는 "typedef A B" 또는 "typeof A"의 두 유형 중 하나이다. 전자의 경우 B 타입은 void 및 errtype 타입과 다르며, 별표와 앰퍼샌드도 포함하지 않는다.
모든 자료형 이름은 최대 20개의 소문자 라틴 문자로 이루어진 비어 있지 않은 문자열이다. 임의의 연산자에 등장하는 하나의 타입에서 별표와 앰퍼샌드의 개수는 각각 10을 초과하지 않는다. 하지만 어떤 타입을 여러 개의 별표가 붙은 void로 변환하면 별표의 개수가 10을 초과할 수 있다.
각 typeof 연산자에 대해 해당 연산자가 반환한 타입을 한 줄에 출력한다.
17
typedef void* b
typedef b* c
typeof b
typeof c
typedef &b b
typeof b
typeof c
typedef &&b* c
typeof c
typedef &b* c
typeof c
typedef &void b
typeof b
typedef b******* c
typeof c
typedef &&b* c
typeof c
void*
void**
errtype
void**
errtype
errtype
errtype
errtype
errtype
5
typedef void* ptv
typeof ptv
typedef &&ptv node
typeof node
typeof &ptv
void*
errtype
errtype
두 번째 예제를 살펴보자.
처음 두 typedef 질의가 실행된 후 b 타입은 void*와 동등하고, с는 void**와 동등하다.
다음 typedef 질의는 b를 다시 정의한다. 이제 이는 &b = &void* = void와 같다. 이때 с 타입은 변하지 않는다.
그 후 с 타입은 &&b* = &&void* = &void = errtype으로 정의된다. 이는 b 타입에 영향을 주지 않으므로, 다음 typedef는 c를 &void* = void로 정의한다.
그다음 b 타입은 다시 &void = errtype으로 재정의된다.
다음 질의에서 c 타입은 정확히 errtype******* = errtype로 정의되며, &void******* = void******로 정의되는 것이 아님에 유의하라. 마지막 typedef에서도 같은 일이 일어난다.