CF87B.Vasya and Types
普及+/提高
通过率:0%
时间限制:1.00s
内存限制:256MB
AC君温馨提醒
该题目为【codeforces】题库的题目,您提交的代码将被提交至codeforces进行远程评测,并由ACGO抓取测评结果后进行展示。由于远程测评的测评机由其他平台提供,我们无法保证该服务的稳定性,若提交后无反应,请等待一段时间后再进行重试。
题目描述
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.
程序员瓦西娅正在学习一门新的编程语言 &K*。&K* 语言在语法上类似于 C 族语言,但功能更加强大,因此现实 C 类语言中的规则并不适用于它。为完全理解本题,请仔细阅读下方对 &K* 语言的描述,并严格遵循该描述,而非现实中类似编程语言的规则。
&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**...*的类型(含适当数量的星号,该数量可能为零),使其与A等价。换言之,若如上定义了类型ptptvoid,则typeof ptptvoid将返回void**。
对 void 类型执行解引用操作将导致错误,即产生一种特殊数据类型 errtype。对于 errtype,满足如下恒等式:
errtype∗=&errtype=errtype.
尝试使用一个此前未定义过的数据类型,同样会导致 errtype。
通过 typedef,我们可以对同一类型多次定义;其中仅最后一次定义有效。然而,所有此前已用该类型定义的其他类型均保持不变。
还需注意:解引用操作的优先级低于指针操作,即 &T* 恒等于 T。
注意:各运算符按顺序逐个执行。例如,若先后出现两条语句 typedef &void a 和 typedef a* b,则首先 a 被定义为 errtype,随后 b 被定义为 errtype* = errtype,而非 &void* = void(参见样例 2)。
瓦西娅尚未完全掌握这项强大技术,因此他请你协助解决此问题。请编写一个程序来分析这些运算符。
输入格式
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.
第一行包含一个整数 n(1≤n≤100)—— 表示操作符的数量。接下来的 n 行为操作符,每个操作符属于以下两种类型之一:
"typedef A B",或"typeof A"。
在第一种情况下,类型 B 不等于 void 和 errtype 类型,且不包含任何星号(*)和取地址符(&)。
所有数据类型名称均为非空字符串,由至多 20 个小写拉丁字母组成。在任意一个操作符中,单个类型所含的星号(*)和取地址符(&)的数量分别不超过 10;但若将某些类型归约为带多个星号的 void 类型,则其星号总数可能超过 10。
输出格式
For every typeof operator print on the single line the answer to that operator — the type that the given operator returned.
对于每个 typeof 运算符,在单独一行上输出该运算符的结果——即该运算符所返回的类型。
输入输出样例
输入#1
5 typedef void* ptv typeof ptv typedef &&ptv node typeof node typeof &ptv
输出#1
void* errtype void
输入#2
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
输出#2
void* void** void void** errtype void errtype errtype errtype
说明/提示
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.
我们来看第二个样例。
在前两个查询之后,typedef 使得类型 b 等价于 void*,而 c 等价于 void**。
接下来的 typedef 查询重新定义了 b —— 此时 b 变为 &b = &void* = void。此时,类型 c 并未发生变化。
随后,c 被定义为 &&b* = &&void* = &void = errtype。这不会影响 b 类型,因此下一个 typedef 将 c 定义为 &void* = void。
接着,b 再次被重新定义为 &void = errtype。
请注意,在下一个查询中,c 类型被恰好定义为 errtype****** = errtype,而非 &void****** = void******。最后一个 typedef 中也发生了同样的情况。
输入解题思路,AI测评打分。不知道怎么写?