วันพุธที่ 27 ตุลาคม พ.ศ. 2553

Compiler : คลาส Lexical 2 (ภาษา Java)

กลับมายังคลาส Lexical เพื่อโค้ดให้สำเร็จครับ
(รูปหมายเลข 159)
- โดยปกติแล้วค่าคงที่ใดๆในจาวาจะระบุด้วย final และเขียนด้วยตัวพิมพ์ใหญ่ทั้งหมด ทว่าค่าคงที่ end ยังคงเป็นพิมพ์เล็ก ฉะนั้นโอกาสนี้ผลจึงเสนอวิธีการเปลี่ยนชื่อ โดยมีผลกับทุกส่วนของโค้ดที่มีชื่อนี้อยู่ หรือใช้กับชื่อคลาสหรือชื่อเมธอดก็ได้ครับ
- แดรกเลือกชื่อ ขณะนี้คือ end แล้วคลิกขวาเลือก Refactor ตามด้วยเลือก Rename...

(รูปหมายเลข 160)
- เปลี่ยนจาก end เป็น END แล้วกดปุ่ม Refactor เป็นอันว่าเรียบร้อย

(รูปหมายเลข 161)
- เลื่อนบรรทัดมายังส่วนท้ายสุดของคลาส Lexical แต่ยังอยู่ในขอบเขตของคลาสนะครับ
- บรรทัดที่ 96 และ 97 ประกาศแอตทริบิวต์คลาส SymbolTable และ TokenStream ตามลำดับ
- บรรทัดที่ 99 สร้างเมธอดชื่อ addNewToken โดยมี tokenName และ tokenTypeIndex เป็น Parameters กระบวนการคือเพิ่ม tokenName และ tokenTypeIndex ให้กับ symbolTable
- บรรทัดที่ 101 ขอ tokenNameIndex ผ่านเมธอด getTokenNameIndex ของ symbolTable เพื่อนำไปเพิ่มยัง tokenStream พร้อมกับ tokenTypeIndex

(รูปหมายเลข 162)
- ถัดจากเมธอดชื่อ addNewToken เพิ่มเมธอด getSymbolTable และ getTokenStream เพื่อขอออบเจ็คก์ symbolTable และ tokenStream (บริการนี้จะถูกเรียกอย่างชัดเจนที่เมธอด main ของไฟล์ MainProgram.java)

(รูปหมายเลข 163)
- ถัดจากนั้นเพิ่มเมธอด isWhiteSpacesAndLineTerminators เพื่อกำหนดให้ภาษาของเรายอมรับ White Spaces และ Terminators ครับ

(รูปหมายเลข 164)
- กลับมาที่เมธอด start (ได้สร้างไว้แล้ว) ภายใต้ประโยค isSeparators... ของประโยค if เรียกเมธอด addNewToken เพื่อกำหนดให้ currentChar มีประเภทเป็น Separators
- เช่นเดียวกัน ภายใต้ประโยค isOperators... ของประโยค else if เรียกเมธอด addNewToken เพื่อกำหนดให้ currentChar มีประเภทเป็น Operators

(รูปหมายเลข 165)
- ภายใต้ประโยค isLetter... ของ else if (ยังอยู่ในเมธอด start) เขียนอัลกอริทึมเชื่อมตัวอักษรให้เป็นคำ (สตริง) เก็บไว้กับตัวแปรชื่อ word
- เมื่อได้หนึ่งคำ (หรือ word) จึงนำไปถามต่อว่า คำนี้ใช่ประเภท Keywords หรือไม่ ถ้าใช่ก็เรียกเมธอด addNewToken แล้วกำหนดให้เป็นประเภท Keywords ถ้าไม่ใช่จึงให้เป็นประเภท Identifiers
- สุดท้ายถามว่า currentChar ไม่ใช่ END (คือยังไม่จบ Source Code) ใช่ไหม หากผลลัพธ์เป็น true ให้ลดค่า countOfSourceCode ลงเสียหนึ่ง เพื่อนป้องกันการอ่านข้าม currentChar ตัวปัจจุบันที่หลุดออกจาก while ลูปในอัลกอริทึมครับ

(รูปหมายเลข 166)
- ภายใต้ประโยค isDigit คืออัลกอริทึมตัดตัวเลขจำนวนเต็มและทศนิยม (กรอบสีเขียว)
- การทำงานก็คล้ายกับการตัด Keywords และ Identifiers ที่เพื่อนๆพึ่งสังเกตผ่านมาครับ เพียงแต่ผมใช้ boolean ที่ชื่อ isFloatingPointLiterals ช่วยชี้ว่าควรเป็นจำนวนเต็ม (Integer Literals) หรือทศนิยม (Floating-point Literals) หากพบว่าตัวแปร currentChar มีค่าเป็น '.' (dot) ก็จะเข้าสู่ส่วนที่เป็นทศนิยมทันทีครับ (กรอบสีน้ำตาลเข้ม)
- ภายหลังจึงถามว่าตัวแปร isFloatingPointLiterals มีค่าเป็น ture ให้เป็นจำนวนทศนิยม เมื่อเป็น false ให้เป็นจำนวนเต็ม
- สุดท้ายถามว่า currentChar ไม่ใช่ END (คือยังไม่จบ Source Code) ใช่ไหม หากผลลัพธ์เป็น true ให้ลดค่า countOfSourceCode ลงเสียหนึ่ง เพื่อนป้องกันการอ่านข้าม currentChar ตัวปัจจุบันที่หลุดออกจาก while ลูปในอัลกอริทึมครับ

(รูปหมายเลข 167)
- แทรกโค้ดเหมือนกับในรูปเพื่อให้การตัดคำไม่เกิด error
- ส่วนการทำงานภายในขณะนี้ยังไม่มีครับ ^^ (ก็ยังไม่ได้ใช้ประโยชน์)

(รูปหมายเลข 168)
- เนื่องจากเมธอด start ที่โค้ดเสร็จไปนั้นมี Access Modifier เป็น private ผมจึงตั้งใจให้มันถูกเรียกจากอย่างอื่นภายในคลาส ซึ่งคือ Constructor ของคลาส Lexical นั่นเอง ฉะนั้นเขียนเพิ่มอีกนิดตามรูปครับ

เป็นอันว่าคลาส Lexical ของเราพร้อมตัดคำแล้ว บทความต่อไปเรามาทดสอบกันครับ

อ่านเนื้อหาที่เกี่ยวข้อง ก่อนหน้า หรือ ถัดไป

ไม่มีความคิดเห็น:

แสดงความคิดเห็น