4065: 瓦夏和类型

内存限制:256 MB 时间限制:2 S 标准输入输出
题目类型:传统 评测方式:文本比较 上传者:
提交:2 通过:2

题目描述

B. 瓦夏和类型
每次测试的时限

2秒

每次测试的内存限制

256兆字节

输入

标准输入

输出

标准输出


程序员Vasya正在研究一种新的编程语言&K*。&K*语言在语法上类似于C家族的语言。然而,它更强大,这就是为什么实际的类c语言的规则不适用于它的原因。要完全理解这个语句,请仔细阅读下面的语言描述,并遵循它,而不是实际编程语言中的类似规则。
在&K*上有一个非常强大的指针系统,您可以在现有类型X的右侧添加一个星号,这将导致新的类型X*。这被称为指针定义操作。此外,还有一种相反的操作——对任何类型的X(指针),你可以添加一个&号——这将导致类型&X,指向X,这被称为解引用操作。
&K*语言只有两种基本数据类型:void和errtype。此外,该语言还有操作符typedef和typeof。
操作符“typedef A B”定义了一个新的数据类型B,它相当于A。A可以有星号和&号,而B不能有它们。例如,操作符typedef void** ptptvoid将创建一个新的类型ptptvoid,可以用作void**。
操作符"typeof A"返回类型为A的void,即返回类型为void**…*,相当于它与必要的星号数量(数字可以是零)。也就是说,如上所示,定义了ptptvoid类型后,typeof ptptvoid操作符将返回void**。
试图取消对void类型的引用将导致错误:指向一个特殊的数据类型errtype。对于errtype,以下公式成立:errtype*=&errtype=errtype。尝试使用之前未定义的数据类型也会导致错误类型。
使用typedef,我们可以多次定义一个类型。所有的定义中只有最后一个是有效的。但是,之前使用该类型定义的所有类型都不会更改。
我们还要注意到,解引用操作的优先级比指针操作低,换句话说,&T*总是等于T。
注意,操作符是一个接一个连续执行的。如果我们有两个操作符“typedef &void a”和“typedef a* b”,那么首先a变成errtype,然后b变成errtype* = errtype,而不是&void* = void(见示例2)。
瓦斯亚还没有完全理解这种强大的技术,所以他才让你帮他。写一个程序来分析这些运算符。
输入
第一行为整数n(1≤n≤100)−操作符个数。然后在n行后面加上运算符。每个操作符都是两种类型之一:“typedef A B”或“typeof A”。在第一种情况下,B类型不同于void和errtype类型,此外,没有任何星号和&号。
所有数据类型名称都是不超过20个小写拉丁字母的非空行。在任何运算符中,一种类型中星号和和号的数量都不超过10个,但是如果我们用几个星号使某些类型无效,它们的数量可能超过10个。
输出
对于每个typeof操作符,在单行上打印该操作符的答案-给定操作符返回的类型。
例子
输入

time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Programmer Vasya is studying a new programming language &K*. The &K* language resembles the languages of the C family in its syntax. However, it is more powerful, which is why the rules of the actual C-like languages are unapplicable to it. To fully understand the statement, please read the language's description below carefully and follow it and not the similar rules in real programming languages.
There is a very powerful system of pointers on &K* − you can add an asterisk to the right of the existing type X − that will result in new type X*. That is called pointer-definition operation. Also, there is the operation that does the opposite − to any type of X, which is a pointer, you can add an ampersand − that will result in a type &X, to which refers X. That is called a dereference operation.
The &K* language has only two basic data types − void and errtype. Also, the language has operators typedef and typeof.

  • The operator "typedef A B" defines a new data type B, which is equivalent to A. A can have asterisks and ampersands, and B cannot have them. For example, the operator typedef void** ptptvoid will create a new type ptptvoid, that can be used as void**.
  • The operator "typeof A" returns type of A, brought to void, that is, returns the type void**...*, equivalent to it with the necessary number of asterisks (the number can possibly be zero). That is, having defined the ptptvoid type, as shown above, the typeof ptptvoid operator will return void**.
An attempt of dereferencing of the void type will lead to an error: to a special data type errtype. For errtype the following equation holds true: errtype*=&errtype=errtype. An attempt to use the data type that hasn't been defined before that will also lead to the errtype.
Using typedef, we can define one type several times. Of all the definitions only the last one is valid. However, all the types that have been defined earlier using this type do not change.
Let us also note that the dereference operation has the lower priority that the pointer operation, in other words &T* is always equal to T.
Note, that the operators are executed consecutively one by one. If we have two operators "typedef &void a" and "typedef a* b", then at first a becomes errtype, and after that b becomes errtype* = errtype, but not &void* = void (see sample 2).
Vasya does not yet fully understand this powerful technology, that's why he asked you to help him. Write a program that analyzes these operators.

Input
The first line contains an integer n (1≤n≤100) − the number of operators. Then follow n lines with operators. Each operator is of one of two types: either "typedef A B", or "typeof A". In the first case the B type differs from void and errtype types, and besides, doesn't have any asterisks and ampersands.
All the data type names are non-empty lines of no more than 20 lowercase Latin letters. The number of asterisks and ampersands separately in one type in any operator does not exceed 10, however if we bring some types to void with several asterisks, their number may exceed 10.

Output
For every typeof operator print on the single line the answer to that operator − the type that the given operator returned.
Examples
Input
5
typedef void* ptv
typeof ptv
typedef &&ptv node
typeof node
typeof &ptv
Output
void*
errtype
void
Input
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
Output
void*
void**
void
void**
errtype
void
errtype
errtype
errtype
Note
Let's look at the second sample.
After the first two queries typedef the b type is equivalent to void*, and c − to void**.
The next query typedef redefines b − it is now equal to &b = &void* = void. At that, the c type doesn't change.
After that the c type is defined as &&b* = &&void* = &void = errtype. It doesn't influence the b type, that's why the next typedef defines c as &void* = void.
Then the b type is again redefined as &void = errtype.
Please note that the c type in the next query is defined exactly as errtype******* = errtype, and not &void******* = void******. The same happens in the last typedef.

输入样例 复制


输出样例 复制