18. Token hóa

Mã thông báo là giai đoạn cấu trúc đầu tiên trong quy trình biên dịch của CPython.

Nó nhận văn bản nguồn Python và tạo ra một luồng mã thông báo. Trình phân tích cú pháp sử dụng luồng mã thông báo đó và xây dựng cấu trúc cú pháp từ nó.

Ở giai đoạn này, CPython vẫn chưa biết liệu một chương trình có ý nghĩa hay không. Nó chỉ nhận dạng các đơn vị từ vựng: tên, số, chuỗi, toán tử, dòng mới, thụt lề và dấu cuối tập tin.

Trình mã thông báo biến điều này:python def add(a, b): return a + b thành một dòng có hình dạng như thế này:text NAME "def" NAME "add" LPAR "(" NAME "a" COMMA "," NAME "b" RPAR ")" COLON ":" NEWLINE "\n" INDENT " " NAME "return" NAME "a" PLUS "+" NAME "b" NEWLINE "\n" DEDENT "" ENDMARKER "" Tên mã thông báo chính xác và giao diện trình phân tích cú pháp khác nhau giữa các phiên bản CPython, nhưng ý tưởng cốt lõi là ổn định. Thư viện chuẩn Python hiển thị mã thông báo cấp Python thông quatokenize, trong khi trình phân tích cú pháp của CPython sử dụng mã thông báo C của riêng nó trong nội bộ. Công chúngtokenizemô-đun cũng trả về các nhận xét và mã thông báo mã hóa ban đầu, giúp nó phù hợp với các công cụ như trình định dạng và tô sáng cú pháp. ([Tài liệu Python][1])

18.1 Vị trí trong Đường dẫn biên dịch

Đường dẫn nguồn thực thi đầy đủ là:```text bytes from file or string ↓ encoding detection ↓ decoded source text ↓ tokenizer ↓ token stream ↓ parser ↓ abstract syntax tree ↓ symbol table ↓ code object ↓ bytecode execution


Trình mã thông báo tr li các câu hi như:```text
Where does this logical line end?
Is this identifier a name?
Is this numeric literal well-formed?
Is this string literal closed?
Did indentation increase or decrease?
Is this character part of an operator?
Has the source reached end-of-file?
```Trình phân tích cú pháp tr li các câu hi khác nhau:```text
Is this a valid function definition?
Is this expression allowed here?
Does this statement match a grammar rule?
Does this sequence form a valid pattern match?
How should these tokens be grouped into an AST?
```Trình mã thông báo không to AST. Nó ch to ra mt chui các s kin t vng.

## 18.2 Đầu vào và mã hóa nguồn

Ngun Python thường bt đầu bng byte.

Trước khi quá trình mã hóa có th được tiến hành, CPython phi xác định cách gii mã các byte đó thành văn bn. Các tp ngun Python theo mc định là UTF-8, nhưng mt tp có th khai báo mt mã hóa khác  gn đầu.

Khai báo mã hóa đin hình:```python
# -*- coding: latin-1 -*-
```hoc:```python
# coding: utf-8
```Trình mã thông báo phi x lý vic này sm vì nó không th phân loi các ký t ngun mt cách đáng tin cy cho đến khi ngun được gii mã.

 cp độ Python,`tokenize.tokenize()`bt đầu bng cách tr li mt`ENCODING`mã thông báo. các`token`tài liu lưu ý rng điu này`ENCODING`mã thông báo là cn thiết cho Python`tokenize`mô-đun và không được mã thông báo C ca CPython s dng theo cách tương t. ([Tài liu Python][2])

Mô hình thc tế là:```text
read first source lines
detect encoding declaration if present
decode source bytes
normalize line handling
begin lexical scanning
```Đây là lý do ti sao vic mã thông báo không ch là mt vòng lp trên các ký t. Nó cũng s hu ranh gii gia byte ngun bên ngoài và văn bn ngun bên trong.

## 18.3 Đường vật lý và Đường logic

Ngun Python có dòng vt lý và dòng logic.

Mt dòng vt lý là mt dòng trong tp ngun.

Mt dòng logic là mt câu lnh hoc đơn v biu thc Python hoàn chnh mà trình phân tích cú pháp nhìn thy.

Thông thường chúng ging nhau:```python
x = 1
y = 2
``` đây, mi dòng vt lý cũng là mt dòng logic.

Nhưng Python cho phép ni dòng rõ ràng bng du gch chéo ngược:```python
x = 1 + \
    2 + \
    3
```Đây là mt dòng logic tri rng trên ba dòng vt lý.

Python cũng cho phép ni dòng ngm bên trong du ngoc đơn, du ngoc và du ngoc nhn:```python
values = [
    1,
    2,
    3,
]
```Bên trong các du phân cách nhóm, dòng mi không kết thúc câu lnh logic. Trình mã thông báo theo dõi độ sâu lng nhau để có th phân bit các dòng mi quan trng vi các dòng mi không quan trng.

V mt khái nim:```text
paren_level = 0

when "(" or "[" or "{" appears:
    paren_level += 1

when ")" or "]" or "}" appears:
    paren_level -= 1

when newline appears:
    if paren_level == 0:
        emit NEWLINE
    else:
        ignore as statement terminator
```Quy tc này rt cn thiết cho cú pháp nhiu dòng d đọc ca Python.

## 18.4`NEWLINE`Và`NL`Mã thông báo cấp Python phân biệt giữa dòng mới theo logic và dòng mới không kết thúc.

Ti công chúng`tokenize`cp độ:

| Mã thông báo | Ý nghĩa |
| --------- | ---------------------------------------- |
|`NEWLINE`| Kết thúc mt dòng hp lý |
|`NL`| Dòng mi không kết thúc mt dòng hp lý |

Ví d:```python
x = (
    1 +
    2
)
y = 3
```Các dòng mi bên trong du ngoc đơn không phi là du kết thúc câu lnh. Trình phân tích cú pháp không nên x lý`1 +`như mt tuyên b hoàn chnh. Nhng ngt dòng đó tn ti để b trí, không phi ng pháp.

Trong trình mã thông báo đối din vi công c, chúng xut hin dưới dng`NL`. Trong mô hình đối mt vi trình phân tích cú pháp, chúng b b qua hoc x lý khác vi các dòng mi logic thc s.

S khác bit này rt quan trng đối vi các trình định dng và linters. Trình định dng có th quan tâm đến mi dòng mi vt lý. Trình phân tích cú pháp ch cn cu trúc logic.

## 18.5 Thụt lề dưới dạng mã thông báo

Python s dng tht l làm cú pháp.

Điu đó có nghĩa là trình mã thông báo phi biến khong trng  đầu thành mã thông báo.

Ví d:```python
if ready:
    run()
    log()
finish()
```Trình phân tích cú pháp không th hiu ngun này nếu ch s dng tên và du câu. Nó cn ranh gii khi rõ ràng.

Trình mã thông báo phát ra:```text
NAME      "if"
NAME      "ready"
COLON     ":"
NEWLINE   "\n"
INDENT    "    "
NAME      "run"
LPAR      "("
RPAR      ")"
NEWLINE   "\n"
NAME      "log"
LPAR      "("
RPAR      ")"
NEWLINE   "\n"
DEDENT    ""
NAME      "finish"
LPAR      "("
RPAR      ")"
NEWLINE   "\n"
ENDMARKER ""
```Tht l to ra mt khi bt đầu o. Vic tht l to ra mt kết thúc khi o.

CPython duy trì mt ngăn xếp tht đầu dòng. Khi bt đầu mt dòng logic, b mã thông báo s đo khong trng  đầu và so sánh nó vi mc tht l hin ti.

Mô hình đơn gin hóa:```text
indent_stack = [0]

at beginning of logical line:
    col = indentation_column()

    if col > indent_stack[-1]:
        push col
        emit INDENT

    else if col == indent_stack[-1]:
        emit no indentation token

    else:
        while col < indent_stack[-1]:
            pop
            emit DEDENT

        if col != indent_stack[-1]:
            report indentation error
```K lut ngăn xếp này gii thích ti sao vic tht l không nht quán là mt li t vng trước khi quá trình phân tích cú pháp thông thường có th tiếp tc.

## 18.6 Tab, Dấu cách và Cột thụt lề

Tht l được đo bng ct, không phi ký t thô.

Du cách tiến lên mt ct. Các tab tiến ti đim dng tab tiếp theo. Vic x lý tab ca Python tn ti để tương thích, nhưng vic trn ln các tab và du cách có th to ra li và li tht vào không rõ ràng.

Ví d:```python
if x:
\tprint("tab")
    print("spaces")
```Căn chnh trc quan có th ph thuc vào cài đặt trình son tho. CPython không th tin tưởng cách trình son tho ca con người hin th điu này. Nó tính toán tht l bng cách s dng các quy tc tab ca ngôn ng và phát sinh li khi tht l không nht quán.

Đim ni b quan trng là tht l không được lưu tr dưới dng s ký t đầu. Nó được chuyn đổi thành mc tht l. Các mc đó được so sánh vi ngăn xếp tht l.

## 18.7 Dòng trống và Dòng chỉ nhận xét

Các dòng trng thường không to ra các mã thông báo có ý nghĩa đối vi trình phân tích cú pháp.

Ví d:```python
x = 1

y = 2
```Dòng trng không kết thúc mt khi hoc to mt câu lnh.

Các dòng ch nhn xét hot động tương t đối vi trình phân tích cú pháp:```python
x = 1
# comment
y = 2
```Công chúng`tokenize`mô-đun tr v nhn xét vì các công c cn chúng. Trình phân tích cú pháp ca CPython không coi nhn xét là cú pháp.

S khác bit này rt quan trng:

| Người tiêu dùng | Cn bình lun? | Lý do |
| ------------------ | --------------: | ---------------------------------- |
| Trình phân tích cú pháp |              Không | Bình lun không nh hưởng ti ng pháp |
| Trình định dng |             Có | Bình lun phi được bo tn |
| Công c tô sáng cú pháp |             Có | Bình lun cn to kiu |
| K nói di |             Có | Bình lun có th cha ch th |
| Trình kim tra loi |       Đôi khi | Bình lun có th cha loi bình lun |

Mã thông báo công khai là mt API công c. Mã thông báo C là mt phn ca giao din người dùng ca trình biên dch.

## 18.8 Tên, Từ khóa và Từ khóa mềm

Mã định danh được mã hóa dưới dng tên.

Ví d:```python
total = price + tax
```Trình mã thông báo thy:```text
NAME "total"
EQUAL "="
NAME "price"
PLUS "+"
NAME "tax"
```T khóa Python truyn thng bao gm các t như:```text
def
class
if
else
while
for
try
except
return
yield
import
from
with
lambda
``` cp độ t vng, đây là nhng chui hình tên. Trình mã thông báo hoc trình phân tích cú pháp có th phân loi chúng theo nhu cu ng pháp.

Python hin đại cũng có t khóa mm. T khóa mm ch hot động ging như t khóa  các v trí ng pháp c th.

Ví d bao gm các t được s dng bi khp mu:```python
match value:
    case 0:
        pass

matchcasevẫn có thể được sử dụng như tên thông thường trong các ngữ cảnh khác mà ngữ pháp cho phép.

Đây là một lý do khiến quá trình mã hóa và phân tích cú pháp phải hợp tác. Một tokenizer đã chuyển đổi vĩnh viễn mỗi lần xuất hiện củamatchvào mã thông báo từ khóa cứng sẽ từ chối mã hợp lệ trong bối cảnhmatchchỉ là một cái tên.

Nguyên tắc thực hành:```text hard keyword: reserved everywhere soft keyword: special only in selected grammar positions name: ordinary identifier


Mã định danh Python có thể chứa nhiều ký tự Unicode.

Ví dụ:```python
π = 3.14159
面积 = 42
```Trình mã thông báo phải nhận dạng các ký tự bắt đầu và tiếp tục định danh theo quy tắc định danh của Python. Điều này mang lại sự hỗ trợ Unicode rộng rãi cho mã nguồn Python.

Nhưng số nhận dạng vẫn được chuẩn hóa và kiểm tra theo quy tắc ngôn ngữ. Không phải mọi ký tự Unicode đều hợp pháp trong tên và một số ký tự trông giống nhau có thể khác biệt.

Từ góc độ nội bộ, việc xử lý mã định danh yêu cầu:```text
Unicode-aware character classification
identifier start validation
identifier continuation validation
normalization rules
error reporting for invalid characters
```Điều này làm cho mã thông báo Python phức tạp hơn mã thông báo ngôn ngữ chỉ ASCII.

## 18.10 Chữ số

Trình mã thông báo nhận dạng các chữ số trước khi trình phân tích cú pháp xây dựng các biểu thức.

Ví dụ:```python
123
0b1010
0o755
0xff
1_000_000
3.14
10.
.5
1e9
1.2e-3
3j
```Chúng trở thành mã thông báo số.

Trình mã thông báo phải xác thực dạng từ vựng:```text
base prefixes
digits allowed in each base
underscore placement
decimal points
exponents
imaginary suffix
```Một số số không hợp lệ không thành công trong quá trình mã thông báo:```python
0b102
1__2
```Trình mã thông báo không đánh giá số học tùy ý. Nó chỉ nhận ra mã thông báo theo nghĩa đen. Các giai đoạn biên dịch sau này chuyển đổi văn bản mã thông báo thành đối tượng Python tương ứng.

Ví dụ:```python
x = 1 + 2
```Mã thông báo thấy:```text
NAME     "x"
EQUAL    "="
NUMBER   "1"
PLUS     "+"
NUMBER   "2"
```Sự thật là`1 + 2`có thể được gấp lại thành`3`thuộc về tối ưu hóa trình biên dịch sau này, không phải mã thông báo.

## 18.11 Chuỗi ký tự

Mã thông báo chuỗi phức tạp hơn mã thông báo số.

Python hỗ trợ:```python
"hello"
'hello'
"""hello"""
'''hello'''
r"\n"
b"bytes"
f"value={x}"
fr"path={name}\n"
```Trình mã thông báo phải xác định:```text
string prefixes
quote style
single-line or triple-quoted form
raw strings
bytes strings
f-strings
escape sequences
line continuation rules
string termination
```Mã thông báo chuỗi thông thường được nhận dạng là một đơn vị từ vựng:```python
x = "hello"
```Luồng mã thông báo:```text
NAME    "x"
EQUAL   "="
STRING  "\"hello\""
```Chuỗi trích dẫn ba có thể kéo dài các dòng vật lý:```python
text = """
line 1
line 2
"""
```Trình mã thông báo phải tiếp tục quét cho đến khi tìm thấy trích dẫn ba phù hợp.

Các chuỗi bị hủy là lỗi mã thông báo:```python
x = "missing end
```Trình phân tích cú pháp không thể khôi phục ngữ pháp có ý nghĩa từ một chuỗi bị kết thúc vì trình mã thông báo không thể tạo ra luồng mã thông báo hợp lệ.

## 18.12 Dây F

Chuỗi F đặc biệt vì chúng chứa cả nội dung chuỗi ký tự và các biểu thức Python được nhúng.

Ví dụ:```python
name = "Ada"
text = f"hello {name.upper()}"
```Bên trong chuỗi, phần này là văn bản bằng chữ:```text
hello 
```Phần này là cú pháp biểu thức Python:```python
name.upper()
```Trình mã thông báo và trình phân tích cú pháp phải hợp tác để xử lý cấu trúc lồng nhau này.

Về mặt khái niệm:```text
enter f-string mode
scan literal characters
when "{" starts expression:
    tokenize embedded Python expression
    parse embedded expression
return to f-string literal scanning
finish at closing quote
```Việc xử lý biểu thức lồng nhau làm cho chuỗi f phong phú hơn nhiều so với các chuỗi ký tự thông thường. Chúng không chỉ là các mã thông báo chuỗi có thể thay thế văn bản sau này. Chúng chứa cú pháp phải được phân tích cú pháp thành các nút biểu thức.

## 18.13 Toán tử và dấu phân cách

Các toán tử và dấu phân cách trong Python bao gồm các dạng một ký tự và nhiều ký tự.

Ví dụ:```text
+   -   *   /   //   %   **
=   ==  !=  <   <=   >   >=
:=  ->  @   @=
(   )   [   ]   {   }
,   :   .   ;   ...
```Trình mã thông báo thường áp dụng hành vi khớp dài nhất.

Ví dụ, khi đọc`**=`, nó sẽ tạo ra một mã thông báo toán tử gán quyền thay vì`*`, `*`, Và`=`.

Logic đơn giản hóa:```text
if next characters form "**=":
    emit DOUBLESTAR_EQUAL
else if next characters form "**":
    emit DOUBLESTAR
else if next character is "*":
    emit STAR
```Quy tắc này phổ biến trong các tokenizer. Nó giúp trình phân tích cú pháp không phải xây dựng lại các toán tử nhiều ký tự từ các phần nhỏ hơn.

## 18.14 Mã thông báo lỗi và lỗi từ vựng

Một số lỗi xuất hiện trước khi phân tích cú pháp.

Ví dụ:```python
x = "unterminated
if x:
  a = 1
 b = 2
x = 0b123
```Đây  những lỗi từ vựng hoặc thụt lề.

Trình  thông báo phải báo cáo đủ thông tin để chẩn đoán hữu ích:```text
filename
line number
column offset
source line
error type
error message
```Các lỗi  giai đoạn  thông báo phổ biến bao gồm:

| Lỗi | Nguyên nhân |
| ------------------ | --------------------------------------------- |
|`SyntaxError`| Cấu trúc từ vựng hoặc chuỗi  thông báo không hợp lệ |
|`IndentationError`| Mức thụt lề không hợp lệ |
|`TabError`| Thụt lề  hồ từ các tab  dấu cách |
|`TokenError`| Lỗi  thông báo công khai do đầu vào không đầy đủ |

Không phải mọi`SyntaxError`bắt nguồn từ việc  hóa. Nhiều đến từ việc phân tích  pháp. Tuy nhiên, trình  thông báo sở hữu các lỗi ngăn cản luồng  thông báo hợp lệ tồn tại.

## 18.15 Kết thúc tệp và thụt lề tổng hợp

 cuối tệp, CPython phải đóng mọi khối thụt lề đang mở.

 dụ:```python
if x:
    if y:
        run()
```Nguồn kết thúc trong khi hai mức thụt lề vẫn hoạt động. Tokenizer phát ra tổng hợp`DEDENT` thông báo trước`ENDMARKER`.

Về mặt khái niệm:```text
NAME      "if"
NAME      "x"
COLON     ":"
NEWLINE
INDENT
NAME      "if"
NAME      "y"
COLON     ":"
NEWLINE
INDENT
NAME      "run"
LPAR
RPAR
NEWLINE
DEDENT
DEDENT
ENDMARKER
```Điều này cho phép trình phân tích  pháp nhìn thấy các kết thúc khối ngay cả khi không  dấu ngoặc nhọn đóng  ràng.

Do đó, trình  thông báo tạo  thông báo không   tự trực tiếp trong tệp nguồn.`INDENT`, `DEDENT`, `ENDMARKER` các  thông báo cấu trúc.

## 18.16 Trạng thái mã thông báo

Một  thông báo  trạng thái.

 phải nhớ:```text
current input pointer
current line
current column
current indentation stack
current nesting level
whether scanning begins a line
whether inside a string
whether inside an f-string expression
whether an encoding was detected
whether interactive mode is active
pending INDENT or DEDENT tokens
error state
```Một máy quét không trạng thái sẽ không đủ cho Python  ý nghĩa phụ thuộc vào bố cục  ngữ cảnh.

 dụ:```python
x = [
    1,
    2,
]
```Dòng mới sau`1,`xuất hiện bên trong dấu ngoặc.  không nên trở nên logic`NEWLINE`.

 dụ:```python
if x:
    y = 1
z = 2
```Khoảng trắng hàng đầu trước`z`gây ra một`DEDENT`.

Những quyết định đó đòi hỏi trạng thái được ghi nhớ.

## 18.17 Mã thông báo tương tác

Đầu vào tương tác  trường hợp đặc biệt.

Trong REPL, CPython thường cần quyết định xem dữ liệu đầu vào đã hoàn tất hay chưa.

 dụ:```python
>>> if x:
...
```Điều này  không đầy đủ  dự kiến ​​sẽ  phần thân khối.

 dụ:```python
>>> x = (1 +
...
```Điều này chưa đầy đủ  biểu thức trong ngoặc đơn vẫn mở.

Trình  thông báo  trình phân tích  pháp hợp tác để quyết định xem nên yêu cầu một dòng khác hay phát sinh lỗi. Do đó, chế độ tương tác khác với chế độ tập tin. Kết thúc đầu vào trong một tệp  nghĩa  EOF thực sự. Kết thúc đầu vào trong REPL  thể  nghĩa  yêu cầu thêm văn bản.

## 18.18 Công khai`tokenize`mô-đun

Thư viện chuẩn hiển thị  thông báo thông qua`tokenize`.

 dụ:```python
from io import BytesIO
import tokenize

src = b"x = 1 + 2\n"

for tok in tokenize.tokenize(BytesIO(src).readline):
    print(tok)
```Đầu ra  hình dạng như sau:```text
TokenInfo(type=ENCODING, string='utf-8', ...)
TokenInfo(type=NAME, string='x', ...)
TokenInfo(type=OP, string='=', ...)
TokenInfo(type=NUMBER, string='1', ...)
TokenInfo(type=OP, string='+', ...)
TokenInfo(type=NUMBER, string='2', ...)
TokenInfo(type=NEWLINE, string='\n', ...)
TokenInfo(type=ENDMARKER, string='', ...)
```Trình  thông báo công khai hữu ích cho:```text
formatters
linters
code generators
syntax highlighters
refactoring tools
documentation tools
source-to-source transforms
```các`tokenize`tài liệu  tả  như một máy quét từ vựng cho nguồn Python  lưu ý rằng  trả về các nhận xét dưới dạng  thông báo, điều này làm cho  hữu ích cho các máy in  máy  màu đẹp. ([Tài liệu Python][1])

## 18.19 Mã thông báo C so với Mã thông báo Python

 hai khái niệm tokenizer liên quan trong CPython:

| Thành phần | Vị trí | Mục đích |
| ----------------- | --------------------------------- | ----------------------------------- |
|  thông báo C | Nội bộ của trình biên dịch/phân tích  pháp CPython | Cung cấp trình phân tích  pháp trong quá trình biên dịch |
|`Lib/tokenize.py`| Thư viện chuẩn | Đưa  thông báo vào các công cụ Python |

Chúng không phải  giao diện giống hệt nhau.

 thông báo C được tối ưu hóa cho đường dẫn trình biên dịch của CPython.  tạo ra những  trình phân tích  pháp cần.

 thông báo Python  một giao diện công cụ công cộng.  bảo tồn các bình luận, hiển thị  hóa, trả về phong phú`TokenInfo`đối tượng  được thiết kế cho người tiêu dùng bên ngoài.

Sự khác biệt này giải thích tại sao  thông báo truyền từ`tokenize` thể chứa thông tin  trình phân tích  pháp bỏ qua.

## 18.20 Ví dụ chi tiết về token hóa

Hãy xem xét nguồn này:```python
def area(r):
    pi = 3.14159
    return pi * r * r
```Luồng  thông báo được đơn giản hóa:```text
NAME       "def"
NAME       "area"
LPAR       "("
NAME       "r"
RPAR       ")"
COLON      ":"
NEWLINE    "\n"
INDENT     "    "
NAME       "pi"
EQUAL      "="
NUMBER     "3.14159"
NEWLINE    "\n"
NAME       "return"
NAME       "pi"
STAR       "*"
NAME       "r"
STAR       "*"
NAME       "r"
NEWLINE    "\n"
DEDENT     ""
ENDMARKER  ""
```Những điểm quan trọng:

1.`def` hình dạng từ vựng nhưng đóng vai trò như một từ khóa về mặt ngữ pháp.
2. Thân hàm bắt đầu  mức thụt lề tăng sau`NEWLINE`.
3.`3.14159` một  thông báo số duy nhất.
4.`return pi * r * r` một dòng logic.
5.  thể chức năng kết thúc thông qua một  chế tổng hợp`DEDENT`.
6. Tệp kết thúc thông qua`ENDMARKER`.

Trình phân tích  pháp nhận luồng này  khớp  với các quy tắc ngữ pháp cho định nghĩa hàm, bộ, phép gán, câu lệnh trả về  biểu thức.

## 18.21 Tokenization không hiểu đầy đủ ngữ nghĩa

Trình  thông báo không biết rằng tên này không được xác định:```python
print(missing_name)
``` không biết rằng cuộc gọi này sẽ thất bại:```python
1()
``` không biết liệu nhập khẩu này  tồn tại hay không:```python
import does_not_exist
``` chỉ phát ra  thông báo.

Việc kiểm tra ngữ nghĩa diễn ra sau đó, thường  trong thời gian chạy.

Token hóa  chủ ý nông cạn.  nhận dạng dạng từ vựng chứ không phải ý nghĩa chương trình.

## 18.22 Tại sao việc mã hóa lại quan trọng

 thông báo  vẻ nhỏ nhưng  định hình toàn bộ ngôn ngữ.

 định nghĩa:```text
how indentation becomes syntax
how source bytes become characters
how comments are ignored or preserved
how strings are delimited
how f-strings embed expressions
how operators are recognized
how logical lines are formed
how parser input is structured
```Đối với những người đóng góp CPython, lỗi  thông báo  thể ảnh hưởng đến  pháp, chẩn đoán, công cụ, khả năng tương thích  bảo mật. Một thay đổi từ vựng nhỏ  thể thay đổi cách phân tích  pháp mọi tệp Python.

Đối với các tác giả công cụ,  thông báo thường  lớp tốt nhất để làm việc.  lưu giữ thông tin cấp nguồn  AST loại bỏ, bao gồm các nhận xét, khoảng cách chính xác, dòng vật   chính tả của toán tử.

## 18.23 Mô hình tinh thần tối thiểu

Sử dụng  hình này:```text
The tokenizer reads decoded Python source.
It emits lexical tokens.
It tracks indentation, nesting, strings, and line boundaries.
It inserts structural tokens such as INDENT, DEDENT, and ENDMARKER.
It reports lexical errors before parsing.
The parser consumes tokens and builds syntax structure.
```Đó  cầu nối từ văn bản nguồn thô đến ngữ pháp.