trang chủ / đề bài / 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: void và errtype. 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 * và &; B là một định danh đơn (không có * hay &, khác void và errtype). 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

  • 1≤n≤100
  • 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* và 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******* c ⇒ c= 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.47 awk 1.3.4 gcc 16.2.0 dotnet 10.0.402 g++ 16.2.0 g++-themis 16.2.0 g++17 16.2.0 g++20 16.2.0 g++23 16.2.0 clang++ 22.1.8 dmd 2.113.0 dart 3.13.6 gforth 0.7.3 gfortran 15.3.0 go 1.27.3 groovyc 5.1.3 javac 26.0.2.1 node 26.12.1 julia 1.13.2 kotlinc 2.4.21 lean 4.35.0 sbcl 2.2.9 lua 5.5.1 nim 2.2.12 fpc 3.2.2 fpc-themis 3.2.2 perl 5.42.3 php 8.5.12 pike 8.0 swipl 9.0.4 pypy3 7.3.23 python3 3.15.1 racket 8.7 ruby 4.0.8 rustc 1.99.1 csc 5.3.0 ctoj-scratch 0.0.1 sed 4.9 swiftc 6.4.1 tclsh 8.6 bun 1.4.4 deno 2.9.8 v 0.5.2 zig 0.17.0