> For the complete documentation index, see [llms.txt](https://overleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://overleaf-pro.ayaka.space/latex/vi/bai-viet-chuyen-sau/53-what-is-a-tex-token.md).

# Một "TeX token" là gì?

## Động lực cho một loạt bài về các token TeX và các khái niệm liên quan

Bài viết này thảo luận về động lực và phương pháp được sử dụng để tạo ra một loạt bài về các token TeX và các khái niệm liên quan [Một loạt bài viết mới: Các token TeX và các khái niệm liên quan—Nhưng tại sao (và như thế nào)?](https://www.overleaf.com/blog/521-a-new-series-of-articles-tex-tokens-and-related-concepts-but-why-and-how) Như đã lưu ý trong bài viết đó, xuyên suốt loạt bài này chúng tôi dựa các trao đổi và giải thích của mình trên những hiểu biết thu được qua một bản dựng tùy chỉnh của chương trình TeX nguyên bản của Knuth—sử dụng nó để tạo ra một loạt bài nhằm cung cấp các mô tả đơn giản và những giải thích dễ theo dõi về các khái niệm TeX then chốt.

## Giới thiệu: mục tiêu của chúng ta là gì?

Trong bài viết này, chúng ta sẽ tìm hiểu chính xác token TeX là gì bằng cách lần theo hành trình xử lý từ các ký tự trong tệp đầu vào đến việc TeX thực sự tạo ra các token TeX. Trên thực tế, điều này khá phức tạp nên chúng tôi đã giản lược quá trình xuống các yếu tố cốt lõi, cố gắng làm cho nó dễ theo dõi và dễ hiểu trong khi vẫn giữ được độ chính xác kỹ thuật.

Chúng ta bắt đầu bằng cách giới thiệu một số khái niệm nội bộ quan trọng của TeX: *các nguyên thủy*, *mã lệnh* và *bộ biến đổi lệnh*. Từ đó, chúng ta dùng một ví dụ macro rất đơn giản để xem chính xác cách TeX xử lý lệnh `\def` và token kết quả mà TeX tạo ra để biểu diễn lệnh đó.

Chúng ta kết thúc bằng một cái nhìn ngắn về cách TeX tạo token để biểu diễn các ký tự và cách `\catcode` của một ký tự quả thật được gắn vĩnh viễn vào một token ký tự—điều thường được nhắc đến trong các sách về TeX nhưng ở đây chúng ta sẽ thấy chính xác điều đó được thực hiện như thế nào.

Đồ họa sau đây cho thấy hành trình mà chúng ta sẽ tóm lược—từ văn bản đầu vào đến các token TeX:

![Hành trình từ đầu vào TeX đến token TeX.](/files/a60f0cc5ba5a537f83fcd3878c391e83af61077e)

## Nhưng trước hết: các lệnh nguyên thủy và mã lệnh

Mọi bộ máy TeX (Knuthian TeX, pdfTeX, XeTeX, LuaTeX) đều hiểu một số lệnh tích hợp sẵn: cái gọi là *các nguyên thủy*—những lệnh xây dựng nền tảng cơ bản làm nên khả năng lập trình của TeX. Chúng được gọi là “nguyên thủy” vì, khác với các macro do người dùng định nghĩa, chúng không được cấu tạo từ các lệnh khác và không thể được giản lược thêm thành các chỉ thị đơn giản hơn. Với TeX của Knuth có khoảng 320 primitive—mặc dù cần lưu ý rằng các bộ máy TeX khác như pdfTeX, XeTeX và LuaTeX đều đã bổ sung các lệnh mới vào chương trình gốc của Knuth và sẽ chứa những primitive không có trong phần mềm TeX của Knuth.

Bên trong, TeX gán một *mã lệnh* mã số

Các nhóm lệnh có chức năng liên quan sẽ dùng chung cùng một mã lệnh. Ví dụ, `\def`, `\gdef`, `\edef` và `\xdef` các primitive

Bản thân một mã lệnh (chẳng hạn 97) không thể cho bạn biết lệnh tạo macro nào đang được xét; vì vậy, như bạn có thể đoán, mỗi lệnh TeX được gán thêm một mảnh thông tin gọi là *bộ sửa đổi lệnh* (xem các ví dụ bên dưới).

### Bộ biến đổi lệnh: hai loại

Các bộ biến đổi lệnh được chia thành hai nhóm mà chúng ta sẽ gọi là “Loại 1” và “Loại 2”—TeX không dùng thuật ngữ này, chỉ là ở đây ta thấy tiện khi gọi như vậy:

* **Loại 1**: Các giá trị số nguyên đơn giản mà TeX, nếu cần, có thể dùng để phân biệt giữa các lệnh dùng chung cùng một mã lệnh.
* **Loại 2**: Một giá trị số nguyên là một vị trí số trong bộ nhớ của TeX, cho TeX biết nó cần đi đâu để tra cứu thông tin cho lệnh đó. Ví dụ, điều này áp dụng cho các lệnh do người dùng định nghĩa (macro), trong đó bộ biến đổi lệnh cho TeX biết định nghĩa macro được lưu ở đâu trong bộ nhớ.

#### Các bộ biến đổi lệnh Loại 1 (một ví dụ)

Như đã lưu ý, trong TeX của Knuth, bốn lệnh nguyên thủy để định nghĩa macro: `\def`, `\gdef`, `\edef`, `\xdef` đều có chung mã lệnh 97: chúng được phân biệt thông qua các bộ biến đổi lệnh của chúng, được liệt kê trong bảng sau:

| Lệnh    | <p>Mã<br>lệnh</p> | <p>Bộ biến<br>đổi lệnh</p> |
| ------- | ----------------- | -------------------------- |
| `\def`  | 97                | 0                          |
| `\gdef` | 97                | 1                          |
| `\edef` | 97                | 2                          |
| `\xdef` | 97                | 3                          |

Lấy ví dụ thứ hai, Knuth đã quyết định triển khai các lệnh `\openout`, `\write`, `\closeout`, `\special`, `\immediate` và `\setlanguage` như các “phần mở rộng” của TeX, chỉ nhằm cho thấy bạn có thể thêm các primitive mới vào TeX như thế nào. Trong trường hợp này, những lệnh đó thực ra không thật sự chia sẻ “chức năng tương tự”, ngoại trừ việc Knuth quyết định nhóm chúng lại với nhau để giải thích cách mở rộng TeX. Sáu lệnh đó được phân loại là “phần mở rộng” và được nhóm cùng với giá trị mã lệnh 59, nhưng mỗi lệnh đều có một bộ biến đổi lệnh thích hợp để phân biệt nó với các lệnh còn lại:

| Lệnh           | <p>Mã<br>lệnh</p> | <p>Bộ biến<br>đổi lệnh</p> |
| -------------- | ----------------- | -------------------------- |
| `\openout`     | 59                | 0                          |
| `\write`       | 59                | 1                          |
| `\closeout`    | 59                | 2                          |
| `\special`     | 59                | 3                          |
| `\immediate`   | 59                | 4                          |
| `\setlanguage` | 59                | 5                          |

#### Bộ biến đổi lệnh Loại 2 (giải thích ngắn)

Mặc dù tất cả các bộ biến đổi lệnh đều là số nguyên, các bộ biến đổi Loại 2 cần được giải thích thêm một chút. Trong TeX, các bộ biến đổi lệnh này được gọi là “con trỏ” vì chúng trỏ tới một vị trí trong bộ nhớ nơi TeX có thể tìm thêm thông tin cho lệnh đó. Điều này nghe có vẻ hơi mơ hồ nhưng cách TeX dùng các con trỏ này để tra cứu thông tin thì rất đa dạng và một giải thích đầy đủ hơn sẽ làm lệch khỏi mục tiêu cốt lõi của bài viết này. Một ví dụ có thể giúp ích: macro. Khi một lệnh macro được định nghĩa, TeX sẽ cần lưu văn bản thay thế ở đâu đó trong bộ nhớ. Như chúng ta sẽ thấy bên dưới, các macro do người dùng định nghĩa có mã lệnh từ 111 đến 114 với một bộ biến đổi lệnh là con trỏ vào bộ nhớ cho TeX biết văn bản thay thế của nó (định nghĩa macro) được lưu ở đâu.

### Mã lệnh: có thể mở rộng và không thể mở rộng

Trong mã nguồn TeX của Knuth, các mã lệnh dao động từ 0 đến 120—lưu ý rằng một số mã trong phạm vi đó chỉ dành cho mục đích sử dụng nội bộ chuyên biệt và không được gán cho những lệnh mà người dùng có thể truy cập. Cần lưu ý rằng các bộ máy TeX khác như pdfTeX, XeTeX và LuaTeX đều đã bổ sung các lệnh mới vào bộ lệnh gốc của Knuth và sẽ chứa nhiều lệnh nguyên thủy hơn, cùng các mã lệnh tương ứng; tuy nhiên, các nguyên tắc trình bày ở đây là cốt lõi cho mọi bộ máy dựa trên TeX phát sinh từ mã nguồn của Knuth.

Tập hợp các mã lệnh được chia thành hai nhóm chính:

* *các lệnh không thể mở rộng*: có mã lệnh nhỏ hơn hoặc bằng 100;
* *các lệnh có thể mở rộng*: có mã lệnh lớn hơn 100, tối đa là 120. Phạm vi từ 101 đến 120 bao gồm các macro do người dùng định nghĩa cùng các lệnh như `\csname`, `\expandafter` và `\the`.

Các lệnh không thể mở rộng thường thực hiện việc gán một giá trị cho một tham số nội bộ hoặc trực tiếp tạo ra nội dung có thể được dàn trang. Các lệnh có thể mở rộng thường “chèn” một luồng token vào hoạt động xử lý hiện tại của TeX hoặc sửa đổi thứ tự xử lý token.

Như đã nói ở trên, tất cả các macro (lệnh do người dùng định nghĩa) đều được gán mã lệnh từ 111 đến 114: các giá trị khác nhau phản ánh việc macro được định nghĩa là `\long`, `\outer`, cả hai hoặc không cái nào. Đây là một ví dụ:

| Loại macro             | Ví dụ                          | Chú thích             |
| ---------------------- | ------------------------------ | --------------------- |
| Không dài, không outer | `\def\ohyeah{....}`            | `\ohyeah` mã lệnh=111 |
| Dài, không outer       | `\long\def\ohyeah{....}`       | `\ohyeah` mã lệnh=112 |
| Không dài, outer       | `\outer\def\ohyeah{....}`      | `\ohyeah` mã lệnh=113 |
| Dài, outer             | `\long\outer\def\ohyeah{....}` | `\ohyeah` mã lệnh=114 |

Nhắc lại về các bộ biến đổi lệnh: khi một macro được định nghĩa, TeX sẽ lưu định nghĩa của macro ở một vị trí nào đó trong bộ nhớ: vị trí đó (một con trỏ) sẽ trở thành bộ biến đổi lệnh cho lệnh macro, và nó sẽ được lưu cùng một mã lệnh từ 111 đến 114 tùy theo cách nó được định nghĩa. Tên thực tế được gán cho một macro do người dùng định nghĩa không thật sự quan trọng: sau khi xử lý đầu vào, tất cả chúng sẽ được gán một mã lệnh dao động từ 111–114 và, cuối cùng, mọi lệnh mà TeX đọc từ đầu vào của bạn, dù là primitive hay macro do người dùng định nghĩa, rồi cũng được chuyển thành một biểu diễn số gọi là một *token*.

## Hành trình từ văn bản đầu vào đến các token TeX

Trong phần này, chúng ta sẽ dùng một ví dụ macro rất đơn giản để xem chính xác cách TeX xử lý lệnh `\def` để tạo ra một token biểu diễn `\def` lệnh. Hoạt động xử lý chi tiết của TeX có thể cực kỳ phức tạp nên chúng ta sẽ không dùng tham số macro hay dấu phân tách vì như vậy sẽ làm tăng độ phức tạp và làm lệch khỏi hành trình của chúng ta.

Giả sử tệp đầu vào TeX của bạn chứa dòng sau:

```latex
\def\ohyeah{Overleaf is cool!}
```

Khi TeX bắt đầu xử lý dòng đầu vào này, nó kiểm tra `\catcode` của từng ký tự và thấy ký tự đầu tiên là `\` (ký tự đầu tiên của `\def`). Nó phát hiện (tra cứu trong một bảng nội bộ) rằng `\` có `\catcode` 0, nghĩa là nó mở đầu cho một *chuỗi điều khiển*. Dĩ nhiên, bạn có thể định nghĩa lại bất kỳ ký tự nào để có `\catcode` 0 nhưng ở đây chúng ta sẽ giả sử đang dùng các định nghĩa quy ước của plain TeX hoặc LaTeX.

Nói chính xác thì thuật ngữ *chuỗi điều khiển* có hai tiểu loại: *từ điều khiển* và *ký hiệu điều khiển*:

* *từ điều khiển*: một chuỗi ký tự có `\catcode` chữ cái (11);
* *ký hiệu điều khiển*: một ký tự đơn có `\catcode` là *không* chữ cái (11).

Tại thời điểm này, `\` ký tự đã hoàn thành nhiệm vụ của nó và giờ không còn gì nữa. Khi phát hiện một ký tự thoát, phản ứng của TeX là bắt đầu đọc tất cả các ký tự tiếp theo trong đầu vào với mục đích phát hiện một từ điều khiển hoặc một ký hiệu điều khiển.

Sau `\`, TeX ngay lập tức phát hiện `d`: một ký tự có `\catcode` là 11, điều đó báo cho TeX biết rằng nó đã tìm thấy chữ cái đầu tiên của một *từ điều khiển*. Nó tiếp tục quét các ký tự tiếp theo cho đến khi cuối cùng phát hiện một ký tự mà *không* đã `\catcode` chữ cái (11). Tất cả các ký tự tiếp theo (sau `\`ban đầu) với `\catcode` 11 (chữ cái) được coi là tạo thành tên của một từ điều khiển: tức là tên của một lệnh—có thể là macro hoặc một primitive nhưng TeX, lúc này, vẫn chưa biết đó là loại lệnh nào. Ở thời điểm này, nó chỉ đơn thuần là một chuỗi ký tự.

Vì vậy, trong ví dụ của chúng ta, TeX vui vẻ quét tiếp, kiểm tra từng ký tự, cho đến khi nó tới `\` của `\ohyeah` ban đầu cũng có `\catcode` 0. TeX nhận ra rằng nó đã quét quá xa và lịch sự trả lại `\` đó vào luồng văn bản để nó trở thành ký tự tiếp theo được nhìn thấy trong quá trình quét tiếp theo của văn bản. Tại thời điểm này, TeX đã xác định được một chuỗi (`def`) mà nó biết tạo thành văn bản của một từ điều khiển gồm ba ký tự, mỗi ký tự có `\catcode` 11 (`d`, `e` và `f`). Điều TeX cần làm lúc này là tìm ra `def` nghĩa là gì: nó phải làm gì? Như bạn có thể đoán, TeX cần tìm mã lệnh và mã định danh lệnh cho `def` để nó có thể xác định phải làm gì với lệnh này.

## Đánh một mớ bùi nhùi

Sau khi phát hiện một từ điều khiển (`def`), việc đầu tiên TeX làm là “chuyển đổi” chuỗi ký tự (`def` trong ví dụ của chúng ta) thành một số nguyên bằng cách sử dụng cái gọi là hàm băm. Chúng ta không cần quá bận tâm đến chi tiết; chỉ cần một phác thảo là đủ. Về bản chất, TeX xem xét từng ký tự trong từ điều khiển vừa phát hiện và dùng giá trị mã ASCII (hoặc giá trị Unicode đối với XeTeX/LuaTeX) của từng ký tự để tính ra một con số gọi là giá trị băm: đó chỉ là một số nguyên đơn giản.

Trong quá trình tính băm này, TeX cũng sẽ kiểm tra xem chuỗi ký tự trong từ điều khiển vừa được phát hiện đã được nó biết hay chưa. Văn bản có thể đọc được của tất cả các lệnh, dù là primitive hay macro do người dùng định nghĩa, đều được lưu trong một vùng lưu trữ nội bộ gọi là *vùng chuỗi*. TeX phải làm như vậy vì nó có thể cần xuất ra tên có thể đọc được của một lệnh—ví dụ khi TeX cần báo lỗi và nêu tên lệnh gây lỗi. Chẳng hạn, macro của chúng ta `\def\ohyeah{Overleaf is cool!}` đang định nghĩa một lệnh mới gọi là `\ohyeah` và TeX sẽ (ở giai đoạn sau) không chỉ cần tính giá trị băm cho `ohyeah` (*không có* của nó (ký tự đầu `\` mà còn lưu luôn dạng chuỗi văn bản (dễ đọc với con người) phòng khi cần dùng nó cho việc báo lỗi (hoặc các tác vụ khác).

Nếu bạn muốn biết chi tiết hơn về các quá trình xử lý chuỗi của TeX, tôi đã viết về điều này trên [trang blog cá nhân của tôi](http://www.readytext.co.uk/?p=3590).

Kết quả cuối cùng là chuỗi ký tự biểu diễn lệnh `def` được biến thành giá trị số 1218 (đó là giá trị thực sự do TeX tính ra). Lúc này các ký tự riêng lẻ `d`, `e` và `f` không còn là một phần của câu chuyện chính nữa—chúng đã được đọc từ đầu vào và đã hoàn thành nhiệm vụ của mình: từ đây trở đi mọi thứ đều xoay quanh các số nguyên và *token*—chúng ta sẽ sớm thấy token thực sự là gì! Bên trong, TeX gọi những số giá trị băm này là *chuỗi điều khiển hiện tại* nhưng trong mã nguồn, thuật ngữ đó được rút ngắn thành một biến tên là `curcs`. Mã nguồn của TeX đầy những tên biến rất ngắn, thường khá bí hiểm.

Nhưng TeX *thực sự làm gì* với giá trị số nguyên 1218 vừa được tạo ra này? Làm sao TeX biết rằng chuỗi ban đầu `def`, nay được biểu diễn bởi số nguyên 1218, thực ra là chỉ dẫn để định nghĩa một macro? Câu trả lời là TeX có một kiểu “tủ hồ sơ” nội bộ nơi nó lưu ý nghĩa và giá trị hiện tại của mọi lệnh mà nó hiện biết—dù lệnh đó là macro do người dùng định nghĩa hay một primitive tích hợp sẵn. Lý do TeX phải kỳ công chuyển `def` thành giá trị băm 1218 (nay được lưu trong biến tên là `curcs`) là để dùng nó cho việc tra cứu *và* của `def`. Dĩ nhiên, TeX sẽ lặp lại thao tác tính băm này cho mọi từ điều khiển mà nó phát hiện trong đầu vào—tất nhiên, các từ điều khiển khác nhau sẽ cho ra các giá trị số nguyên khác nhau từ hàm băm: đó chính là toàn bộ ý tưởng.

Tủ hồ sơ nội bộ của TeX được gọi là *bảng tương đương* và sẽ là chủ đề của phần tiếp theo.

### Tra cứu bảng tương đương

Để ôn lại, hãy xem chúng ta đã học được gì cho đến đây:

* `\` mở đầu cho một chuỗi điều khiển (hoặc một *ký hiệu điều khiển* hoặc một *từ điều khiển*).
* Nếu ký tự đầu tiên sau `\` có `\catcode` 11 (chữ cái) thì đó là bắt đầu của một *từ điều khiển*.
* Đối với *các từ điều khiển* TeX quét để kiểm tra tất cả các ký tự đầu vào tiếp theo có `\catcode` 11 và sẽ ngừng quét ngay khi nó gặp ký tự đầu tiên không *không* có một `\catcode` của 11.
* Chuỗi các ký tự đầu vào (theo sau `\`) có `\catcode` 11 được coi là một *từ điều khiển* mà người dùng đã gõ: một lệnh yêu cầu TeX “làm điều gì đó”.
* Để bắt đầu quá trình “làm điều gì đó”, TeX chuyển chuỗi ký tự trong từ điều khiển thành một số nguyên. Nó làm điều này bằng cái gọi là hàm băm, vốn cho ra một số nguyên.
* Số nguyên (giá trị băm đã tính) được gọi là *chuỗi điều khiển hiện tại*, nhưng TeX đặt cho nó tên ngắn hơn là `curcs`.
* Trong ví dụ của chúng ta, từ điều khiển `def` được chuyển thành giá trị 1218—giá trị này được lưu trong một biến tên là `curcs`: tức là, `curcs=1218`.

TeX giờ cần tìm hiểu xem *chuỗi điều khiển hiện tại* vừa được phát hiện thực sự có nghĩa là gì—TeX làm gì với nó?

#### Một lưu ý về việc gom nhóm: nhu cầu lưu và khôi phục thông tin

Ở đây, chúng ta sẽ rẽ ngang một chút để nhắc lại rằng TeX có khả năng lưu và khôi phục thông tin: tức là nó có một dạng “bộ nhớ” tích hợp.

Bất kỳ ai đã viết dù chỉ một macro đơn giản nhất cũng nên biết cơ chế gom nhóm của TeX—ví dụ, dùng `\def` để tạo macro trong một nhóm. Trừ khi bạn áp dụng tiền tố `\global` cho các macro được `\def`tạo bên trong một nhóm, giá trị hoặc ý nghĩa của macro đó chỉ tồn tại trong nhóm đó (và các nhóm con bên dưới nó): định nghĩa của nó sẽ bị mất khi nhóm kết thúc. Ví dụ, nếu bạn định nghĩa một macro đơn giản bên trong một nhóm, như sau:

```latex
{\def\foo{Hello}}
```

và cố gắng dùng `\foo` ở ngoài nhóm

```latex
{\def\foo{Hello}}% \foo được định nghĩa trong một nhóm (lưu ý: không dùng \global)
\foo %<--- không còn được định nghĩa nữa, giờ là chưa định nghĩa
```

thì ta sẽ gặp lỗi quen thuộc: `Undefined control sequence`. `\foo` chỉ có nghĩa bên trong nhóm (và các nhóm con của nó) nơi nó được định nghĩa. Hơn nữa, khi bạn định nghĩa lại một macro bên trong một nhóm, giá trị mới có thể bị mất khi nhóm kết thúc và ý nghĩa trước đó (tồn tại bên ngoài nhóm) sẽ được khôi phục.

```latex
\def\foo{Goodbye}
\foo\par% Xuất ra Goodbye
{\def\foo{Hello}% Được định nghĩa lại bên trong một nhóm:
{Trong nhóm mức 2: \foo\par}}% Được dùng trong nhóm mức 2: \foo xuất ra Hello
Bên ngoài nhóm, giá trị cũ được khôi phục: \foo\par% Xuất ra Goodbye
```

Mục đích của các ví dụ đơn giản này là để chỉ ra rằng TeX có một dạng “cơ chế lưu trữ” hay “bộ nhớ” lưu/khôi phục “ý nghĩa” của các lệnh—và dĩ nhiên, nó thực sự có. Chúng ta đã gợi ý điều này ở phần trước: “cơ chế lưu trữ” hay “tủ hồ sơ” đó là một bảng nội bộ lớn gọi là *bảng tương đương*. Chính ở đó TeX lưu ý nghĩa hoặc giá trị hiện tại của tất cả các lệnh mà nó biết đến—các primitive tích hợp và các macro do người dùng định nghĩa.

### Bảng tương đương: bằng phép so sánh tương tự

Để giải thích bảng tương đương, chúng ta sẽ tiếp cận bằng phép so sánh tương tự. Chúng ta sẽ tiếp tục dùng khái niệm một tủ hồ sơ với hàng nghìn ngăn kéo nhỏ, mỗi ngăn được gắn một số nguyên duy nhất. Ở giai đoạn xử lý này TeX về thực chất nói:

“Được rồi, tôi có giá trị số nguyên 1218 vừa tính và lưu trong một biến tên là `curcs`. Giờ tôi cần tìm xem nó có nghĩa gì: để làm điều đó tôi sẽ đi xem ngăn số 1218 trong tủ hồ sơ của tôi và đọc xem trong đó ghi gì.”

TeX dùng 1218 để xác định ngăn kéo đúng và ở đó nó tìm thấy một ghi chú nhỏ chứa ba mẩu thông tin mà tên của chúng là những tên được dùng trong mã nguồn của TeX:

* **`eq_level:`** mức gom nhóm tại đó mục này được định nghĩa (mức 1 = được định nghĩa toàn cục). Chúng ta đã thấy tác động của việc gom nhóm ở trên: chính ở bảng tương đương là nơi thông tin về mức gom nhóm đó được lưu;
* **`eq_type:`** mã lệnh của mục này;
* **`equiv:`** “giá trị” hiện tại của mục này—nó có thể là một số nguyên đơn giản như bộ biến đổi lệnh đã nói ở trên, hoặc một con trỏ tới một vùng trong bộ nhớ; ví dụ, vị trí bộ nhớ cho tập hợp các token biểu diễn một định nghĩa macro.

Vì vậy, giá trị băm 1218 của chúng ta (được lưu trong biến `curcs`) trên thực tế đã được dùng làm *khóa* để truy cập một ngăn kéo chứa ý nghĩa và giá trị hiện tại của lệnh mà ban đầu chúng ta gõ vào dưới dạng chuỗi chữ `\def`.

Trong mã nguồn của chương trình TeX, trường `eq_type` cho bất kỳ lệnh nào được lưu bằng một biến tên là `curcmd` và giá trị `equiv` được lưu trong một biến tên là `curchr`.

### Bảng tương đương nói gì đối với def?

Như đã lưu ý, giá trị băm được tính cho bất kỳ lệnh nào được lưu trong một biến tên là `curcs`; do đó đối với `def` ta có `curcs=1218`. Khi xem vị trí 1218 trong bảng tương đương, TeX sẽ tìm thấy thông tin sau:

* `curcmd`=97. Đây là mã lệnh cho `\def`;
* `curchr`=0. Đây là bộ biến đổi lệnh cho `\def`.

`\def` là một lệnh TeX nguyên thủy (tích hợp sẵn) và trừ khi nó đã bị định nghĩa lại ở đâu đó, mẩu thông tin thứ ba và cuối cùng phải là `eq_level=1` cho thấy ý nghĩa của `\def` được định nghĩa toàn cục chứ không bị giới hạn trong một mức gom nhóm thấp hơn nào đó. Bên trong, giá trị `eq_level` gắn với một lệnh đóng vai trò cực kỳ quan trọng trong cơ chế gom nhóm của TeX nhưng chúng ta sẽ không xét thêm ở đây.

Đồ họa sau đây tóm tắt phần giải thích mà chúng ta vừa đi qua:

![Hành trình từ đầu vào TeX đến token TeX.](/files/a60f0cc5ba5a537f83fcd3878c391e83af61077e)

## Token TeX cho các lệnh

Sau khi đã lội qua các giải thích ở trên, việc thực sự tính token TeX cho các chuỗi điều khiển hóa ra lại rất đơn giản. TeX dùng giá trị của `curcs` (1218) từ hàm băm để tạo một số nguyên đơn giản mà nó gọi là một *token*token. `curcs` là:

```c
Công thức tính để tạo token từ giá trị của
```

curtok = 4095 + curcs `curtok`.

TeX lưu giá trị của token hiện tại (mới được tính gần đây nhất) trong một biến tên là `\def` lệnh là `4095 + 1218 = 5313`. Vì vậy, kết luận lại, token TeX biểu diễn

## Token TeX cho các ký tự

Khi TeX cần tạo một token biểu diễn một ký tự, nó dùng công thức đơn giản tương tự sau:

```c
curtok = 256*catcode + (giá trị ASCII của ký tự)
```

Lưu ý rằng các phép tính hơi khác được dùng cho các bộ máy nhận biết Unicode như LuaTeX.

Ví dụ, token TeX biểu diễn một ký tự khoảng trắng với `\catcode` 10 và giá trị ASCII 32 là:

```c
256*10 + 32 = 2592
```

### Danh sách token chứa các ký tự

Khi bạn tạo một danh sách token đơn giản với, chẳng hạn,

```latex
\toks100={Hello}
```

TeX sẽ tạo danh sách token sau đây và lưu chúng trong bộ nhớ để dùng sau:

* H→ 256 × 11 + 72 = 2888
* e→ 256 × 11 + 101 = 2917
* l→ 256 × 11 +108 = 2924
* l→ 256 × 11 +108 = 2924
* o→256 × 11 + 111 = 2927

Sâu trong bộ nhớ của TeX, thanh ghi token 100 sẽ cho phép truy cập đến vị trí lưu trữ của “Hello”, được lưu dưới dạng 5 giá trị token: 2888, 2917, 2924, 2924, 2927. Lưu ý rằng các token này kết hợp mã ASCII của từng ký tự và giá trị `\catcode`tại thời điểm chúng được chuyển thành token (được token hóa). Một khi các ký tự đã được chuyển thành token ký tự, giá trị `\catcode` gắn với chúng là vĩnh viễn và được lưu trong các token để dùng sau này khi người dùng nói, chẳng hạn, `\the\toks100`.

Như đã lưu ý, token ký tự được tính từ `256*catcode + (giá trị ASCII)` trong khi token chuỗi điều khiển được tính từ `4095 + curcs` trong đó `curcs` là giá trị băm của từ điều khiển (chuỗi văn bản của một lệnh do người dùng gõ) được TeX phát hiện trong đầu vào. Cần lưu ý rằng các token ký tự luôn nhỏ hơn 4095. Vì vậy TeX có thể dễ dàng xác định liệu một token cụ thể biểu diễn một chuỗi điều khiển (một lệnh) hay một ký tự, rồi xác định chính chuỗi điều khiển hoặc ký tự nào `\catcode` được mã hóa trong token đó.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://overleaf-pro.ayaka.space/latex/vi/bai-viet-chuyen-sau/53-what-is-a-tex-token.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
