Trong Xây dựng trình biên dịch của Aho Ullman và Sethi, người ta cho rằng chuỗi ký tự đầu vào của chương trình nguồn được chia thành chuỗi ký tự có ý nghĩa logic, và được gọi là thẻ và lexem là chuỗi tạo nên mã thông báo. sự khác biệt cơ bản là gì?
Trong Xây dựng trình biên dịch của Aho Ullman và Sethi, người ta cho rằng chuỗi ký tự đầu vào của chương trình nguồn được chia thành chuỗi ký tự có ý nghĩa logic, và được gọi là thẻ và lexem là chuỗi tạo nên mã thông báo. sự khác biệt cơ bản là gì?
Câu trả lời:
Sử dụng " Nguyên tắc, kỹ thuật và công cụ biên dịch, lần xuất bản thứ 2 " (WorldCat) của Aho, Lam, Sethi và Ullman, AKA the Purple Dragon Book ,
Lexeme pg. 111
Lexeme là một chuỗi các ký tự trong chương trình nguồn khớp với mẫu cho mã thông báo và được bộ phân tích từ vựng xác định là một phiên bản của mã thông báo đó.
Mã thông báo pg. 111
Mã thông báo là một cặp bao gồm tên mã thông báo và giá trị thuộc tính tùy chọn. Tên mã thông báo là một ký hiệu trừu tượng đại diện cho một loại đơn vị từ vựng, ví dụ: một từ khóa cụ thể hoặc chuỗi các ký tự đầu vào biểu thị một số nhận dạng. Tên mã thông báo là các ký hiệu đầu vào mà trình phân tích cú pháp xử lý.
Mô hình pg. 111
Một mẫu là một mô tả về dạng mà các lexemes của một mã thông báo có thể sử dụng. Trong trường hợp từ khóa là mã thông báo, mẫu chỉ là chuỗi ký tự tạo thành từ khóa. Đối với số nhận dạng và một số mã thông báo khác, mẫu có cấu trúc phức tạp hơn được ghép bởi nhiều chuỗi.
Hình 3.2: Ví dụ về mã thông báo pg.112
[Token] [Informal Description] [Sample Lexemes]
if characters i, f if
else characters e, l, s, e else
comparison < or > or <= or >= or == or != <=, !=
id letter followed by letters and digits pi, score, D2
number any numeric constant 3.14159, 0, 6.02e23
literal anything but ", surrounded by "'s "core dumped"
Để hiểu rõ hơn mối quan hệ này với lexer và trình phân tích cú pháp, chúng ta sẽ bắt đầu với trình phân tích cú pháp và làm việc ngược lại với đầu vào.
Để giúp thiết kế trình phân tích cú pháp dễ dàng hơn, trình phân tích cú pháp không làm việc trực tiếp với đầu vào mà lấy danh sách các mã thông báo do lexer tạo ra. Nhìn vào cột thẻ trong hình 3.2 chúng ta thấy mã thông báo như if
, else
, comparison
, id
, number
và literal
; đây là tên của các mã thông báo. Thông thường với lexer / parser, mã thông báo là một cấu trúc không chỉ chứa tên của mã thông báo mà còn chứa các ký tự / ký hiệu tạo nên mã thông báo và vị trí bắt đầu và kết thúc của chuỗi ký tự tạo nên mã thông báo, với vị trí bắt đầu và kết thúc được sử dụng để báo cáo lỗi, đánh dấu, v.v.
Bây giờ lexer lấy đầu vào của các ký tự / ký hiệu và sử dụng các quy tắc của lexer chuyển các ký tự / ký hiệu đầu vào thành các mã thông báo. Giờ đây, những người làm việc với lexer / parser có những từ ngữ riêng của họ cho những thứ họ sử dụng thường xuyên. Những gì bạn nghĩ về một chuỗi các ký tự / ký hiệu tạo nên mã thông báo là những gì những người sử dụng lexer / parsers gọi là lexeme. Vì vậy, khi bạn nhìn thấy lexeme, chỉ cần nghĩ đến một chuỗi các ký tự / biểu tượng đại diện cho một mã thông báo. Trong ví dụ so sánh, chuỗi ký tự / ký hiệu có thể là các mẫu khác nhau như <
hoặc >
hoặc else
hoặc 3.14
, v.v.
Một cách khác để nghĩ về mối quan hệ giữa hai mã này là mã thông báo là một cấu trúc lập trình được sử dụng bởi trình phân tích cú pháp có thuộc tính gọi là lexeme chứa ký tự / ký hiệu từ đầu vào. Bây giờ nếu bạn nhìn vào hầu hết các định nghĩa của mã thông báo trong mã, bạn có thể không thấy lexeme là một trong những thuộc tính của mã thông báo. Điều này là do mã thông báo có nhiều khả năng sẽ giữ vị trí bắt đầu và kết thúc của các ký tự / biểu tượng đại diện cho mã thông báo và lexeme, chuỗi ký tự / biểu tượng có thể được lấy từ vị trí bắt đầu và kết thúc khi cần thiết vì đầu vào là tĩnh.
an individual entry in the lexicon
can you please explain by taking simple input at parser stage and when does parser asks for tokens from lexer.
SO không phải là một trang thảo luận. Đó là một câu hỏi mới và cần được hỏi như một câu hỏi mới.
Khi một chương trình nguồn được đưa vào bộ phân tích từ vựng, nó sẽ bắt đầu bằng cách chia nhỏ các ký tự thành các chuỗi từ vựng. Các lexem sau đó được sử dụng để xây dựng các mã thông báo, trong đó các lexem được ánh xạ thành các mã thông báo. Một biến được gọi là myVar sẽ được ánh xạ thành một mã thông báo nêu rõ < id , "num">, trong đó "num" sẽ trỏ đến vị trí của biến trong bảng ký hiệu.
Nói ngắn gọn:
Một ví dụ bao gồm:
x = a + b * 2 Tạo
ra các lexemes: {x, =, a, +, b, *, 2}
Với các token tương ứng: {< id , 0>, <=>, < id , 1 >, <+>, < id , 2>, <*>, < id , 3>}
a) Mã thông báo là tên tượng trưng cho các thực thể tạo nên văn bản của chương trình; ví dụ: if cho từ khóa if và id cho bất kỳ mã định danh nào. Chúng tạo nên đầu ra của máy phân tích từ vựng. 5
(b) Một mẫu là một quy tắc chỉ định khi một chuỗi ký tự từ đầu vào tạo thành một mã thông báo; ví dụ: chuỗi i, f cho mã thông báo if, và bất kỳ chuỗi chữ và số nào bắt đầu bằng một chữ cái cho mã mã thông báo.
(c) Một lexeme là một chuỗi các ký tự từ đầu vào khớp với một mẫu (và do đó tạo thành một phiên bản của mã thông báo); ví dụ nếu khớp với mẫu cho if và foo123bar khớp với mẫu cho id.
LEXEME - Chuỗi ký tự khớp với PATTERN tạo thành TOKEN
PATTERN - Bộ quy tắc xác định TOKEN
TOKEN - Tập hợp các ký tự có ý nghĩa trên bộ ký tự của ngôn ngữ lập trình, ví dụ: ID, Hằng số, Từ khóa, Toán tử, Dấu câu, Chuỗi chữ
Lexeme - Một lexeme là một chuỗi các ký tự trong chương trình nguồn khớp với mẫu cho mã thông báo và được bộ phân tích từ vựng xác định là một phiên bản của mã thông báo đó.
Token - Token là một cặp bao gồm tên mã thông báo và giá trị mã thông báo tùy chọn. Tên mã thông báo là một danh mục của đơn vị từ vựng. Tên mã thông báo phổ biến là
Hãy xem xét biểu thức này trong ngôn ngữ lập trình C:
tổng = 3 + 2;
Mã hóa và đại diện bởi bảng sau:
Lexeme Token category
------------------------------
sum | Identifier
= | Assignment operator
3 | Integer literal
+ | Addition operator
2 | Integer literal
; | End of statement
Chúng ta hãy xem hoạt động của một máy phân tích từ vựng (còn gọi là Máy quét)
Hãy lấy một biểu thức ví dụ:
INPUT : cout << 3+2+3;
FORMATTING PERFORMED BY SCANNER : {cout}|space|{<<}|space|{3}{+}{2}{+}{3}{;}
không phải là đầu ra thực tế.
CÁC CUỐN SÁCH MÔ PHỎNG QUÉT LẠI ĐƯỢC LẶP LẠI CHO MỘT LEXEME TRONG VĂN BẢN CHƯƠNG TRÌNH NGUỒN CHO NẾU ĐẦU VÀO ĐƯỢC XẢ
Lexeme là một chuỗi con của đầu vào tạo thành một chuỗi đầu cuối hợp lệ có trong ngữ pháp. Mọi lexeme tuân theo một mẫu được giải thích ở cuối (phần mà người đọc có thể bỏ qua cuối cùng)
(Quy tắc quan trọng là tìm kiếm tiền tố dài nhất có thể tạo thành một chuỗi-đầu cuối hợp lệ cho đến khi gặp phải khoảng trắng tiếp theo ... được giải thích bên dưới)
LEXEMES:
(mặc dù "<" cũng là chuỗi ký tự đầu cuối hợp lệ nhưng quy tắc được đề cập ở trên sẽ chọn mẫu cho lexeme "<<" để tạo mã thông báo do máy quét trả về)
TOKENS: Các mã được trả lại từng lần một (bởi Máy quét khi Trình phân tích cú pháp yêu cầu) mỗi khi Máy quét tìm thấy một lexeme (hợp lệ). Máy quét tạo, nếu chưa có, một mục nhập bảng ký hiệu (có các thuộc tính: chủ yếu là danh mục mã thông báo và một số thuộc tính khác) , khi nó tìm thấy một lexeme, để tạo mã thông báo đó
'#' biểu thị mục nhập bảng ký hiệu. Tôi đã chỉ vào số lexeme trong danh sách trên để dễ hiểu nhưng về mặt kỹ thuật nó phải là chỉ số thực tế của bản ghi trong bảng ký hiệu.
Các mã thông báo sau được máy quét trả về trình phân tích cú pháp theo thứ tự được chỉ định cho ví dụ trên.
<số nhận dạng, # 1>
<Toán tử, # 2>
<Literal, # 3>
<Toán tử, # 4>
<Literal, # 5>
<Toán tử, # 4>
<Literal, # 3>
<Máy chấm câu, # 6>
Như bạn có thể thấy sự khác biệt, mã thông báo là một cặp không giống như lexeme là một chuỗi con của đầu vào.
Và phần tử đầu tiên của cặp là lớp / danh mục mã thông báo
Các loại mã thông báo được liệt kê dưới đây:
Và một điều nữa, Scanner phát hiện khoảng trắng, bỏ qua chúng và không tạo bất kỳ mã thông báo nào cho khoảng trắng cả. Không phải tất cả các dấu phân cách đều là khoảng trắng, khoảng trắng là một dạng dấu phân cách được các máy quét sử dụng cho mục đích đó. Tab, Dòng mới, Dấu cách, Ký tự thoát trong đầu vào được gọi chung là dấu phân cách Khoảng trắng. Một số dấu phân cách khác là ';' ',' ':' vv, được công nhận rộng rãi là lexemes tạo thành mã thông báo.
Tổng số mã thông báo được trả lại là 8 ở đây, tuy nhiên chỉ có 6 mục nhập bảng biểu tượng được thực hiện cho lexemes. Tổng cộng lexemes cũng là 8 (xem định nghĩa của lexeme)
--- Bạn có thể bỏ qua phần này
A ***pattern*** is a rule ( say, a regular expression ) that is used to check if a string-of-terminals is valid or not
.
If a substring of input composed only of grammar terminals is
following the rule specified by any of the listed patterns , it is
validated as a lexeme and selected pattern will identify the category
of lexeme, else a lexical error is reported due to either (i) not
following any of the rules or (ii) input consists of a bad
terminal-character not present in grammar itself.
for example :
1. No Pattern Exists : In C++ , "99Id_Var" is grammar-supported string-of-terminals but is not recognised by any of patterns hence lexical error is reported .
2. Bad Input Character : $,@,unicode characters may not be supported as a valid character in few programming languages.`
Lexeme - Lexeme là một chuỗi ký tự là đơn vị cú pháp cấp thấp nhất trong ngôn ngữ lập trình.
Mã thông báo - Mã thông báo là một danh mục cú pháp tạo thành một lớp lexemes có nghĩa là lexeme thuộc về lớp nào thì đó là từ khóa hoặc mã định danh hoặc bất kỳ thứ gì khác. Một trong những nhiệm vụ chính của trình phân tích từ vựng là tạo một cặp từ vựng và mã thông báo, nghĩa là thu thập tất cả các ký tự.
Chúng ta hãy lấy một ví dụ:-
nếu (y <= t)
y = y-3;
nếu KEYWORD
(PHỤ TÙNG TRÁI
y IDENTIFIER
<= SO SÁNH
t IDENTIFIER
) ĐÚNG PHỤ LỤC
y IDENTIFIER
= ĐÁNH GIÁ
y IDENTIFIER
_ THUẬT TOÁN
3 INTEGER
; SEMICOLON
Mối quan hệ giữa Lexeme và Token
Mã thông báo: Loại cho (từ khóa, mã định danh, ký tự chấm câu, toán tử nhiều ký tự), đơn giản là Mã thông báo.
Mẫu: Quy tắc hình thành mã thông báo từ các ký tự đầu vào.
Lexeme: Một chuỗi các ký tự trong CHƯƠNG TRÌNH NGUỒN được khớp với một mẫu cho mã thông báo. Về cơ bản, nó là một phần tử của Token.
Mã thông báo: Mã thông báo là một chuỗi các ký tự có thể được coi như một thực thể logic duy nhất. Các mã thông báo điển hình là,
1) Số nhận dạng
2) từ khóa
3) toán tử
4) ký hiệu đặc biệt
5) hằng số
Mẫu: Một tập hợp các chuỗi trong đầu vào mà mã thông báo tương tự được tạo như đầu ra. Tập hợp các chuỗi này được mô tả bởi một quy tắc được gọi là mẫu được liên kết với mã thông báo.
Lexeme: Lexeme là một chuỗi các ký tự trong chương trình nguồn được khớp với mẫu cho mã thông báo.
Lexeme Lexemes được cho là một chuỗi các ký tự (chữ và số) trong một mã thông báo.
Mã thông báo Mã thông báo là một chuỗi các ký tự có thể được xác định như một thực thể logic duy nhất. Thông thường các mã thông báo là từ khóa, định danh, hằng số, chuỗi, ký hiệu dấu câu, toán tử. những con số.
Mẫu Một tập hợp các chuỗi được mô tả bởi quy tắc được gọi là mẫu. Một mẫu giải thích những gì có thể là mã thông báo và các mẫu này được xác định bằng các biểu thức chính quy, được liên kết với mã thông báo.
Các nhà nghiên cứu CS, như những người từ Toán học, thích tạo ra các thuật ngữ "mới". Các câu trả lời trên đều rất hay nhưng rõ ràng, không có nhu cầu lớn như vậy để phân biệt token và lexemes IMHO. Chúng giống như hai cách để đại diện cho cùng một thứ. Một lexeme là cụ thể - ở đây là một tập hợp các ký tự; Mặt khác, mã thông báo là trừu tượng - thường đề cập đến loại lexeme cùng với giá trị ngữ nghĩa của nó nếu điều đó có ý nghĩa. Chỉ hai xu của tôi.
Lexical Analyzer nhận một chuỗi các ký tự xác định một lexeme khớp với biểu thức chính quy và phân loại thêm nó thành mã thông báo. Do đó, một Lexeme là một chuỗi được so khớp và tên Mã thông báo là danh mục của lexeme đó.
Ví dụ: hãy xem xét bên dưới biểu thức chính quy cho một số nhận dạng có đầu vào "int foo, bar;"
chữ cái (chữ cái | chữ số | _) *
Ở đây, foo
và bar
đối sánh với biểu thức chính quy do đó cả hai đều là từ vựng nhưng được phân loại là một mã thông báo ID
tức là mã định danh.
Cũng lưu ý, giai đoạn tiếp theo, tức là trình phân tích cú pháp không cần phải biết về lexeme mà là một mã thông báo.
Lexeme về cơ bản là đơn vị của mã thông báo và về cơ bản nó là chuỗi các ký tự khớp với mã thông báo và giúp chia mã nguồn thành các mã thông báo.
Ví dụ: Nếu nguồn là x=b
, sau đó các lexemes sẽ x
, =
, b
và các thẻ sẽ là <id, 0>
, <=>
, <id, 1>
.