อะไรคือความแตกต่างระหว่างโทเค็นและคำศัพท์?


86

ในการสร้างคอมไพเลอร์โดย Aho Ullman และ Sethi กำหนดให้สตริงอินพุตของอักขระของโปรแกรมต้นทางถูกแบ่งออกเป็นลำดับของอักขระที่มีความหมายเชิงตรรกะและเป็นที่รู้จักกันในชื่อโทเค็นและ lexemes เป็นลำดับที่ประกอบเป็นโทเค็นดังนั้นสิ่งที่ ความแตกต่างพื้นฐานคืออะไร?

คำตอบ:


120

การใช้ " หลักการคอมไพเลอร์เทคนิคและเครื่องมือ 2nd Ed. " (WorldCat)โดย Aho, Lam, Sethi and Ullman, AKA the Purple Dragon Book ,

Lexeme หน้า 111

lexeme คือลำดับของอักขระในโปรแกรมต้นทางที่ตรงกับรูปแบบของโทเค็นและถูกระบุโดยตัววิเคราะห์คำศัพท์เป็นตัวอย่างของโทเค็นนั้น

โทเค็นหน้า 111

โทเค็นคือคู่ที่ประกอบด้วยชื่อโทเค็นและค่าแอตทริบิวต์ที่เป็นทางเลือก ชื่อโทเค็นเป็นสัญลักษณ์นามธรรมที่แสดงถึงหน่วยคำศัพท์ชนิดหนึ่งเช่นคำสำคัญเฉพาะหรือลำดับของอักขระอินพุตที่แสดงถึงตัวระบุ ชื่อโทเค็นคือสัญลักษณ์อินพุตที่ตัวแยกวิเคราะห์ประมวลผล

รูปแบบหน้า 111

รูปแบบคือคำอธิบายของรูปแบบที่อาจใช้คำศัพท์ของโทเค็น ในกรณีของคีย์เวิร์ดเป็นโทเค็นรูปแบบเป็นเพียงลำดับของอักขระที่สร้างคีย์เวิร์ด สำหรับตัวระบุและโทเค็นอื่น ๆ รูปแบบเป็นโครงสร้างที่ซับซ้อนมากขึ้นซึ่งจับคู่โดยสตริงจำนวนมาก

รูปที่ 3.2: ตัวอย่างโทเค็นหน้า 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"

เพื่อให้เข้าใจถึงความสัมพันธ์กับตัวเล็กซ์เซอร์และตัวแยกวิเคราะห์นี้ได้ดีขึ้นเราจะเริ่มต้นด้วยตัวแยกวิเคราะห์และย้อนกลับไปที่อินพุต

เพื่อให้ง่ายต่อการออกแบบตัวแยกวิเคราะห์ตัวแยกวิเคราะห์จะไม่ทำงานกับอินพุตโดยตรง แต่รับรายการโทเค็นที่สร้างโดยตัวเล็กซ์เซอร์ มองไปที่โทเค็นคอลัมน์ในรูปที่ 3.2 เราเห็นราชสกุลเช่นif, else, comparison, id,numberและliteral; นี่คือชื่อของโทเค็น โดยทั่วไปแล้วโทเค็นจะใช้ตัวเล็กเซอร์ / ตัวแยกวิเคราะห์เป็นโครงสร้างที่ไม่เพียง แต่เก็บชื่อของโทเค็นเท่านั้น แต่ยังรวมถึงอักขระ / สัญลักษณ์ที่ประกอบเป็นโทเค็นและตำแหน่งเริ่มต้นและสิ้นสุดของสตริงของอักขระที่ประกอบเป็นโทเค็นด้วย ตำแหน่งเริ่มต้นและตำแหน่งสิ้นสุดที่ใช้สำหรับการรายงานข้อผิดพลาดการไฮไลต์ ฯลฯ

ตอนนี้ lexer รับอินพุตของอักขระ / สัญลักษณ์และใช้กฎของ lexer แปลงอักขระ / สัญลักษณ์อินพุตเป็นโทเค็น ตอนนี้คนที่ทำงานกับ lexer / parser มีคำพูดของตัวเองสำหรับสิ่งที่พวกเขาใช้บ่อยๆ สิ่งที่คุณคิดว่าเป็นลำดับของอักขระ / สัญลักษณ์ที่ประกอบเป็นโทเค็นคือสิ่งที่ผู้ที่ใช้ lexer / parsers เรียกว่า lexeme ดังนั้นเมื่อคุณเห็น lexeme ให้นึกถึงลำดับของอักขระ / สัญลักษณ์ที่แสดงถึงโทเค็น ในตัวอย่างการเปรียบเทียบลำดับของอักขระ / สัญลักษณ์อาจเป็นรูปแบบที่แตกต่างกันเช่น<หรือ>หรือelseหรือ3.14เป็นต้น

อีกวิธีหนึ่งในการคิดถึงความสัมพันธ์ระหว่างทั้งสองก็คือโทเค็นเป็นโครงสร้างการเขียนโปรแกรมที่ใช้โดยตัวแยกวิเคราะห์ที่มีคุณสมบัติที่เรียกว่า lexeme ซึ่งเก็บอักขระ / สัญลักษณ์จากอินพุต ตอนนี้ถ้าคุณดูคำจำกัดความของโทเค็นส่วนใหญ่ในโค้ดคุณอาจไม่เห็น lexeme เป็นหนึ่งในคุณสมบัติของโทเค็น เนื่องจากโทเค็นมีแนวโน้มที่จะยึดตำแหน่งเริ่มต้นและจุดสิ้นสุดของอักขระ / สัญลักษณ์ที่แสดงถึงโทเค็นและคำศัพท์ลำดับของอักขระ / สัญลักษณ์สามารถได้รับจากตำแหน่งเริ่มต้นและตำแหน่งสิ้นสุดตามต้องการเนื่องจากอินพุตเป็นแบบคงที่


12
ในการใช้งานคอมไพเลอร์ภาษาผู้คนมักจะใช้สองคำนี้สลับกัน ความแตกต่างที่แม่นยำเป็นสิ่งที่ดีหากคุณต้องการและเมื่อใด
Ira Baxter

แม้ว่าจะไม่ใช่คำจำกัดความของวิทยาศาสตร์คอมพิวเตอร์ แต่เพียงอย่างเดียวนี่คือหนึ่งจากการประมวลผลภาษาธรรมชาติที่มีความเกี่ยวข้องตั้งแต่Introduction to lexical semantics an individual entry in the lexicon
Guy Coder

คำอธิบายที่ชัดเจนแน่นอน นี่คือวิธีที่ควรอธิบายสิ่งต่างๆในสวรรค์
Timur Fayzrakhmanov

คำอธิบายที่ดี ฉันมีข้อสงสัยอีกประการหนึ่งฉันยังอ่านเกี่ยวกับขั้นตอนการแยกวิเคราะห์ตัวแยกวิเคราะห์ขอโทเค็นจากตัววิเคราะห์ศัพท์เนื่องจากตัววิเคราะห์ไม่สามารถตรวจสอบโทเค็นได้ คุณช่วยอธิบายโดยการป้อนข้อมูลง่ายๆในขั้นตอนการแยกวิเคราะห์และเมื่อใดที่ตัวแยกวิเคราะห์จะขอโทเค็นจาก lexer
Prasanna Sasne

@PrasannaSasne can you please explain by taking simple input at parser stage and when does parser asks for tokens from lexer.SO ไม่ใช่ไซต์สนทนา นั่นเป็นคำถามใหม่และจำเป็นต้องถามเป็นคำถามใหม่
Guy Coder

37

เมื่อโปรแกรมต้นทางถูกป้อนเข้าไปในตัววิเคราะห์คำศัพท์โปรแกรมจะเริ่มต้นด้วยการแยกอักขระออกเป็นลำดับของคำศัพท์ จากนั้นคำศัพท์จะถูกใช้ในการสร้างโทเค็นซึ่งมีการแมปคำศัพท์ลงในโทเค็น ตัวแปรที่เรียกว่าmyVarจะถูกแมปลงในโทเค็นที่ระบุ < id , "num"> โดยที่ "num" ควรชี้ไปที่ตำแหน่งของตัวแปรในตารางสัญลักษณ์

ใส่สั้น ๆ :

  • Lexemes เป็นคำที่มาจากสตรีมอินพุตอักขระ
  • โทเค็นคือคำศัพท์ที่แมปเป็นชื่อโทเค็นและแอตทริบิวต์ - ค่า


ตัวอย่างประกอบด้วย:
x = a + b * 2
ซึ่งให้คำศัพท์: {x, =, a, +, b, *, 2}
ด้วยโทเค็นที่เกี่ยวข้อง: {< id , 0>, <=>, < id , 1 >, <+>, < id , 2>, <*>, < id , 3>}


2
ควรจะเป็น <id, 3> หรือไม่? เพราะ 2 ไม่ใช่ตัวระบุ
Aditya

แต่ที่บอกว่า x เป็นตัวระบุ? นั่นหมายความว่าตารางสัญลักษณ์คือตาราง 3 คอลัมน์ที่มี 'name' = x, 'type' = 'identifier (id)', pointer = '0' เป็นรายการเฉพาะหรือไม่ก็ต้องมีรายการอื่นเช่น 'name' = while, 'type' = 'keyword', pointer = '21 '??

8

ก) โทเค็นเป็นชื่อสัญลักษณ์สำหรับเอนทิตีที่ประกอบเป็นข้อความของโปรแกรม เช่นถ้าสำหรับคำหลัก if และ id สำหรับตัวระบุใด ๆ สิ่งเหล่านี้ประกอบเป็นผลลัพธ์ของตัววิเคราะห์คำศัพท์ 5

(b) รูปแบบเป็นกฎที่ระบุว่าเมื่อใดที่ลำดับของอักขระจากอินพุตจะประกอบเป็นโทเค็น เช่นลำดับ i, f สำหรับโทเค็น if และลำดับของตัวอักษรและตัวเลขใด ๆ ที่ขึ้นต้นด้วยตัวอักษรสำหรับรหัสโทเค็น

(c) lexeme คือลำดับของอักขระจากอินพุตที่ตรงกับรูปแบบ (และด้วยเหตุนี้จึงเป็นอินสแตนซ์ของโทเค็น) ตัวอย่างเช่นหากตรงกับรูปแบบสำหรับ if และ foo123bar ตรงกับรูปแบบสำหรับ id


8

LEXEME - ลำดับของอักขระที่จับคู่โดย PATTERN ที่สร้าง TOKEN

รูปแบบ - ชุดของกฎที่กำหนด TOKEN

TOKEN - ชุดอักขระที่มีความหมายเหนือชุดอักขระของภาษาโปรแกรมเช่น ID, ค่าคงที่, คำหลัก, ตัวดำเนินการ, เครื่องหมายวรรคตอน, สตริงตัวอักษร


7

Lexeme - คำศัพท์คือลำดับของอักขระในโปรแกรมต้นทางที่ตรงกับรูปแบบของโทเค็นและถูกระบุโดยตัววิเคราะห์คำศัพท์เป็นตัวอย่างของโทเค็นนั้น

โทเค็น - โทเค็นคือคู่ที่ประกอบด้วยชื่อโทเค็นและค่าโทเค็นที่เป็นทางเลือก ชื่อโทเค็นเป็นหมวดหมู่ของหน่วยศัพท์ชื่อโทเค็นทั่วไปคือ

  • ตัวระบุ: ตั้งชื่อโปรแกรมเมอร์เลือก
  • คำสำคัญ: ชื่อที่มีอยู่แล้วในภาษาโปรแกรม
  • ตัวคั่น (หรือที่เรียกว่าเครื่องหมายวรรคตอน): อักขระเครื่องหมายวรรคตอนและตัวคั่นที่จับคู่
  • ตัวดำเนินการ: สัญลักษณ์ที่ดำเนินการกับอาร์กิวเมนต์และสร้างผลลัพธ์
  • ลิเทอรัล: ตัวเลขตรรกะข้อความตัวอักษรอ้างอิง

พิจารณานิพจน์นี้ในภาษาโปรแกรม C:

ผลรวม = 3 + 2;

Tokenized และแสดงโดยตารางต่อไปนี้:

 Lexeme        Token category
------------------------------
sum      |    Identifier
 =       |    Assignment operator
 3       |    Integer literal
 +       |    Addition operator
 2       |    Integer literal
 ;       |    End of statement

5

มาดูการทำงานของเครื่องวิเคราะห์ศัพท์ (เรียกอีกอย่างว่าเครื่องสแกน)

ลองดูนิพจน์ตัวอย่าง:

INPUT : cout << 3+2+3;

FORMATTING PERFORMED BY SCANNER :  {cout}|space|{<<}|space|{3}{+}{2}{+}{3}{;} 

ไม่ใช่ผลลัพธ์ที่แท้จริง

สแกนเนอร์ที่เรียบง่ายดูซ้ำสำหรับข้อความในโปรแกรมแหล่งข้อมูลจนกว่าอินพุตจะถูกระบายออก

Lexeme เป็นสตริงย่อยของอินพุตที่สร้างสตริง - ออฟ - เทอร์มินัลที่ถูกต้องที่มีอยู่ในไวยากรณ์ คำศัพท์ทุกตัวเป็นไปตามรูปแบบที่อธิบายไว้ในตอนท้าย (ส่วนที่ผู้อ่านอาจข้ามไปในที่สุด)

(กฎที่สำคัญคือการมองหาคำนำหน้าที่ยาวที่สุดที่เป็นไปได้ซึ่งสร้างสตริงของเทอร์มินัลที่ถูกต้องจนกว่าจะพบช่องว่างถัดไป ... อธิบายด้านล่าง)

LEXEMES:

  1. cout
  2. <<

(แม้ว่า "<" จะเป็นเทอร์มินัลสตริงที่ถูกต้อง แต่กฎที่กล่าวถึงข้างต้นจะเลือกรูปแบบสำหรับ lexeme "<<" เพื่อสร้างโทเค็นที่ส่งคืนโดยสแกนเนอร์)

  1. 3
  2. +
  3. 2
  4. ;

TOKENS:โทเค็นจะถูกส่งคืนทีละรายการ (โดยเครื่องสแกนเนอร์เมื่อได้รับการร้องขอจากพาร์เซอร์) ทุกครั้งที่สแกนเนอร์พบคำศัพท์ (ถูกต้อง) สแกนเนอร์จะสร้างรายการตารางสัญลักษณ์หากยังไม่มี(มีแอตทริบิวต์: หมวดโทเค็นส่วนใหญ่และอื่น ๆ อีกไม่กี่รายการ)เมื่อพบคำศัพท์เพื่อสร้างโทเค็น

'#' หมายถึงรายการตารางสัญลักษณ์ ฉันได้ชี้ไปที่หมายเลข lexeme ในรายการด้านบนเพื่อความสะดวกในการทำความเข้าใจ แต่ในทางเทคนิคแล้วควรเป็นดัชนีจริงของการบันทึกในตารางสัญลักษณ์

โทเค็นต่อไปนี้จะถูกส่งคืนโดยสแกนเนอร์เพื่อแยกวิเคราะห์ตามลำดับที่ระบุสำหรับตัวอย่างข้างต้น

  1. <ตัวระบุ # 1>

  2. <ตัวดำเนินการ # 2>

  3. <ตัวอักษร # 3>

  4. <ตัวดำเนินการ # 4>

  5. <ตัวอักษร # 5>

  6. <ตัวดำเนินการ # 4>

  7. <ตัวอักษร # 3>

  8. <เครื่องหมายวรรคตอน # 6>

ดังที่คุณเห็นความแตกต่างโทเค็นเป็นคู่ที่แตกต่างจาก lexeme ซึ่งเป็นสตริงย่อยของอินพุต

และองค์ประกอบแรกของคู่คือโทเค็นคลาส / หมวดหมู่

คลาสโทเค็นแสดงอยู่ด้านล่าง:

  • คีย์เวิร์ด
  • ตัวบ่งชี้
  • วรรณกรรม
  • PUNCTUATORS
  • ผู้ปฏิบัติงาน
  • และอีกอย่างหนึ่งคือ Scanner ตรวจพบช่องว่างไม่สนใจและไม่สร้างโทเค็นใด ๆ สำหรับช่องว่างเลย ตัวคั่นทั้งหมดไม่ใช่ช่องว่างช่องว่างเป็นรูปแบบหนึ่งของตัวคั่นที่สแกนเนอร์ใช้เพื่อจุดประสงค์ Tabs, Newlines, Spaces, Escaped Characters ในอินพุตทั้งหมดเรียกรวมกันว่าตัวคั่นช่องว่าง ตัวคั่นอื่น ๆ อีกไม่กี่ตัวคือ ';' ',' ':' ฯลฯ ซึ่งได้รับการยอมรับอย่างกว้างขวางว่าเป็นคำศัพท์ที่สร้างโทเค็น

    จำนวนโทเค็นทั้งหมดที่ส่งคืนคือ 8 ที่นี่อย่างไรก็ตามมีเพียง 6 รายการตารางสัญลักษณ์เท่านั้นที่สร้างขึ้นสำหรับ lexemes Lexemes มีทั้งหมด 8 (ดูคำจำกัดความของ lexeme)

    --- คุณสามารถข้ามส่วนนี้ได้

    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.`
    

    5

    Lexeme - lexeme คือสตริงของอักขระที่เป็นหน่วยวากยสัมพันธ์ระดับต่ำสุดในภาษาโปรแกรม

    โทเค็น - โทเค็นเป็นหมวดหมู่ไวยากรณ์ที่สร้างคลาสของคำศัพท์ซึ่งหมายความว่าคลาสที่ศัพท์นั้นเป็นของมันคือคีย์เวิร์ดหรือตัวระบุหรือสิ่งอื่นใด งานหลักอย่างหนึ่งของเครื่องวิเคราะห์ศัพท์คือการสร้างคำศัพท์และโทเค็นคู่หนึ่งนั่นคือการรวบรวมอักขระทั้งหมด

    ให้เรายกตัวอย่าง: -

    ถ้า (y <= t)

    y = y-3;

    Lexeme Token

    ถ้า KEYWORD

    (PARENTHESIS ซ้าย

    y IDENTIFIER

    <= การเปรียบเทียบ

    t IDENTIFIER

    ) PARENTHESIS ที่ถูกต้อง

    y IDENTIFIER

    = ASSGNMENT

    y IDENTIFIER

    _ ARITHMATIC

    3 INTEGER

    ;                                    อัฒภาค

    ความสัมพันธ์ระหว่าง Lexeme และ Token

    ความสัมพันธ์ระหว่าง lexeme และ token


    4

    โทเค็น: ชนิดของ (คีย์เวิร์ดตัวระบุอักขระเครื่องหมายวรรคตอนตัวดำเนินการหลายอักขระ) คือโทเค็น

    รูปแบบ: กฎสำหรับการสร้างโทเค็นจากอักขระอินพุต

    Lexeme: ลำดับของอักขระใน SOURCE PROGRAM ที่จับคู่กับรูปแบบของโทเค็น โดยพื้นฐานแล้วมันเป็นองค์ประกอบของ Token


    4

    โทเค็น: โทเค็นคือลำดับของอักขระที่สามารถถือว่าเป็นเอนทิตีตรรกะเดียว โทเค็นทั่วไปคือ
    1) ตัวระบุ
    2) คีย์เวิร์ด
    3) ตัวดำเนินการ
    4) สัญลักษณ์พิเศษ
    5) ค่าคงที่

    รูปแบบ:ชุดของสตริงในอินพุตที่สร้างโทเค็นเดียวกันเป็นเอาต์พุต ชุดของสตริงนี้อธิบายโดยกฎที่เรียกว่ารูปแบบที่เกี่ยวข้องกับโทเค็น
    Lexeme: lexeme คือลำดับของอักขระในโปรแกรมต้นทางที่จับคู่ตามรูปแบบของโทเค็น


    1

    Lexeme Lexemes เป็นลำดับของอักขระ (ตัวเลขและตัวอักษร) ในโทเค็น

    โท เค็นโทเค็นคือลำดับของอักขระที่สามารถระบุได้ว่าเป็นเอนทิตีตรรกะเดียว โดยทั่วไปโทเค็นคือคีย์เวิร์ดตัวระบุค่าคงที่สตริงสัญลักษณ์วรรคตอนตัวดำเนินการ ตัวเลข

    Pattern ชุดของสตริงที่อธิบายโดยกฎที่เรียกว่า pattern รูปแบบอธิบายสิ่งที่สามารถเป็นโทเค็นได้และรูปแบบเหล่านี้ถูกกำหนดโดยใช้นิพจน์ทั่วไปที่เกี่ยวข้องกับโทเค็น


    1

    นักวิจัย CS ซึ่งเป็นผู้ที่มาจาก Math ชอบสร้างคำศัพท์ "ใหม่" คำตอบข้างต้นเป็นสิ่งที่ดี แต่เห็นได้ชัดว่าไม่มีความจำเป็นอย่างยิ่งที่จะต้องแยกแยะโทเค็นและคำศัพท์ IMHO พวกเขาเป็นเหมือนสองวิธีในการแสดงสิ่งเดียวกัน คำศัพท์เป็นคอนกรีต - นี่คือชุดของถ่าน ในทางกลับกันโทเค็นเป็นนามธรรม - โดยปกติจะหมายถึงประเภทของคำศัพท์พร้อมกับค่าความหมายหากมีเหตุผล แค่สองเซ็นต์ของฉัน


    0

    Lexical Analyzer ใช้ลำดับของอักขระเพื่อระบุ lexeme ที่ตรงกับนิพจน์ทั่วไปและจัดหมวดหมู่ให้เป็นโทเค็น ดังนั้น Lexeme จึงถูกจับคู่สตริงและชื่อโทเค็นคือหมวดหมู่ของคำศัพท์นั้น

    ตัวอย่างเช่นพิจารณาด้านล่างนิพจน์ทั่วไปสำหรับตัวระบุที่มีอินพุต "int foo, bar;"

    จดหมาย (ตัวอักษร | หลัก | _) *

    ที่นี่fooและbarตรงกับนิพจน์ทั่วไปดังนั้นจึงเป็นทั้งคำศัพท์ แต่ถูกจัดประเภทเป็นIDตัวระบุโทเค็นหนึ่งตัว

    โปรดทราบว่าขั้นตอนต่อไปคือตัววิเคราะห์ไวยากรณ์ไม่จำเป็นต้องรู้เกี่ยวกับ lexeme แต่เป็นโทเค็น


    -2

    Lexeme เป็นหน่วยของโทเค็นและโดยพื้นฐานแล้วจะเป็นลำดับของอักขระที่ตรงกับโทเค็นและช่วยแบ่งซอร์สโค้ดเป็นโทเค็น

    ตัวอย่างเช่นหากมาเป็นx=bแล้ว lexemes จะx, =, bและโทเค็นจะ<id, 0>, ,<=><id, 1>


    คำตอบควรมีความเฉพาะเจาะจงมากขึ้น ตัวอย่างอาจเป็นประโยชน์
    Zverev Evgeniy
    โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
    Licensed under cc by-sa 3.0 with attribution required.