ฉันกำลังเขียนโปรแกรมแยกวิเคราะห์สำหรับภาษามาร์กอัปที่ฉันสร้างขึ้น (เขียนด้วยภาษาไพ ธ อน แต่นั่นไม่เกี่ยวข้องกับคำถามนี้จริง ๆ แล้วถ้านี่เป็นความคิดที่ไม่ดีฉันชอบคำแนะนำสำหรับเส้นทางที่ดีกว่า) .
ฉันกำลังอ่านเกี่ยวกับตัวแยกวิเคราะห์ที่นี่: http://www.ferg.org/parsing/index.htmlและฉันกำลังพยายามเขียน lexer ซึ่งถ้าหากฉันเข้าใจถูกต้องให้แบ่งเนื้อหาออกเป็นโทเค็น สิ่งที่ฉันมีปัญหาในการทำความเข้าใจคือสิ่งที่ฉันควรใช้โทเค็นประเภทใดหรือวิธีการสร้างพวกเขา ตัวอย่างเช่นประเภทโทเค็นในตัวอย่างที่ฉันเชื่อมโยงคือ:
- STRING
- IDENTIFIER
- จำนวน
- ช่องว่าง
- แสดงความคิดเห็น
- EOF
- สัญลักษณ์จำนวนมากเช่น {และ (นับเป็นประเภทโทเค็นของตัวเอง
ปัญหาที่ฉันมีอยู่ก็คือโทเค็นประเภททั่วไปนั้นดูจะเป็นเรื่องที่ฉันไม่ชอบ ตัวอย่างเช่นเหตุใด STRING ถึงมีประเภทโทเค็นแยกต่างหากกับ IDENTIFIER สตริงสามารถแสดงเป็น STRING_START + (IDENTIFIER | WHITESPACE) + STRING_START
สิ่งนี้อาจเกี่ยวข้องกับภาษาของฉันด้วย ยกตัวอย่างเช่นการประกาศตัวแปรถูกเขียนเป็นและนำไปใช้กับ{var-name var value}
{var-name}
ดูเหมือนว่า'{'
และ'}'
ควรจะราชสกุลของตัวเอง แต่มี var_name และ VAR_VALUE ประเภทโทเค็นมีสิทธิ์หรือจะเหล่านี้ทั้งสองตกอยู่ภายใต้การ IDENTIFIER? มีอะไรเพิ่มเติมคือ VAR_VALUE สามารถมีช่องว่างได้จริง ช่องว่างหลังจากvar-name
ถูกใช้เพื่อบ่งบอกถึงการเริ่มต้นของค่าในการประกาศ .. ช่องว่างอื่น ๆ เป็นส่วนหนึ่งของค่า พื้นที่ว่างนี้กลายเป็นโทเค็นของตัวเองหรือไม่ ช่องว่างมีความหมายในบริบทนี้เท่านั้น ยิ่งกว่านั้น{
อาจไม่ใช่จุดเริ่มต้นของการประกาศตัวแปร .. มันขึ้นอยู่กับบริบท (นั่นคือคำนั้นอีกครั้ง!) {:
เริ่มการประกาศชื่อและ{
ยังสามารถใช้เป็นส่วนหนึ่งของค่าบางอย่าง
ภาษาของฉันคล้ายกับ Python ในบล็อกนั้นถูกสร้างขึ้นด้วยการเยื้อง ฉันกำลังอ่านเกี่ยวกับวิธีที่ Python ใช้ lexer เพื่อสร้างโทเค็น INDENT และ DEDENT (ที่ให้บริการมากกว่าหรือน้อยกว่าเป็นสิ่งที่{
และ}
จะทำในภาษาอื่น ๆ มากมาย) Python อ้างว่าปราศจากบริบทซึ่งหมายความว่าอย่างน้อย lexer ไม่ควรสนใจว่ามันอยู่ที่ไหนในกระแสขณะสร้างโทเค็น ตัวเล็กของไพ ธ อนรู้ได้อย่างไรว่ามันสร้างโทเค็น INDENT ที่มีความยาวเฉพาะโดยไม่ทราบเกี่ยวกับอักขระก่อนหน้า (เช่นบรรทัดก่อนหน้าเป็นบรรทัดใหม่ดังนั้นเริ่มสร้างช่องว่างสำหรับ INDENT) ฉันถามเพราะฉันจำเป็นต้องรู้สิ่งนี้ด้วย
คำถามสุดท้ายของฉันคือคำถามที่โง่ที่สุด: เหตุใด lexer ถึงจำเป็น? สำหรับฉันแล้ว parser สามารถไปทีละตัวอักษรและคิดออกว่ามันอยู่ที่ไหนและสิ่งที่คาดหวัง lexer เพิ่มประโยชน์ของความเรียบง่ายหรือไม่?