วิชานี้ อาจารย์ได้มอบหมายให้นักศึกษาทำโปรเจคซึ่งเกี่ยวกับการประมวลผลภาษาโปรแกรม ซึ่งก็คือโปรแกรมแมวไล่จับหนู โดยเป็นโปรแกรมที่ให้เราเขียน code เพื่อสั่งให้แมววิ่งไล่จับหนู แล้วโปรแกรมที่เราเขียนจะประมวลผล code ที่เรา input เข้าไป ไปแสดงผลเป็น animation แมววิ่งไล่จับหนู
รายละเอียดของโปรเจคนี้นั้นถูกแปลมาจากโปรเจคในวิชา CompSci 140, Spring 2012 Mathematical Foundations of CS Assignments ของต่างประเทศอีกทีหนึ่ง ซึ่งต้องขอขอบพระคุณมา ณ ที่นี้ด้วย โดยลิงค์รายละเอียดในการทำโปรเจค(ภาษาอังกฤษ)มีดังนี้
- https://www.cs.duke.edu/courses/spring12/cps140/assign/proj1.pdf
- https://www.cs.duke.edu/courses/spring12/cps140/assign/data/
- https://www.cs.duke.edu/courses/spring12/cps140/assign/proj2all.pdf
- https://www.cs.duke.edu/courses/spring12/cps140/assign/parsedata
- https://www.cs.duke.edu/courses/spring12/cps140/assign/studentdata/
- https://www.cs.duke.edu/courses/spring12/cps140/assign/proj3.pdf
จากลิ้งค์รายละเอียดข้างต้นจะเห็นว่าภายในตัวโปรเจคจะถูกแบ่งเป็น 3 ส่วนคือ
- Scanner
- Parser
- Syntax Tree
โดยรายละเอียดในการเขียนโปรแกรมแสดงผล Animation Mouse Cat แต่จะส่วนนั้นมีดังนี้
1.Scanner
ในส่วนที่ 1 คือการทำ Scanner โดยในรายละเอียดจากเอกสารก็คือการแบ่ง code ที่เรา input เข้ามา ทำการตัด comment ออกให้หมด แล้วแยกออกมาเป็นคำๆ โดยแต่ละคำที่แยกออกมานั้นจะต้องถูกต้องตามกฏเบื้องต้นของโปรแกรมเพื่อที่จะนำไปประมวลผลต่อในส่วนที่ 2 ซึ่งจะแบ่งคำเป็นกลุ่มของ keyword,variable,integer และ symbol
1.ขั้นตอนแรกให้สร้าง Editor ขึ้นมาเพื่อใช้ในการเขียน code และแสดงผล output ในส่วนต่างๆ
ตัวอย่าง editor ที่มีช่องให้ input code และมี แท็บ 4 แท็บเพื่อแสดงผล output ในส่วนต่างๆ และมีปุ่ม compile เพื่อประมวลผลโปรแกรม (ออกแบบโดยใช้ JSwingDesigner/WindowBuilder)2. สร้างคลาสชื่อว่า Token เพื่อเก็บกลุ่มคำที่ถูกประมวลผลในส่วนของ Scanner โดย Object token นี้จะเก็บข้อมูลดังนี้ String fullName(ชื่อเต็ม), shortName(ชื่อย่อ), characterValue(ค่าของ Token เป็น character), intValue (ค่าของ Token เป็น จำนวนเต็ม )

3. สร้างคลาสชื่อว่า Type เพื่อเก็บกลุ่มคำที่ถูกประมวลผลในส่วนของ Scanner โดย Object type นี้จะเก็บข้อมูลดังนี้ type(ประเภท เป็น Integer หรือ Variable), characterValue(ค่าของ Token เป็น character), intValue (ค่าของ Token เป็น จำนวนเต็ม ) ซึ่งคลาส Type นี้จะถูกนำมาใช้ในการแสดงผลข้อมูลในส่วนของ Scanner

4. สร้างคลาสชื่อว่า CheckToken ซึ่งคลาสนี้มีความสำคัญมากๆ เพราะว่าต้องใช้ในการประมวลผล code ที่เรา input เข้ามาเพื่อแสดงผลในส่วนที่ 1 ให้ถูกต้อง
attribute ทั้งหมดของคลาส Tokenizer ซึ่งจะมีค่า attribute ที่สำคัญๆคือ- ArrayList<Token> tokens = new ArrayList<Token>(); ใช้เก็บ Token ที่ประมวลผลได้ (นำไปใช้ต่อใน part 2)
- ArrayList<Type> type = new ArrayList<Type>(); ใช้เก็บ Typr ที่ประมวลผลได้ ซึ่งจะใช้แสดงผลใน part นี้
- private Parser parser; ใช่ใน part ที่ 2
- private static final ArrayList<String> keyWordPattern = new ArrayList<String>(); ใช้เก็บคำสำคัญซึ่งมีทั้งหมด 14 คำได้แก่ begin , halt , cat , mouse , clockwise , move , north , south , east , west , hole , repeat , size , end โดยเหตุผลที่เก็บใส่ ArrayList เพราะว่าเวลาเราเช็คว่า Token นั้นเป็นคำสำคัญหรือไม่ เราสามารถใช้เมธอด contains ของ ArrayList เพื่อใช้ในการค้นหาคำได้ แทนที่จะต้องมาวนลูปค้นหาคำทีละคำ
- private static final String terminatePattern = ";"; คือ Regular Experssion มีความหมายคือ เช็คว่าเป็นเครื่องหมาย ; หรือไม่
- private static final String variablePattern = "([0-9]*[a-zA-Z]+[0-9]*)+"; คือ Regular Experssion มีความหมายคือ เช็คว่าเป็นตัวแปรที่ตั้งชื่อถูกตามกฏหรือไม่ โดยในที่นี้คือ ตัวแปรต้องมีตัวอักษรอย่างน้อยหนึ่งตัว
- private static final String integerPattern = "[0-9]{1,3}"; คือ Regular Experssion มีความหมายคือ เช็คว่าเป็นตัวเลขจำนวนเต็มที่ถูกต้องหรือไม่ โดยในที่นี้คือ ตัวเลขไม่เกิน 3 หลัก
- private static final String integerErrorPattern = "[0-9][0-9][0-9][0-9]+"; คือ Regular Experssion มีความหมายคือ เช็คว่าเป็นตัวเลขจำนวนเต็มที่ผิดหรือไม่
- private static final String symbolErrorPattern = "[^0-9a-zA-Z]+"; คือ Regular Experssion มีความหมายคือ เช็คว่าเป็นตัวแปรที่ผิดหรือไม่
- private static final String semicolonErrorPattern = ".+;"; คือ Regular Experssion มีความหมายคือ เช็คว่าเครื่องหมาย ; อยู่ติดกับตัวอักษรอื่นหรือไม่
- private String output ,warning ,error ใช้เก็บข้อความเพื่อนำกลับไปแสดงผลใน part ที่ 1
5. การทำงานของคลาส CheckToken

ให้ constructor ทำการเพิ่มคำ keyword ลงใน ArrayListที่เก็บ keyword

เมธอด compile ใช้ในการประมวลผลส่วนที่ 1 (Scanner) โดยเริ่มต้น จะทำการ instance variable ต่างๆ และรับ code ที่เป็น input เข้ามาผ่านตัวแปร text เมื่อรับ input มาแล้วจะแยกบรรทัดของ code ต่อโดยใช้ เมธอด splitLine เก็บใส่อาเรย์ของ String หลังจากนั้นจึงวนลูปทีละบรรทัด(บรรทัดที่ 54 ) ในแต่ละบรรทัดของ code ก็จะทำการแยกคำ โดยใช้ StringTokenizer เพื่อแยกคำออกมาเป็นคำๆ เพื่อนำไปประมวลผลโดยใช้เรื่อง Regular Expression
- ใน if แรก(บรรทัดที่ 59)จะทำการประมวลผลว่าคำ(ต่อไปขอเรียกว่า token) นั้นเป็น keyword หรือเครื่องหมาย ; หรือไม่ ถ้าเป็นก็จะเพิ่มใส่ ArrayListToken โดยปกติชื่อย่อของ keyword จะใช้ตัวอักษรตัวแรก แต่ก็มีบางคำที่ไม่ใช่ตัวอักษรตัวแรกคือ size(z) move(o) clockwise(l) end(d) halt(t) จึงต้องมีการเช็ค if เอาไว้

- ใน if อันต่อมา (บรรทัดที่ 74) จะเป็นการประมวลผลว่า token นั้นเป็นตัวเลขหรือไม่ ถ้าเป็นก็จะเก็บใส่ ArrayListToken ชื่อเต็มคือ integer ชื่อย่อ i และมีส่วนที่เพิ่มเติมคือ ต้องเช็คดูว่าเลขจำนวนนั้นถูกเก็บใน ArrayListType หรือยัง ถ้ายังก็จะเพิ่มเข้าไป แต่ถ้ามีแล้วก็จะไม่ทำอะไร
- ใน if อันต่อมา (บรรทัดที่ 83) จะเป็นการประมวลผลว่า token นั้นเป็นตัวแปรหรือไม่ ถ้าเป็นก็จะเก็บใส่ ArrayListType ชื่อเต็มคือ variable ชื่อย่อ v และมีส่วนที่เพิ่มเติมคือ ต้องเช็คดูว่าชื่อตัวแปรนั้นนั้นถูกเก็บใน ArrayListType หรือยัง ถ้ายังก็จะเพิ่มเข้าไป แต่ถ้ามีแล้วก็จะไม่ทำอะไร

- ใน if บรรทัดที่ 91 และ 93 จะเป็นการเช็คว่าเราใส่สัญลักษณ์พิเศษนอกเหนือจากที่โปรแกรมกำหนด (symbl error) หรือ ใส่เครื่องหมาย ; ไม่เว้นวรรคหลังตัวแปรหรือไม่ มิเช่นนั้นก็จะเพิ่มข้อความแจ้งเตือน error
- if บรรทัดที่ 96 คือการเช็คว่าใส่ตัวเลขจำนวนเต็มผิดรูปแบบหรือไม่ ซึ่งส่วนนี้จะไม่ใช่ error แต่จะถูกมองเป็นตัวแปรแทน ซึ่งจะแจ้งเตือน warning
- else คือเช็คว่าเราตั้งชื่อตัวแปรผิดรูปแบบหรือไม่ มิเช่นนั้นจะเพิ่มข้อความ error
- lineOfCode++ เอาไว้ใช้นับบรรทัด เพื่อใช้ในการบอกบรรทัดของ code ที่มีข้อผิดพลาด!!!
- บรรทัดที่ 109 คือการเรียกใช้เมธอดเพื่อประมวลผลในส่วนที่ 2 (Parser)
- บรรทัดที่ 110 111 112 .ใช้ในการจัด format ของข้อความ output เพื่อที่จะเตรียม Return ข้อความ output ไปแสดงผล


ทดสอบ Input Output
ลิ้งค์ไฟล์ทดสอบ https://www.cs.duke.edu/courses/spring12/cps140/assign/data/



จบการทำงานของส่วนที่ 1 (Scanner)
ต่อส่วนที่ 2(Parser)
[…] Part 1 เราได้ส่วนของ Scanner ไปแล้ว […]
ตอบลบ