trang chủ / bài tập / vastypes

Vasya và Hệ thống kiểu

Đề bài

Mô tả

Ngôn ngữ lập trình giả định &K* có hệ thống kiểu rất mạnh. Bạn cần viết một trình phân tích nhỏ cho hệ thống này.

Ngôn ngữ chỉ có hai kiểu cơ bản: voiderrtype. Trên mỗi kiểu, ta có hai phép toán:

  • Phép con trỏ: thêm dấu * vào bên phải kiểu X tạo ra kiểu mới X*.
  • Phép giải tham chiếu: thêm dấu & vào bên trái kiểu X. Nếu X là một kiểu con trỏ thì kết quả là kiểu mà X trỏ tới; nếu giải tham chiếu void thì kết quả là errtype.

Quy tắc đặc biệt:

  • Phép con trỏ có độ ưu tiên cao hơn phép giải tham chiếu. Do đó biểu thức &T* luôn bằng T (khi T không phải errtype).
  • Với errtype, đẳng thức sau luôn đúng: errtype* = &errtype = errtype.
  • Sử dụng một định danh chưa từng được định nghĩa cũng cho kết quả errtype.

Có hai loại lệnh:

  • typedef A B — định nghĩa kiểu mới B tương đương với kiểu A tại thời điểm hiện tại (đưa A về dạng chuẩn void**...* hoặc errtype rồi gán cho B). A có thể chứa các dấu *&; B là một định danh đơn (không có * hay &, khác voiderrtype). Có thể typedef lại một tên đã định nghĩa — chỉ định nghĩa mới nhất là có hiệu lực, nhưng các kiểu khác đã được định nghĩa dựa trên giá trị cũ thì không thay đổi.
  • typeof A — in ra kiểu của A ở dạng void**...* (số dấu * có thể bằng 0) hoặc errtype.

Các lệnh được thực thi tuần tự. Ví dụ, sau hai lệnh typedef &void a rồi typedef a* b: bước đầu a trở thành errtype, do đó b= errtype* = errtype, không phải &void* = void.

Dữ liệu vào

  • Dòng đầu chứa số nguyên n — số lệnh.
  • n dòng tiếp theo, mỗi dòng chứa một lệnh dạng typedef A B hoặc typeof A.

Dữ liệu ra

Với mỗi lệnh typeof, in ra một dòng chứa kết quả.

Ràng buộc

  • 1n100
  • Mọi tên kiểu là chuỗi không rỗng gồm tối đa 20 chữ cái Latin thường.
  • Trong mỗi lần xuất hiện, số dấu * và số dấu & không vượt quá 10 mỗi loại; nhưng khi quy về dạng void**...* thì số * có thể lớn hơn 10.

Ví dụ

Input Output Giải thích
5
typedef void* ptv
typeof ptv
typedef &&ptv node
typeof node
typeof &ptv
void*
errtype
void
ptv = void*. &&ptv = &&(void*) = &void = errtype, nên node = errtype. &ptv = &(void*) = void.
2
typedef void errtypea
typeof errtypea
void errtypea là một định danh bình thường, không phải kiểu đặc biệt errtype. Sau lệnh đầu, errtypea = void.
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**
void
void**
errtype
void
errtype
errtype
errtype
Xem ghi chú dưới đây.

Lưu ý cho ví dụ thứ ba: sau hai lệnh typedef đầu, b= void*c= void**. Lệnh typedef &b b đổi b thành &void* = void (giá trị cũ của c giữ nguyên). Sau typedef &&b* c: c= &&void* = &void = errtype. Lệnh typedef &b* c đặt c= &void* = void. Tiếp đến typedef &void b đưa b thành errtype, kéo theo typedef b******* cc= errtype******* = errtype, và lệnh cuối cùng tương tự.

Bình luận

Không có bình luận tại thời điểm này.

gnatmake 12.2.0 a68g 3.1.2 nasm 2.16.1 as_x64 2.46 awk 1.3.4 gcc 16.1.0 csc 6.12.0.200 g++ 16.1.0 g++-themis 16.1.0 g++17 16.1.0 g++20 16.1.0 g++23 16.1.0 clang++ 22.1.6 dmd 2.112.0 dart 3.12.1 gforth 0.7.3 gfortran 12.2.0 go 1.26.3 groovyc 5.0.6 javac 25.0.3 node 26.2.0 kotlinc 2.3.21 sbcl 2.2.9 lua 5.4.8 nim 2.2.10 fpc 3.2.2 fpc-themis 3.2.2 perl 5.36.0 php 8.5.6 pike 8.0 pypy3 7.3.23 python3 3.14.5 racket 8.7 ruby 4.0.5 rustc 1.96.0 csc 5.3.0 ctoj-scratch 0.0.1 sed 4.9 tclsh 8.6 bun 1.3.14 deno 2.8.1 v 0.5.1 zig 0.16.0