หล กการและการประมวลภาษาโปรแกรม 1 1....
TRANSCRIPT
เอกสารคำสอน
2301380
หลกการและการประมวลผลภาษาโปรแกรม
Programming Language Principle and Processing
จารโลจน จงสถตยวฒนา
ภาควชาคณตศาสตรและวทยาการคอมพวเตอร
จฬาลงกรณมหาวทยาลย
หลกการและการประมวลภาษาโปรแกรม
i
สารบญ
1. บทนำ ......................................................................................................................................................... 1
1.1 การออกแบบภาษาโปรแกรม ................................................................................................................ 1
1.2 แบบความคดของภาษาโปรแกรม ......................................................................................................... 4
1.3 ขนตอนการประมวลผลสำหรบภาษาโปรแกรม ..................................................................................... 8
2. สแกนเนอร ............................................................................................................................................... 13
2.1 แนวคดในภาษาโปรแกรมทเกยวของกบสแกนเนอร ........................................................................... 13
2.1.1 รปแบบของโทเคน ...................................................................................................................... 13
2.1.2 คำสงวนหรอคำหลก .................................................................................................................... 15
2.1.3 รปแบบของสตรง ........................................................................................................................ 15
2.1.4 การใชตวอกษรตวใหญ/ตวเลก .................................................................................................... 16
2.2 การอธบายรปแบบของโทเคนดวยนพจนปกต .................................................................................... 16
2.3 การสรางออโตมาตาจำกดสำหรบสแกนเนอร ..................................................................................... 18
2.3.1 ออโตมาตาจำกด ......................................................................................................................... 18
2.3.2 การสรางออโตมาตาจำกดจากนพจนปกต ................................................................................... 20
2.4 โปรแกรมสแกนเนอร .......................................................................................................................... 22
2.4.1 การปรบออโตมาตาจำกดเพอสรางสแกนเนอร ............................................................................ 22
2.4.2 โปรแกรมจำลองการทำงานของออโตมาตาจำกดเพอสรางสแกนเนอร ........................................ 24
2.4.3 ตารางสญลกษณ ......................................................................................................................... 26
2.4.4 การสรางสแกนเนอรใหหาคำหลก ............................................................................................... 26
2.4.5 การใชตวอกษรตวใหญ/ตวเลก .................................................................................................... 26
3. ตวแจงสวน (Parser) ................................................................................................................................. 27
3.1 แนวคดในภาษาโปรแกรมทเกยวของกบตวแจงสวน ........................................................................... 27
3.1.1 ลำดบการทำงานในนพจน ........................................................................................................... 27
3.1.2 Dangling else ........................................................................................................................... 28
3.1.3 ตำแหนงของคำหลกในโครงสราง ................................................................................................ 29
3.2 การอธบายภาษาโปรแกรมดวยไวยากรณไมพงบรบท ......................................................................... 30
Programming Language Principles and Processing
ii
3.2.1 ไวยากรณไมพงบรบท .................................................................................................................. 30
3.2.2 ไวยากรณกำกวม ......................................................................................................................... 33
3.2.3 การเขยนไวยากรณเพอบงคบลำดบการทำงานของตวกระทำในนพจน ........................................ 35
3.2.4 การเขยนไวยากรณเพอกำหนดการจบคของ else กบ if ............................................................. 37
3.3 ออโตมาตาพชดาวน ........................................................................................................................... 39
3.4 ขนตอนวธแจงสวนแบบ LL(1) ........................................................................................................... 41
3.4.1 ขนตอนวธจำลองการทำงานของออโตมาตาพชดาวน .................................................................. 42
3.4.2 ขนตอนวธแจงสวนแบบ LL(1) .................................................................................................... 44
3.5 ขนตอนวธแจงสวนแบบ SLR(1) ......................................................................................................... 56
3.5.1 หลกการทำงานของการแจงสวนแบบ LR .................................................................................... 56
3.5.2 ออโตมาตาจำกดของรายการ ...................................................................................................... 58
3.5.3 การสรางตารางการแจงสวนแบบ SLR(1) .................................................................................... 61
3.5.4 ไวยากรณแบบ non-SLR(1) ....................................................................................................... 66
4. ตววเคราะหความหมาย ............................................................................................................................ 73
4.1 แนวคดเกยวกบความหมายในภาษาโปรแกรมทเกยวกบตววเคราะหความหมาย ................................ 73
4.1.1 ชนดของตวแปร .......................................................................................................................... 73
4.1.2 ขอบเขต (scope) ของตวแปร ..................................................................................................... 75
4.2 การกำหนดความสมพนธของความหมายดวยไวยากรณของลกษณะประจำ ....................................... 76
4.2.1 ไวยากรณของลกษณะประจำ ...................................................................................................... 76
4.2.2 การสงคาของลกษณะประจำในตนไมแจงสวนประกอบความหมาย............................................. 77
4.2.3 การอธบายชนดขอมลในโปรแกรมดวยไวยากรณของลกษณะประจำ .......................................... 80
4.3 โปรแกรมตววเคราะหความหมาย ....................................................................................................... 81
4.3.1 โปรแกรมสำหรบลกษณะประจำทสงคาจากบนลงลาง ................................................................ 81
4.3.2 โปรแกรมสำหรบลกษณะประจำทสงคาจากลางขนบน ................................................................ 82
4.3.3 โปรแกรมสำหรบลกษณะประจำทสงคาจากซายไปขวา ............................................................... 83
4.3.4 โปรแกรมสำหรบลกษณะประจำทสงคาแบบผสม ........................................................................ 84
5. ตวกอกำเนดรหส ...................................................................................................................................... 89
5.1 รหสกลาง ........................................................................................................................................... 89
หลกการและการประมวลภาษาโปรแกรม
iii
5.1.1 P-code ...................................................................................................................................... 90
5.1.2 3-address Code ....................................................................................................................... 96
5.2 ไวยากรณลกษณะประจำกำหนดการลำดบการทำงาน ..................................................................... 100
5.2.1 ไวยากรณลกษณะประจำทสราง P-code .................................................................................. 100
5.2.2 ไวยากรณลกษณะประจำทสราง 3-address code .................................................................. 105
5.3 ชนดขอมลและไวยากรณลกษณะประจำสำหรบเขาถงขอมลชนดตางๆ ............................................ 111
5.3.1 การสรางรหสกลางคำนวณเลขทอยของขอมลในตวแปรแถวลำดบ ............................................ 112
5.3.2 การสรางรหสกลางคำนวณเลขทอยของขอมลในตวแปรแบบระเบยน ....................................... 115
6. สภาพแวดลอมเวลาดำเนนงาน ............................................................................................................... 118
6.1 ชนดของตวแปรในภาษาโปรแกรม ................................................................................................... 118
6.1.1 ตวแปรแบบสถต (static variable) ......................................................................................... 118
6.1.2 ตวแปรในสแตคแบบพลวต (stack-dynamic variable) .......................................................... 118
6.1.3 ตวแปรในฮปแบบกำหนดชดแจง (explicit heap dynamic variable) ................................... 119
6.1.4 ตวแปรในฮปแบบกำหนดโดยปรยาย (implicit heap dynamic variable) ............................. 119
6.2 การจดหนวยความจำสำหรบตวแปร ................................................................................................. 120
6.2.1 การจดเกบตวแปรแบบสถต ...................................................................................................... 120
6.2.2 การจดเกบตวแปรในสแตคแบบพลวต ....................................................................................... 121
6.2.3 การจดเกบตวแปรในฮป ............................................................................................................ 122
6.3 คำสงทใชจดการสแตคการเรยกและเลขทอยของตวแปรเฉพาะท ..................................................... 122
6.3.1 คำสงจดการเรยกฟงกชนและกลบจากฟงกชน .......................................................................... 123
6.3.2 การคำนวณเลขทอยของตวแปรในฟงกชน ................................................................................ 125
7. สรป ........................................................................................................................................................ 128
Programming Language Principles and Processing
iv
หลกการและการประมวลภาษาโปรแกรม
v
คำนำ
ภาษาโปรแกรมและการการประมวลภาษาโปรแกรมเปนพ นฐานทสำคญสวนหนงของวทยาการคอมพวเตอร ขนตอนวธทใชในการประมวลภาษาโปรแกรมยงใชในการประมวลผลขอมลทเปนพนฐานในงานประยกตหลายดาน การประมวลขอความ (text processing) ใชสแกนเนอรเพอแยกคำและใชหลกการแจงสวนเพอหาความสมพนธระหวางคำ การรวบรวมขอมลเวบ (web crawling) ใชหลกการแจงสวนเพอระบความสมพนธระหวางขอมลในเวบ
ผออกแบบภาษาโปรแกรมตองการใหมนษยอานโปรแกรมไดงาย อยางไรกตาม การประมวลภาษาโปรแกรมมความสมพนธกบการออกแบบภาษาโปรแกรมอยางมาก ลกษณะหลายอยางของภาษาโปรแกรมเปนผลจากขนตอนวธทใชในการประมวลผลภาษาโปรแกรม ดงนนความรเกยวกบการประมวลภาษาโปรแกรมยงชวยใหสามารถเขาใจความหมายของภาษาโปรแกรมไดดขน
รายวชานอธบายขนตอนวธท ใชในการประมวลผลภาษาโปรแกรมโดยเชอมโยงกบการออกแบบลกษณะของภาษาโปรแกรม ความเขาใจเกยวกบความสมพนธนชวยใหเขาใจแนวคดใหม ๆ ในภาษาโปรแกรมไดอยางลกซง
หากผอานพบขอผดพลาดในเอกสารน กรณาแจงทางอเมล [email protected] เพอการปรบปรงเอกสารตอไป
จารโลจน จงสถตยวฒนา
Programming Language Principles and Processing
vi
หลกการและการประมวลภาษาโปรแกรม
1
1. บทนำ
ในประวตศาสตรคอมพวเตอรทผานมามภาษาโปรแกรมทใชกนเปนจำนวนมาก ความนยมใชภาษาโปรแกรมขนกบปจจยหลายดาน ภาษาทออกแบบมาเหมาะสมเปนปจจยหนงทมผลตอความนยม นอกจากนนเครองมอชวยพฒนาโปรแกรมสำหรบภาษานนยงมผลตอความนยมดวย หากมตวแปลภาษาใหใชไดบนเครองคอมพวเตอรทใชตวประมวลผลกลาง (CPU) ตางๆกนและใชไดบนระบบปฏบตการ (operating system) หลายระบบโปรแกรมเมอรจะเลอกใชภาษาโปรแกรมนนมากขน แหลงขอมลสำหรบการเรยนรภาษากเปนปจจยอกขอหนงททำใหโปรแกรมเมอรเลอกใชภาษานน ในบทนเราจะพจารณาการออกแบบภาษาทด แบบความคด (paradigms) ของภาษาโปรแกรม และ ข นตอนการประมวลผลสำหร บภาษาโปรแกรม (programming language processing)
1.1 การออกแบบภาษาโปรแกรม
ในหวขอนเราจะพจารณาการออกแบบภาษาทดคอใหใชงาย ซงรวมถง อานงาย (readability) เขยนงาย (writability) และเชอถอได (reliability) ภาษาโปรแกรมทอานงายหมายถงภาษาททำใหเขยนโปรแกรมแลวอานเขาใจไดงายสำหรบทงผเขยนโปรแกรมเองและผทมาอานโปรแกรมภายหลง โปรแกรมทอานเขาใจไดงายมความสำคญในการพฒนาโปรแกรมเนองจากโปรแกรมทเขยนดวยคนหนงยงตองมโปรแกรมเมอรคนอนมาอานโปรแกรมนนเพอแกไขปรบปรงในภายหลงหรอผทเขยนโปรแกรมทเกยวของในทมเดยวกนอาจตองอานโปรแกรมนนเพ อเขยนโปรแกรมสวนอ นใหทำงานรวมกนไดถกตอง ดงนนภาษาโปรแกรมทดควรทำใหโปรแกรมอานแลวเขาใจไดงาย
ภาษาโปรแกรมทเขยนงายทำใหโปรแกรมเมอรใชความพยายามไมมากในการเรยนรภาษาและการใชภาษานนเขยนโปรแกรม ภาษาบางภาษาใชเวลาเรยนภาษาไมนาน แตอาจใชเวลาในการเขยนโปรแกรมดวยภาษานนนานกวาเมอใชภาษาอน ภาษาระดบตำ (low-level language) เชน ภาษาแอสเซมบล (assembly language) มคำสงนอย จงทำใหเรยนภาษาไดเรว แตเมอเขยนโปรแกรมดวยภาษาแอสเซมบลจะใชเวลามากกวาภาษาระดบสง (high-level language) ดงนนภาษาแอสเซมบลจงไมเปนภาษาทเขยนงาย
ภาษาโปรแกรมบางภาษาทำใหโปรแกรมเกดความผดพลาดไดนอย เรมตงแตโปรแกรมเมอรเขยนโปรแกรมแลวมโอกาสผดพลาดนอย ในลำดบตอมาตวประมวลภาษากตรวจสอบแลวแจงขอผดพลาดเพอใหโปรแกรมเมอรแกไขได นอกจากนนแลวโปรแกรมจะมขอผดพลาดจากกรณทไมได คาดคดไดนอย ภาษาทออกแบบใหมโอกาสผดพลาดนอยถอวามความเชอถอไดสง
ลกษณะเฉพาะ (characteristics) ของภาษาโปรแกรมทำใหภาษาใชยาก-งายตางกน ในทนเราจะพจารณาลกษณะเฉพาะตอไปน คอ ความเรยบงาย (simplicity) ความไมข นตอกนขององคประกอบยอย (orthogonality) ชนดขอมล (data type) ท ม ในภาษา ไวยากรณ (syntax) ของภาษา การแยกระดบความหมาย (abstraction) ในภาษาการแสดงออก (expressivity) ดวยภาษา การตรวจสอบชนดขอมล (type checking) การจดการเมอเกดกรณไมปกต (exception handling) การใช alias
Programming Language Principles and Processing
2
ความเรยบงาย
ความเรยบงายของภาษาเกดจากการเลอกความคดหลกและโครงสรางในภาษาใหเหมาะสมตามความจำเปน หากความคดหลกของภาษามนอยและความคดหลกเหลานไมขดแยงกน โปรแกรมเมอรสามารถเรยนรภาษาไดงายเพราะมมจำนวนแนวคดทตองเรยนรไมมากและแนวคดจากสถานการณหนงสามารถนำไปใชในสถานการณอน ๆ ได ตวอยาง เชน ในภาษาโปรแกรม เชน ภาษาซ ภาษาจาวา ภาษาไพธอน มแนวความคดของบลอก (block) แนวความคดนสามารถนำไปใชไดในโครงสราง if, while, for และ function โดยไมขดแยงกน เมอแนวคดหลกในภาษามจำนวนนอย โปรแกรมเมอรสามารถเรยนรภาษาไดเรว หากเปรยบเทยบภาษาซกบภาษาจาวา ภาษาจาวาม แนวคดเชงวตถเพมมาทำใหเรยนรไดชากวาภาษาซ แตการใชวตถในโปรแกรมทำใหโปรแกรมเมอรทำงานไดงายขน ดงนนผออกแบบภาษาควรเลอกแนวคดหลกสำหรบภาษาหนงใหเหมาะกบการใชงาน
ผออกแบบภาษาควรเลอกโครงสรางทจำเปนในการทำงานของโปรแกรมเมอรโดยไมใหเกนความจำเปน ตวอยาง เชน ภาษาซมตวกระทำ ++ แต x++ อาจเขยนแทนดวย x=x+1 ได ดงนนจงไมจำเปนตองมตวกระทำ ++ เนองจากถาภาษามโครงสรางทตองเรยนรเปนจำนวนมากโปรแกรมเมอรจะเรยนภาษาไดชา นอกจากนนโปรแกรมเมอรจะเลอกใชโครงสรางทตนเองถนดและไมเลอกใชบางโครงสรางได ดงนนเมอโปรแกรมเมอรอานโปรแกรมทผ อนเขยนไว อาจพบโครงสรางทตนเองไมคนเคยและทำความเขาใจไดชา ในทางตรงขาม ภาษาทมสวนประกอบพนฐานนอยทำใหโปรแกรมเมอรเลอกใชโครงสรางไดจำกด ดงนนเมอโปรแกรมเมอรอนมาอานโปรแกรมกจะพบโครงสรางทใชคลาย ๆ กนไดมาก แตโครงสรางทตางกนแตละแบบอาจทำใหโปรแกรมเมอรเลอกใชอธบายการทำงานไดเหมาะสมในกรณทตางกน ตวอยาง เชน โครงสราง while ในภาษาโปรแกรมกเพยงพอทจะทดแทนโครงสราง for แตเมอตองการอธบายการทำงานกบคาในตวแปรแถวลำดบ (array) ทละคาเรยงตามลำดบ โครงสราง for ใชสอความหมายไดชดเจนกวา ดงนนผออกแบบภาษาโปรแกรมตองพจารณาความเหมาะสมดวย
นนคอภาษาทเรยบงายจะทำใหโปรแกรมอานงายและเขยนงายแตหากจำกดใหภาษาเรยบงายเกนไปกจะทำใหเขยนโปรแกรมยาก สดทายความเรยบงายของภาษายงทำใหโปรแกรมนาเชอถอมากขน เนองจากภาษาทอานงายและเขยนงายทำใหเกดความผดพลาดนอยและหาขอผดพลาดงาย
ความไมขนตอกนขององคประกอบยอย
เนองจากภาษาโปรแกรมมองคประกอบหลายชนซงอาจไมเกยวของกน การนำองคประกอบเหลานมาประกอบกนในโปรแกรมไดโดยไมขนกบองคประกอบขางเคยงทำใหอานโปรแกรมไดงาย เชน ตวกระทำ + และ * สามารถใชกบตวแปร คาคงท หรอ นพจนซงเปนจำนวนเตมหรอจำนวนจรงกได นนคอความหมายของตวกระทำ + และ * ไมขนกบองคประกอบขางเคยงวาเปนตวแปรหรอคาคงทหรอนพจนและไมขนกบวาเปนจำนวนเตมหรอจำนวนจรง การทความหมายขององคประกอบหนงในภาษาไมขนกบองคประกอบขางเคยงเรยกวาม orthogonality ซงทำใหอานโปรแกรมไดงาย แตหากนำไปใชในบางสถานการณกอาจทำใหสบสน เชน ในภาษาไพธอน ตวกระทำ + ใชกบสตรงไดโดยหมายถงการนำสตรงมาเชอมตอกน (concatenation) ตว
หลกการและการประมวลภาษาโปรแกรม
3
กระทำ * ใชกบสตรงโดยหมายถงการนำสตรงนนมาเชอมตอกนหลาย ๆ ครง แตในกรณนตวถกกระทำตวหนงเปนสตรงและอกตวหนงเปนจำนวนเตมเพอระบวานำสตรงนนมาตอกนกครง
หากองคประกอบยอยในภาษามความหมายเปนอสระตอกนโปรแกรมเมอรจะเรยนภาษาไดงายทำใหการอานและเขยนโปรแกรมงายไปดวย แตการออกแบบใหองคประกอบยอยไมขนตอกนอาจขดกบปจจยอน เชน การใช * กบจำนวน และการใช * กบสตรงในภาษาไพธอน ทำใหความหมายของตวกระทำ * ขนอยกบตวถกกระทำในทน นดวย แตการใชสญลกษณเดยวกนสำหรบการคณจำนวนและการตอซำสตรง มขอดคอโปรแกรมเมอรคนเคยกบความหมายของการคณจำนวนทางคณตศาสตรอยแลว การตอซำสตรงกใชสญลกษณเดยวกนกบการคณจำนวน คอ • (เชน x•y) หรอ เขยนตวแปรตอกบไป (เชน xy) ดงนนการเลอกใชสญลกษณเดยวกนกบตวกระทำการคณจำนวนกสอความหมายกบโปรแกรมเมอรไดด
ชนดขอมลทมในภาษา
หากภาษาโปรแกรมมชนดของขอมลทเหมาะสมใหโปรแกรมเมอรเลอกใชจะทำให โปรแกรมเขาใจไดงาย อยางไรกตาม งานประเภทตาง ๆ กนตองการชนดของขอมลทตางกน เชน งานทางคณตศาสตรอาจตองการใชขอมลทเปนจำนวนเชงซอน (complex number) แตงานทางธนาคารอาจตองการใชขอมลทเปนวนเวลา ชนดขอมลทเหมาะสมทำใหภาษาอานงายและเขยนงาย
ไวยากรณของภาษา
ปจจยอกประการหน งในการออกแบบท ทำใหภาษาโปรแกรมอานงายคอการใชร ปแบบท สอความหมายไดชดเจน ดงน นภาษาโปรแกรมสวนใหญจะใชร ปแบบท มาจากภาษาองกฤษหรอภาษาคณตศาสตรทคนสวนใหญเขาใจกนดอยแลว เชน การเลอกคำทมความหมายในภาษาองกฤษ (ไดแก if, while, for เปนตน) เปนคำสงในภาษาโปรแกรม การใชสญลกษณทางคณตศาสตร (ไดแก +, -, *, /, >, < เปนตน) สำหรบตวกระทำในภาษาโปรแกรม แตในกรณทสญลกษณทางคณตศาสตรนนไมอยในชดตวอกขระทใชกนทวไปในภาษาโปรแกรมผออกแบบภาษาในยคแรก ๆ จงเลอกใชตวอกขระ 2 ตวรวมกน เชน >=, <=, != ในทางตรงขาม สญลกษณทางคณตศาสตรบางตวใชในหลายความหมายซงนกคณตศาสตรสามารถเลอกตความหมายตามบรบท เชน + อาจหมายถงการบวกจำนวน 2 จำนวนหรอการเชอมสตรง 2 สตรงหรอการบวกเวคเตอร เปนตน แตเมอนำมาใชในภาษาโปรแกรมอาจทำใหผอานสบสนได
การแยกระดบความหมาย (abstraction) ในภาษา
การแยกระดบความหมายในภาษาใชสรางสวนของโปรแกรมในระดบความหมายทสงขนเพอซอนรายละเอยด เชน การสรางฟงกชนเพอใหผใชเรยกใชไดโดยไมตองสนใจการทำงานภายในฟงกชน แตระบขอมลเขาใหถกตองและนำผลลพธทสงจากฟงกชนมาใชได ภาษาเชงวตถแยกระดบความหมายดวยโครงสรางของคลาสดวยอกมตหนง การแยกระดบความหมายทำใหอานและเขยนโปรแกรมไดงายขนเพราะสามารถเขยนและทำความเขาใจกบโปรแกรมในระดบตาง ๆ กนไดตามตองการ นอกจากนนยงทำใหตรวจสอบความถกตองของโปรแกรมทละสวนไดงายขน ดงนนจงทำใหภาษาอานงาย เขยนงายและเชอถอได
การแสดงออก (Expressivity) ดวยภาษา
Programming Language Principles and Processing
4
ภาษาทแสดงออกไดด จะทำใหอธบายการทำงานทซบซอนไดงาย คำสง โครงสรางการโปรแกรม และ ชนดขอมลทเหมาะสมกบงานชวยใหอธบายการทำงานไดงาย เชน คำสง for ... in ... ในภาษาไพธอนอธบายการทำงานกบขอมลแตละตวในโครงสรางไดงาย โครงสราง dictionary ในภาษาไพธอนทำใหอธบายการหาคาในตาราง (table lookup) ไดงาย ดงนนจงทำใหเขยนโปรแกรมไดเรว
การตรวจสอบชนดขอมล (type checking)
ภาษาโปรแกรมมขอมลชนดตาง ๆ มตวแปรทใชเกบขอมล และ มตวกระทำหรอโครงสรางการโปรแกรมทตองใชกบขอมลทกำหนดเทานน ดงนนการตรวจสอบชนดขอมลทใชใหถกตองจงเปนการตรวจสอบความถกตองระดบงายแบบหนงซงทำใหภาษาเชอถอไดมากขน ภาษาโปรแกรมทบงค บใหใชขอมลตรงตามชนดทกำหนดโดยไมยอมเปลยนขอมลใหอตโนมต เรยกวา ภาษาทบงคบชนดอยางเขม ( strongly-typed language) ภาษาโปรแกรมทยอมแปลงชนดขอมลใหตรงตามทตวกระทำหรอโครงสรางโปรแกรมกำหนดไวเรยกวาเปนภาษาทบงคบชนดอยางออน (weakly-typed language) ภาษาซเปนภาษาทบงคบชนดอยางออนซงยอมใหเปลยนขอมลชนดจำนวนเตมใหเปนชนดจำนวนจรงได ภาษาทบงคบชนดอยางเขมจะตรวจสอบชนดขอมลและพบขอผดพลาดของโปรแกรมเมอรไดมากกวา ภาษาทบงคบชนดอยางออนจะยอมใหเปลยนชนดขอมลโดยโปรแกรมเมอรไมตองระบจ งอาจเกดขอผดพลาดไดมากกวา อยางไรกตามการบงคบใหโปรแกรมเมอรระบการเปลยนชนดกทำใหเขยนโปรแกรมยากขน
การจดการเมอเกดกรณไมปกต (exception handling)
การจดการเมอเกดกรณไมปกตเปนสวนประกอบของภาษาโปรแกรมทสรางขนเพอจ ดการกบความผดพลาดทเกดระหวางทำงาน (runtime error) ซงชวยใหภาษาเชอถอไดมากขน
การใช alias
aliasing คอการใชชอมากกวาหนงชออางถงหนวยความจำทเดยวกน เชน การใชตวช (pointer) ชไปทตวแปรซงทำใหสามารถเปลยนคาตวแปรโดยอางถงชอตวแปรหรอผานตวช การใช aliase เชนนทำใหโปรแกรมอานยากเนองจากตองดทงชอตวแปรและไปตวชเพอหาการเปลยนคาของตวแปรนน นอกจากนนยงทำใหเกดขอผดพลาดไดงาย คอ ความเชอถอไดลดลง
1.2 แบบความคดของภาษาโปรแกรม
ภาษาโปรแกรมทใชในปจจบนมสวนประกอบพนฐานทเหมอนกน คอ ตวแปรซงเปนทเกบคาและอาจเปลยนคาทเกบในตวแปรได ความแตกตางทเปนหลกใหญระหวางภาษาโปรแกรมเปนผลจากแนวความคดวาการทำงานของโปรแกรมคออะไร ดงนนสวนประกอบพนฐานในภาษาตองรองรบแนวคดของการทำงานเชนนน ในทนเราจะกลาวถงแบบความคดของภาษาโปรแกรม 3 แบบทแตกตางกนอยางมาก คอ การโปรแกรมเชงคำส ง ( imperative programming) การโปรแกรมเช งประกาศ (declarative programming) และการโปรแกรมเชงฟงกชน (functional programming)
หลกการและการประมวลภาษาโปรแกรม
5
การโปรแกรมเชงคำสง
สำหรบการโปรแกรมเชงคำสง การทำงานของโปรแกรมเปนการจดลำดบของคำสงทมการเขยนและอานคาของตวแปร ดงนนสวนประกอบพนฐานของภาษาทใชในการโปรแกรมเชงคำสงตองสามารถกำหนดลำดบกอนหลงของคำสงทตองทำงาน ลำดบของการทำงานสามารถขนกบคาของตวแปรดวย ดงนนโปรแกรมอาจทำงานตางกนเมอตวแปรมคาตางกน สำหรบภาษาโปรแกรมเชงคำสงทใชกนในปจจบน สวนประกอบทใชกำหนดลำดบการทำงานของคำสง ไดแก
- การทำงานเรยงตามลำดบคำสงทเขยนจากบนลงลาง - การทำงานแบบทางเลอกโดยใชโครงสรางทางเลอก เชน คำสง if และคำสง switch - การทำงานแบบวนซำโดยใชโครงสรางวนซำ เชน โครงสราง while และ โครงสราง for - การโดดไปทำงานยอยใหเสรจแลวกลบมาทำงานทคางไวตอ เชน การเรยกใชโปรแกรมยอย
(subroutine call)
ภาษาโปรแกรมสวนใหญทใชกนในปจจบนใชการโปรแกรมเชงคำสง เชน ภาษาซ (C) ภาษาปาสคาล (Pascal) ภาษาฟอรแทรน (FORTRAN) ภาษาจาวา (Java) ภาษาไพธอน (Python) เปนตน
การโปรแกรมเชงประกาศ
สำหรบการโปรแกรมเชงประกาศ การทำงานของโปรแกรมเปนการหาคาของตวแปรททำใหนยามทงหมดทประกาศในโปรแกรมเปนจรง โปรแกรมแบบนไมตองระบลำดบการทำงานของคำสงในโปรแกรม แตตวประมวลภาษาจะหาลำดบการทำงานเพอใหไดคำตอบทตองการจากนยามในโปรแกรม ภาษาโปรแกรมเชงประกาศประกอบดวยส งทระบไวกอนวาเปนจรงและกฎทระบวา สำหรบตวแปรชดทกำหนด ถาสมบตบางอยางของตวแปรชดนเปนจรงแลวเราสามารถสรปสมบตอนของตวแปรบางตวในชดนไดดวย เชน สำหรบตวแปร n ถาเศษของการหาร n ดวย 2 เปนศนยแลว เราสรปไดวา n เปนจำนวนค เราจะยกตวอยางภาษาโปรลอก (Prolog) ทเปนภาษาโปรแกรมเชงประกาศและแสดงตวอยางโปรแกรมในภาษาน
ภาษาโปรลอกระบกฎ (Q and R) → P ดงน
P :- Q, R. และระบวา P เปนจรงดงน
P. โปรแกรมตอไปนใชเพอทดสอบวาจำนวนเตมทระบเปนจำนวนคหรอไม
even(N) :- remainder(N, 2, 0). remainder(M, M, 0). remainder(M, N, M) :- M>=0, M<N. remainder(M, N, R) :- M>0, M>N, remainder(M-N, N, R).
Programming Language Principles and Processing
6
โปรแกรมขางบนน even(N) เปนประพจนทเปนจรงเมอ N เปนจำนวนค ถาเราตองการถามวา 8 เปนจำนวนคหรอไม เราจะถามดวย
:- even(8).
remainder(M, N, R) เปนประพจนทใช ประกอบเพอตดสนวาจำนวนทระบเปนจำนวนคหรอไม โดย remainder(M, N, R) เปนจรงเมอ R เปนเศษของการหาร M ดวย N ดงนนเราสามารถนยามไดวาถาเศษของการหาร N ดวย 2 เปน 0 แลว N เปนจำนวนค ดงแสดงในบรรทดท 1 ของโปรแกรม บรรทดท 2-4 เปนนยามทใชในการเศษของการหาร บรรทดท 2 ระบวาเศษของการหารจำนวนใดใดดวยตวมนเองเปน 0 บรรทดท 3 ระบวาเศษของการหาร M ดวย N เปน M ถา M ไมเปนจำนวนลบและ M<N บรรทดท 4 ระบวาเศษของการหาร M ดวย N เทากบเศษของการหาร M-N ดวย N ถา M>0 และ M>N โปรแกรมนไมไดระบลำดบการทำงานเพอทดสอบวา N เปนจำนวนคหรอไม แตบอกวาจำนวนจำนวนหนงเปนจำนวนค ถา จำนวนนนหาร 2 ไดลงตว ดงนนตวประมวลภาษาตองไปหาคำตอบวาเสรจของการหารจำนวนทระบเปน 0 หรอไม
จากโปรแกรมในตวอยางน เมอถาม :- even(8). จากกฎในบรรทดท 2 ตวประมวลภาษาจะตองหาคำตอบของ remainder(8, 2, 0) มากอน ดงนนจงตองใชกฎ ในบรรทดท 4 เพอหาคำตอบของ remainder(4, 2, 0) และ remainder(2, 2, 0) ตามลำดบ จากนนดวยกฎในบรรทดท 2 จะไดวา remainder(2, 2, 0) เปนจรง ดงนนจงสรปไดวา remainder (4, 2, 0) และ remainder (8, 2, 0) เปนจรงดวยตามลำดบสดทายสรปไดวา even(8) เปนจรงไปดวย
ทำนองเดยวกน เมอถาม :- even(7). จากกฎในบรรทดท 2 ตวประมวลภาษาจะตองหาคำตอบของ remainder(7, 2, 0) มากอน ดงนนจงตองใชกฎ ในบรรทดท 4 เพอหาคำตอบของ remainder(5, 2, 0) และ remainder(3, 2, 0) ตามลำดบ จากนนดวยกฎในบรรทดท 2,3,4 เราสรปไมไดวา remainder(1, 2, 0) เปนจรง ดงนนจงสรปไมไดวา remainder (3, 2, 0), remainder (5, 2, 0) และ remainder (7, 2, 0) เปนจรงดวยตามลำดบ สดทายจงสรปไมไดวา even(7) เปนจรงไป นนคอ even(7) เปนเทจ
จากตวอยางนเหนไดชดวาโปรแกรมใหนยามของจำนวนคและเศษของการหาร แตไมไดกำหนดลำดบการทำงานเพอทดสอบจำนวนคหรอหาเศษของการหาร ดงนนตวประมวลภาษาจะใชนยามทกำหนดไวในโปรแกรมและจดลำดบการทำงานเอง
การโปรแกรมเชงฟงกชน
สำหรบการโปรแกรมเชงฟงกชน โปรแกรมคอฟงกชนทสรางจากการนำฟงกชนมาทำงานดวยก น ลำดบการทำงานในโปรแกรมเชงฟงกชนขนกบการประกอบฟงกชนเปนโปรแกรม แนวคดของโปรแกรมเชงฟงกชนมพนฐานจากฟงกชนทางคณตศาสตรและมฟงกชนเปนวตถหลก ดงนน ฟงกชนเปนการสงคา (map) ในโดเมน (domain) ไปยงคาในเรนจ (range) โดเมนและเรนจอาจเปนเซตของคาพนฐาน (เชน เซตของจำนวนเตม) หรอ เซตของทเปล n คา (n-tuple) หรอ อาจเปนเซตของฟงกชนกได ในทน เราจะยกตวอยางการโปรแกรมเชงฟงกชนจากภาษาไพธอน
หลกการและการประมวลภาษาโปรแกรม
7
ในภาษาโปรแกรมเชงฟงกชน การสรางฟงกชนใหมทำไดโดยใชการประกอบฟงกชน (function composition) ฟงกชนเงอนไข (condition function) หรอฟงกชนใหทำงานกบทกตว (Apply-all function) เปนตน
การประกอบฟงกชน f และ g เขยนแทนดวย f g(x) หมายถง f(g(x)) ตวอยาง เชน ถาให add(x, y) เปนฟงกชนทสงคาจาก (x, y) ไปยงผลบวกของ x และ y และ mul(x, y) เปนฟงกชนทสงคาจาก (x, y) ไปยงผลคณของ x และ y การประกอบฟงกชน add และ mul ดงน add mul (x, y, z) = add(mul(x, y),z) ไดเปนฟงกชนทสงคา x, y, z ไปยงผลบวกของผลคณของ x และ y กบ z การประกอบฟงกชน add ดงน add add (x, y, z) = add(add(x, y),z) เปนฟงกชนท สงคา x, y, z ไปยงผลบวกของ x, y และ z การประกอบฟงกชนมใชในภาษาโปรแกรมระดบสงเกอบทกภาษา เชน ภาษาซ ภาษาจาวา เปนตน
ฟงกชนเงอนไขมกใชชอ if หรอ cond โดย if(c, a, b) จะสงคา c, a, b ไปยง a เมอ c เปนจรง และไปยง b เมอ c เปนเทจ จากฟงกชน mul ทกลาวไปแลว if(x>=0, x, mul(x, -1)) เปนฟงกชนทใหคาสมบรณของ x ฟงกชนเงอนไขคลายกบคำสง if ในภาษาเชงคำสง
ฟงกชนใหทำงานกบทกตวมกใชช อ apply-all หรอ map apply-all(f, x) จะใหคาในโครงสรางเกยวกบ x โดยแตละคาในโครงสรางเปน f(a) สำหรบคา a ใน x ในภาษาไพธอนมฟงกชน map ททำงานเชนนดวย ตวอยาง เชน map(abs, [1, -2, 3, -4, 5]) ใหตวทำซำ (iterator) ทใหคาทไดจากการใชฟงกชน abs กบคาแตละคาในลสต คอ 1, 2, 3, 4, 5 และ map(pow, [-1, 2, 3], [2, 1, 2]) ใหตวทำซำ (iterator) ทใหคาทไดจากการใชฟงกชน pow กบคของคาจากลสต 2 ลสต คอ (-1)2, 21, 32
นอกจากนน ในภาษาโปรแกรมเชงฟงกชนยงใหสรางฟงกชนและสงฟงกชนไปใหฟงกชนอนใชไดดวย ภาษาไพธอนยอมใหสงฟงกชนเปนพารามเตอรใหฟงกชนอน ตวอยางนแสดงฟงกชน integrate รบฟงกชน fและคา a, b แลวคำนวณหาผลรวมของ f(x) เมอ x มคาตงแต a ถง b ในตวอยางน ถาให p เปนฟงกชน 3x2 + 2x + 6 และเมอเรยก integrate(p, 2, 10) จะไดผลรวมของ 3x2 + 2x + 6 เมอ x มคาตงแต 2 ถง 10
def integrate(f, a, b): return sum([f(x) for x in range(a,b, 1)])
ภาษาโปรแกรมเชงฟงกชนแบบบรสทธ (pure functional programming language) ไมมการเกบคาในตวแปร คาถกสงจากฟงกชนหนงถกสงไปใหฟงกชนทตองใชโดยไมเกบในตวแปรกอน ขอด คอ ทำใหโปรแกรมอานงายและเขาใจผดไดนอย ขอเสย คอ จะไมสามารถเกบคาทตองใชในหลายฟงกชนในตวแปรแลวสงใหแตละฟงกชนได
การโปรแกรมในแบบความคดท ตางกนทำให โปรแกรมเมอรคดวธแกปญหาตางกน การเขยนโปรแกรมในแบบความคดทตางกนชวยใหโปรแกรมเมอรมมมของการแกปญหากวางขนและสามารถเลอกไปประยกตใชในสถานการณตาง ๆ ไดอยางเหมาะสม
Programming Language Principles and Processing
8
1.3 ขนตอนการประมวลผลสำหรบภาษาโปรแกรม
เมอโปรแกรมเมอรเขยนโปรแกรมทเปนรหสเร มตน (source code) แลว โปรแกรมนเกบเปนไฟลขอความ (text file) เมอตองการใหโปรแกรมทำงานในเครองคอมพวเตอร โปรแกรมทเปนรหสเรมตนนตองถกแปลเปนคำสงทใชสำหรบเครองคอมพวเตอรนนกอน การแปลโปรแกรมทใชกนม 2 แบบ คอ แบบคอมไพล (compile) และ แบบอนเทอรพรท (interpret) ในการคอมไพลโปรแกรม ขอความในไฟลซงเปนคำสงในภาษาระดบสงถกแปลเปนคำสงในภาษาเครอง (machine code) ของเครองคอมพวเตอรทจะทำงานแลวเกบไวในไฟล โปรแกรมทแปลมาแลวน เรยกวา รหสเปาหมาย (target code) เมอตองการใหโปรแกรมทำงาน เราจงนำรหสเปาหมายไปใหเครองคอมพวเตอรทำงาน (execute) ดงแสดงในรปขางลาง ตวแปลภาษาซ (C compiler) ทใชกนทำงานแบบน สำหรบการแปลโปรแกรมแบบอนเทอรพรท คำสงในภาษาระดบสงถกแปลเปนคำสงในภาษาเครองและสงใหเครองคอมพวเตอรทำงานทละคำสงดงแสดงในรปขางลาง
ในทน เราจะเนนการแปลแบบคอมไพล ขนตอนการคอมไพลโปรแกรมแบงเปนขนตอนยอย คอ
- การสแกน (scanning) - การแจงสวน (parsing) - การวเคราะหความหมาย (semantic analyzing) - การสรางรหสกลาง (intermediate code generating) - การสรางรหส (code generator) - การปรบรหสทเหมาะสม (code optimization)
ดงแสดงในรปขางลาง
source code
compile target code
execute output
source code
interpret output
การแปลแบบคอมไพล
การแปลแบบอนเทอรพรท
หลกการและการประมวลภาษาโปรแกรม
9
รหสเรมตนเปนตวอกขระเรยงตอ ๆ กนเกบในไฟลขอความ ในขนตอนการสแกน ตวอกขระทเรยงตอกนนถกแบงเปนชนสวนพนฐานทมความหมายในภาษาโปรแกรม เชน ชอ ( identifier) จำนวนเตม (integer) สายอกขระ (string) สญลกษณการเปรยบเทยบ >= เปนตน ชนสวนเหลานเรยกวาโทเคน (token) และสตรงทตรงกบรปแบบทกำหนดสำหรบแตละโทเคน เรยกวา หนวยศพท ( lexeme) ตวอยาง เชน สำหรบรหสเรมตน
if (x==0) x=x+1; else x=0;
สแกนเนอรแบงเปนโทเคนดงน
keyword if symbol ( identifier x operator == integer 0 symbol ) identifier x assignment = identifier x operator + integer 1 symbol ; keyword else identifier x assignment = integer 0 symbol ;
รปแบบสำหรบแตละโทเคนถกอธบายดวยนพจนปกตซงจะอธบายตอไปในบทท 2 เมอสแกนเนอรทำงานเสรจแลวจะไดโทเคนซงบอกชนดของชนสวนทอยในโปรแกรม
ในขนตอนการแจงสวน โทเคนทไดจากสแกนเนอรจะถกจดเปนกลมตามโครงสรางทใหญขนของภาษาโปรแกรม เชน นพจน คำสงทางเลอก โครงสรางวนซำแบบ for บลอกของโปรแกรม หรอ ฟงกชน โครงสรางของภาษาในระดบนอธบายดวยไวยากรณไมพงบรบท (context-free grammar) ซงจะอธบายตอไปในบทท 3 โครงสรางนถกเกบในรปตนไมทเรยกวา ตนไมการแจงสวน (parse tree) หรอ ตนไมไวยากรณนามธรรม (abstract syntax tree) ตนไมนแสดงการประกอบกนของโทเคนเปนโครงสรางทใหญขนตามลำดบตามไวยากรณของภาษาโปรแกรมนน ขางลางนเปนตนไมการแจงสวนและตนไมไวยากรณนามธรรมของโทเคนในตวอยางขางตน
scanner parser
semantic analyzer
intermediate code generator
code generator
stream of characters
parse tree
stream of tokens
annotated parse tree
intermediate code
target code
Programming Language Principles and Processing
10
prog
statement statement
if-statement empty
condition symbol ( symbol ) then-part
expression
keyword if else-part
statement
expression expression
operator ==
identifier integer identifier
Assign-st
assignment=
expression
statement
identifier
Assign-st
assignment =
expression
keyword else
integer operator +
expression
identifier
expression
integer
prog
if-statement
operator ==
identifier integer identifier
Assign-st
identifier
Assign-st
integer operator +
identifier integer
ตนไมไวยากรณนามธรรม
ตนไมการแจงสวน
หลกการและการประมวลภาษาโปรแกรม
11
ขนตอนการวเคราะหความหมายเปนการตรวจสอบชนดของขอมลทใชในโปรแกรมใหตรงกบชนดขอมลทระบไวในภาษา เชน ใน x = y + 2 ถาตวแปร x เปนชนดจำนวนเตม แลว ตวแปร y ควรเปนชนดจำนวนเตมหรอจำนวนจรง หาก y เปนจำนวนจรง ตวแปลภาษาจะตองใสตวกระทำการแปลงจำนวนเตมใหเปนจำนวนจรงเพมในตนไมทเรยกวาตนไมแจงสวนประกอบความหมาย (annotated parse tree) แลวจงเลอกวาใชตวกระทำการบวกสำหรบจำนวนจรง ขนตอนการวเคราะหความหมายอธบายในบทท 5
ตนไมการแจงสวนบอกลำดบการทำงานของโปรแกรม ดงนนจงสามารถสรางโปรแกรมจากตนไมการแจงสวนเพอใหทำงานตามลำดบนนได โปรแกรมทสรางขนอาจอยในภาษาเครองหรอภาษาอนได ในการสรางตวแปลภาษาอาจใชรหสกลาง ( intermediate code) ซ งภาษาท อย ระหวางภาษาระดบสงและภาษาเครอง ในขนตอนการสรางรหสกลาง ตนไมการแจงสวนจะถกแปลงเปนโปรแกรมในรหสกลาง บทท 6 แสดงตวอยางของรหสกลางรวมถงขนตอนการสรางรหสกลาง
การสรางรหสกลางชวยอำนวยความสะดวกเมอตองการแปลโปรแกรมจากภาษาระดบสงหลายภาษาไปยงภาษาเครองหลายภาษา ภาษาจาวาและภาษาไพธอนมไบทโคด (byte code) ททำหนาทเปนรหสกลาง เครองเสมอน (virtual machine) อานรหสกลางและทำงานตามคำสงในรหสกลาง สำหรบภาษาอน เชน ภาษาซ ตวแปลภาษาอาจแปลโปรแกรมเปนรหสกลางแลวจงแปลเปนภาษาเครองตอไปในขนตอนการสรางรหส
การปรบรหสใหเหมาะสม (code optimization) เปนขนตอนทปรบปรงโปรแกรมใหทำงานไดประสทธภาพดขน การปรบปรงนอาจทำไดกบโปรแกรมในรหสกลางและโปรแกรมในภาษาเครองโดยวธการปรบรหสใหเหมาะสมขนอยกบภาษาทใช ดงนนขนตอนนอาจทำไดทงหลงขนตอนการสรางรหสกลางและหลงขนตอนการสรางรหส อยางไรกตาม ตวแปลภาษาอาจมขนตอนนหรอไมกได นนคอตวแปลภาษาแบบคอมไพลอยางนอยตองมขนตอนการสแกน การแจงสวน การวเคราะหความหมาย และ การสรางรหส
Programming Language Principles and Processing
12
หลกการและการประมวลภาษาโปรแกรม
13
2. สแกนเนอร
สแกนเนอรเปนสวนแรกของตวแปลภาษา (compiler) ทรบสายของอกขระซงเปนโปรแกรมทตองการแปลมาแบงเปนชนสวนพนฐานของภาษา เชนจำนวนเตม จำนวนจรง สตรง ชอของตวแปรหรอฟงกชน เคร องหมายตางๆ (+ - * /) คำหลก (keyword) เปนตน ช นสวนเหลานเรยกวาโทเคน (token) ซ งเปนสวนประกอบทมความหมายทเลกสดในภาษา คลายกบคำในภาษาธรรมชาต สแกนเนอรตองระบชนดของโทเคนแตละตว เพอสงใหตวแจงสวนตรวจโครงสรางทางไวยากรณ นอกจากนนสแกนเนอรจะเกบโทเคนบางตว เชน ชอตวแปรหรอฟงกชน และ คาคงทไวในตารางทเรยกวา ตารางสญลกษณ (symbol table) เพอใหตวแปลภาษาใชในการทำงานขนตอ ๆ ไป
ในบทนเราจะอธบายแนวคดในภาษาโปรแกรมทเก ยวของกบการสรางสแกนเนอร ในหวขอ 2.1 แนวคดเหลาน ไดแก การกำหนดรปแบบของโทเคนแตละชนด การกำหนดใหคำหลก (keyword) เปนหรอไมเปน คำสงวน (reserved word) ในภาษาหรอไม จากนน หวขอ 2.2 อธบายการใชนพจนปกต (regular expression) ระบรปแบบของโทเคนทใชในภาษา เพอสอสารระหวางผพฒนาคอมไพเลอรดวยกนและกบผใชภาษา จากนนหวขอ 2.3 อธบายการสรางออโตมาตาจำกด ( finite automata) เพอตรวจสอบลำดบของตวอกขระทตรงตามรปแบบทนพจนปกตกำหนด เราใชออโตมาตาจำกดเปนตวแบบสำหรบอธบายการทำงานของสแกนเนอรเนองจากเปนตวแบบทเขาใจงายและจำลองการทำงานดวยโปรแกรมไดสะดวก หวขอ 2.4 อธบาย ประเดนตางๆในการเขยนโปรแกรมสแกนเนอรจากออโตมาตาจำกด
2.1 แนวคดในภาษาโปรแกรมทเกยวของกบสแกนเนอร
การเลอกรปแบบของโทเคนทใชในภาษาโปรแกรมใหเหมาะสมทำใหภาษาอานงาย ในหวขอน เราจะพจารณารปแบบของโทเคนทใชในภาษาโปรแกรมโดยทวไป
2.1.1 รปแบบของโทเคน
ภาษาโปรแกรมสวนใหญมโทเคนดงตอไปน
- จำนวนเตม - จำนวนจรง - สตรง - ชอ (identifier) เชน ชอตวแปร ชอฟงกชน - ตวกระทำ (operator) เชน + - * / >= <= != - เครองหมายแบงวรรคตอน เชน , ; : ( ) [ ] { }
รปแบบของสตรงสำหรบโทเคนในภาษาโปรแกรมควรใกลเคยงกบสงทโทเคนนนอางถงในภาษาธรรมชาต เพอใหโปรแกรมเมอรอานโปรแกรมเขาใจไดงาย แตเนองจากสแกนเนอรตองแยกชนดของโทเคนตามรปแบบ
Programming Language Principles and Processing
14
ของสตรงสำหรบโทเคนนน ภาษาโปรแกรมตองกำหนดรปแบบของสตรงสำหรบโทเคนใหแยกโทเคนแตละชนดออกจากกนไดดวย ภาษาโปรแกรมทใชกนในปจจบนกำหนดรปแบบของโทเคนคลาย ๆ กน ดงน
จำนวนเตม
รปแบบของโทเคนชนดจำนวนเตมเลยนแบบมาจากจำนวนเตมทใชกนในภาษาธรรมชาต เชน 365, 0, -123 เปนตน น นคอสตรงสำหรบโทเคนจำนวนเตมเปนตวเลข 0-9 อยางนอยหนงตวตอกนและอาจมเครองหมาย + หรอ - อยขางหนา เชน -32 +7 0 546
จำนวนจรง
รปแบบของโทเคนทแทนจำนวนจรงม 2 แบบคอ แบบทไมมเลขยกกำลง ซงเลยนแบบจำนวนจรงทใชกนโดยทวไป เชน 123, -564 และ แบบทมเลขยกกำลง ซงคลายกบจำนวนจรงทใชทางวทยาศาสตร เชน 3.1212 x 104 รปแบบแรกประกอบดวยตวเลข 0-9 ตอกนกตวกได ตามดวยจดทศนยม และตวเลข 0-9 ตอกนอกก ตวกได โดยอาจมแตเลขหนาจดทศนยมหรอเลขหลงจดทศนยมอยางใดอยางหน งกได และมเครองหมายบวกหรอลบอยหนาสดได เชน -3.14159 +0.6 .543 365. รปแบบท 2 เปนการนำสตรงในรปแบบแรกมาตอดวยเลขยกกำลงทระบดวย e หรอ E แลวตามดวยสตรงทแทนโทเคนจำนวนเตม เชน 1.3223e-5 0.9e0 -12E4
สตรง
รปแบบของโทเคนทแทนสตรงจะคลายกบการแทนคำพดในภาษาธรรมชาต คอ จะใชเครองหมาย "... " ครอบตวอกขระทเรยงตอกน สงเกตวาการใชเครองหมาย "..." ครอบสตรงนทำใหแยกระหวางสตรงและชอได
นอกจากนนยงทำใหมชองวางและเครองหมายพเศษในสตรงไดโดยไมกำกวม แตการม " ในสตรง จะทำใหสแกนเนอรตความผดได ดงนนถาตองการใชเครองหมาย " ในสตรงจะใหใช \" เพอระบวาเปนตวอกขระในสตรง แตไมใชเครองหมายปด
อยางไรกตามบางภาษา เชน ภาษาไพธอน หลกเลยงการใช \" โดยอนญาตใหเลอกใช " ... " หรอ ' ... ' หรอ """ ... """ ครอบสตรง ดงนนถาตองการใช " ในสตรงกใหเลอกครอบสตรงนนดวย ' ... ' เปนตน
ชอ (identifier)
ชอทใชในภาษาโปรแกรมอาจเปนชอตวแปรหรอชอฟงกชน รปแบบของโทเคนสำหรบชอ เลยนแบบการตงชอตวแปรทางคณตศาสตร โดยใหใชตวอกษร A-Z a-z และตวเลข 0-9 ในชอได แตในภาษาโปรแกรมไมสามารถใชสญลกษณเลยนแบบการทำตวหอยในทางคณตศาสตรได จงอนญาตใหใชสญลกษณ _ ไดดวย แตชอตองขนตนดวยตวอกษร A-Z a-z และสญลกษณ _ เทานน
สงเกตวาชอเหลานไมสามารถมเครองหมายพเศษ เชน + - * / " เพอใหสามารถบอกไดแนนอนวาชอนน จบเมอเจอชองวางหรอเครองหมายพเศษ เหลาน เชน เมอสแกนเนอรอานนพจน grade_380+0.5 แลวจะสามารถบอกไดวามตวแปรชอ grade_380 เครองหมายบวกและคาคงทจำนวนจรง 0.5
หลกการและการประมวลภาษาโปรแกรม
15
สญลกษณพเศษ
สญลกษณพเศษสวนใหญทใชในภาษาโปรแกรม เหมอนกบสญลกษณทใชในภาษาธรรมชาต ยกเวนแตบางสญลกษณทไมมในแปนพมพคอมพวเตอร เชน เครองหมาย ดงนนภาษาโปรแกรมสวนใหญจงใชคของตวอกขระแทนเครองหมาย เหลาน เชน <= >= !=
ตวกระทำการคณในภาษาโปรแกรมใหใชเครองหมาย * และไมอนญาตใหใชการเขยนตวแปรตดกนหรอเขยนคาคงทตดกบตวแปรแทนการคณ เชน xy เนองจาก xy อาจหมายถงชอตวแปรหนงตวไดดวยดงนนเพอใหตความหมายไดทางเดยวจงใชเครองหมาย * แทนการคณในทกกรณ
2.1.2 คำสงวนหรอคำหลก
คำหลกเปนคำทมความหมายพเศษในภาษาโปรแกรม เชน if else int float while ภาษาโปรแกรมบางภาษาไมอนญาตใหใชชอตวแปรซำกบคำหลกเหลาน จงเรยกคำเหลานวาเปนคำสงวน (reserved words) แตบางภาษาอาจยอมใหใชคำเหลานเปนชอไดและเรยกคำเหลานวาเปนคำหลก (keywords) หากยอมใหใชคำเหลานเปนชอไดอาจทำใหสบสนเมออานโปรแกรม เชน
x = if(y=0)
ในทน if เปนชอฟงกชน และเราเกบคา 0 ในตวแปรy และสงใหฟงกชน if ซงอาจทำใหผอานสบสนวาเปนคำสง if และตองอานคำสงถดไปกอนจงบอกไดวาเปนคำสง if หรอไม
เนองจากคำสงวนมรปแบบเหมอนชอ สแกนเนอรตองตรวจสอบชอทอานมาไดกอนวาเปนคำสงวนหรอไม เราจะกลาวถงการทสแกนเนอรจดการคำสงวนในหวขอถดไป
2.1.3 รปแบบของสตรง
ภาษาโปรแกรมหลายภาษา กำหนดใหใชเคร องหมาย "..." ครอบสตรง เชน "Programming Languages" แตเมอตองการใหมสญลกษณ " ในสตรงดวย เชน "Did I say "yes" ? " สแกนเนอรตองแยกระหวางสญลกษณ " ในสตรงและสญลกษณ " ทปดสตรงได ดงนนภาษาโปรแกรมหลายภาษาจงใชสญลกษณ \ นำหนาสญลกษณ " ทเรยกวาเปน escape character เชน "Did I say \"yes\" ? " ดงนนสแกนเนอรตองตรวจสอบวาไมมสญลกษณ \ กอนหนาสญลกษณ " หรอไมเพอทจะบอกไดวาเปนสญลกษณปดทายสตรง
อยางไรกตามภาษาไพธอนหลกเลยงการใชสญลกษณ \ นำหนาสญลกษณ " โดย ใหใชเครองหมาย '...' หรอ "..." หรอ """...""" ครอบสตรง ดงนน หากโปรแกรมเมอรตองการใชสญลกษณใดในสตรงกสามารถเลอกสญลกษณอกตวหนงครอบสตรง เชน 'I said "no".', "It's me." """I said "It's me".""" ดงนนสแกนเนอรตองสามารถตรวจสอบคสญลกษณเปด-ปดทตรงกนได การอนญาตใหใชสญลกษณเปด-ปดสตรงไดหลายแบบทำใหไมจำเปนตองใช escape character แตการใชสญลกษณ " สามตวตดกนอาจทำใหเกดขอผดพลาดได
Programming Language Principles and Processing
16
2.1.4 การใชตวอกษรตวใหญ/ตวเลก
ภาษาโปรแกรมสวนใหญกำหนดใหตวอกขระตวใหญและตวเลก เชน A และ a ตางกน ดงนนตวแปร x และ ตวแปร X ไมถอเปนตวแปรเดยวกน ซงตวแปลภาษาสามารถตรวจสอบความแตกตางไดงาย แตโปรแกรมเมอรอาจพมพผดและไมสงเกตเหนความแตกตาง ภาษาโปรแกรมบางภาษา เชน FORTRAN, Cobol ถอวาตวอกษรตวใหญและตวเลกไมตางกน
2.2 การอธบายรปแบบของโทเคนดวยนพจนปกต
เมอผออกแบบภาษากำหนดรปแบบของโทเคนทใชในภาษาแลวจะอธบายรปแบบของโทเคนเหลานนดวยนพจนปกต ขอดของนพจนปกต คอ มความหมายชดเจน และ ทำใหผออกแบบภาษาผสรางคอมไพเลอรและผใชภาษาเขาใจไดตรงกน นอกจากนนยงนำไปแปลงเปนออโตมาตาจำกดเพอใชสร างสแกนเนอรตอไปไดดงจะอธบายในหวขอ 2.3
รปแบบของโทเคนทใชในภาษาโปรแกรมมกเปนรปแบบงาย ๆ ททำใหแยกชนดของโทเคนไดดงทไดกลาวมาแลว นพจนปกตเปนนพจนทสรางจากตวกระทำสำหรบสตรง คอการตอกน (concatenation) การซำ และการรวม (union) ดงนนเราจะนยามนพจนปกตและแสดงตวอยางการนำนพจนปกตมากำหนดโทเคนในภาษาโปรแกรม เรามกใชนพจนปกตในการอธบายรปแบบของโทเคนในภาษาโปรแกรม จากนนจงแปลงนพจนปกตนเปนออโตมาตาจำกดซงเปนตวแบบทอธบายการทำงานเพอตรวจสอบรปแบบทกำหนดดวยนพจนปกต จากนนจะสรางสแกนเนอรจากออโตมาตาจำกด สาเหตทใชออโตมาตาจำกดเปนเพราะสามารถนำมาเขยนโปรแกรมเลยนแบบการทำงานไดงาย
นพจนปกตเปนนพจนทใชสรางภาษาซงเปนเซตของสตรงทสรางจากสญลกษณทกำหนดสำหรบภาษานน นพจนปกตสรางจากสญลกษณเหลานและตวกระทำพนฐาน ไดแก การตอกน (concatenation) การซำ และ การรวม (Union) นพจนปกตทใชไดสำหรบภาษาทกภาษา ไดแก นพจน e ทใชแทนเซตของสตรงวางและนพจน ทใชแทนเซตวาง นพจนปกตทเลกสดสำหรบเซตของสญลกษณชดหนง ไดแก สญลกษณแตละตวในภาษาซงใชแทนเซตของสตรงทมสญลกษณนนเพยงตวเดยว ถาใหเซตของสญลกษณในภาษาเปน {0, 1} นพจนปกต 0 แทนเซตของสตรง 0 และนพจนปกต 1 แทนเซตของสตรง 1
เราสามารถนำนพจนปกตใด ๆ มาสรางเปนนพจนปกตใหมโดยใชตวกระทำสำหรบนพจนปกต ในทน เราใหตวเขมในนพจนปกตแสดงสญลกษณในภาษา
- การตอกนแสดงดวยการ เขยนนพจนตอกน หรอ ใชสญลกษณ แทนตวกระทำการตอกน เชน 01 หรอ 01 หมายถง {0, 1}
- ตวกระทำการซำใชสญลกษณ * เชน 0* หมายถง {e, 0, 00, 000, ...} - ตวกระทำการรวมใชสญลกษณ + เชน 0+1 หมายถง {0, 1}
เราสามารถใชตวกระทำเหลานสรางนพจนปกตทซบซอนมากขนไดดงตวอยางตอไปน
หลกการและการประมวลภาษาโปรแกรม
17
ตวอยาง 2.1
00*=00* = {0, 00, 000, 0000, ...} = {w | w เปนสตรงทประกอบดวยศนยอยางนอยหนงตวและไมมสญลกษณอน}
0 (0+1)* 0 = {00, 000, 010, 0000, 0010, 0100, 0110, ...} = {w| w เปนสตรงทมความยาวอยางนอย 2 และ ขนตนและลงทายดวยศนย}
0 + (0(0+1)* 0) = {0, 00, 000, 010, 0000, 0010, 0100, 0110, ...} = {w| w เปนสตรงทมความยาวอยางนอย 1 และขนตนและลงทายดวยศนย}
(0+1)*111(0+1)* = {111, 0111, 1111, 1110, 01110, 01111, 11110, 11111, ...} = {w | 111 เปนสตรงยอยใน w }
1*((0+00)11*)* (0+00+e) = {e, 0, 1, 00, 01, 10, 11, 001, 010, 011, 100, 101, 110, 111, 0010, 0011, 0100, 0101, 0110, 0111, 1001, 1010, 1011, 1100, 1101, 1110, 1111, ... } = {w| ไมม 0 ตดกนมากกวา 2 ตว}
นอกจากนนยงมตวกระทำทใชเขยนนพจนปกตใหสนลง เชน
rn หมายถง r ตอกน n ครงเมอ r เปนนพจนปกต
r+ หมายถง r*r เมอ r เปนนพจนปกต
r? หมายถง r หรอสตรงวาง เมอ r เปนนพจนปกต นนคออาจมสตรงตามนพจนปกต r หนงครงหรอไมมเลยกได
~r หมายถง สญลกษณใด ๆ ทไมใช r เมอ r เปนนพจนปกต
[a-z] หมายถง a+b+...+z เมอ a, b, ..., z เปนสญลกษณในภาษา
[a-zA-Z] หมายถง a+b+...+z+A+B+...+Z เมอ a, b, ..., z และ A, B, ..., Z เปนสญลกษณในภาษา
ตวอยาง 2.2
[0-9]+ หมายถงเซตของสตรงทประกอบดวยตวเลข 0 ถง 9 ตอกนอยางนอยหนงตว
(+|-)?[0-9]+ หมายถงเซตของสตรงทประกอบดวยตวเลข 0 ถง 9 ตอกนอยางนอยหนงตว และอาจนำหนาดวยเครองหมาย + หรอ - หรอไมมเครองหมายนำหนา
[0-9]10 หมายถงเซตของสตรงทประกอบดวยตวเลข 0 ถง 9 ตอกน 10 ตว
59[0-9]8 หมายถงเซตของสตรงทประกอบดวยตวเลขตอกน 10 ตว โดยทตวเลขสองตวแรกเปน 59
โทเคนในภาษาโปรแกรมสวนใหญอธบายไดดวยนพจนปกตดงแสดงในตวอยางน
Programming Language Principles and Processing
18
ตวอยาง 2.3
จำนวนเตมอธบายไดดวยนพจนปกต (+|-)?[0-9]+
จำนวนจรงอธบายไดดวยนพจนปกต (+|-)? [0-9]+ . [0-9]* ((e|E) (+|-)?[0-9]+)?
สตรงอธบายไดดวยนพจนปกต " (~")* "
ชออธบายไดดวยนพจนปกต [A-Za-z_][A-Za-z0-9_]*
สแกนเนอรยงตองตรวจหารปแบบหนงทไมใชในโปรแกรม คอ คอมเมนท (comment) คอมเมนทในภาษาซอธบายไดดวยนพจนปกต /* (~(*/))* */ เมอสแกนเนอรพบคอมเมนทจะอานขามไปและไมนำมารวมในโปรแกรม
2.3 การสรางออโตมาตาจำกดสำหรบสแกนเนอร
เมอเราจะสรางสแกนเนอรเพอหาโทเคนทมรปแบบตามกำหนดในนพจนปกตดงทกลาวไปในหวขอทแลว เราจะแปลงนพจนปกตใหเปนออโตมาตาจำกดแลวจงนำไปสรางสแกนเนอร
2.3.1 ออโตมาตาจำกด
ออโตมาตาจำกดเป นต วแบบ (model) ท ใช ตรวจสอบรปแบบของสตร ง ออโตมาตาจำกดประกอบดวยสวนควบคม, เทปสำหรบรบขอมลเขา, และ หวเทปดงแสดงในรปขางลาง
จากสวนประกอบน ออโตมาตาจำกดอธบายดวย 5-สงอนดบ (Q, , , s, F) สวนควบคมมสถานะเปนจำนวนจำกด ซง Q เปนเซตของสถานะ (state) ทเปนไปไดของสวนควบคม เมอเรมทำงาน ออโตมาตาจำกดอยทสถานะ s ทเรยกวา สถานะเรมตน (start state) สวนควบคมจะอยในสถานะเดยว ณ เวลาหนง ไมสามารถอยในสองสถานะในเวลาเดยวกน และ ไมสามารถไมอยในสถานะใดเลย ณ เวลาหนง เทปแบงเปนชอง ๆ แตละชองมสญลกษณอยไดหนงตว เปนเซตของสญลกษณซงอยบนเทป เมอเครองทำงาน สวนควบคมจะเปลยนสถานะตามทระบในฟงกชนเปลยนสถานะ (transition function) ซงระบการเปลยนสถานะทขนกบสถานะปจจบนและสญลกษณทอานจากเทป เครองสามารถอานสญลกษณในชองหนงของเทปไดเมอหวเทปอยทชองนน หวเทปเลอนไปทางขวาในแตละครงทอานสญลกษณ
สวนควบคม
1 0 1 1 .... เทป หวเทป
สญลกษณ
หลกการและการประมวลภาษาโปรแกรม
19
เครองหยดทำงานเมออานสญลกษณตวขวาสดบนเทปแลวเปลยนสถานะ หากเครองหยดทำงานทสถานะใน F ทเรยกวาสถานะสนสด (final state) เราถอวาเครองยอมรบสตรงบนเทป แตถาเครองจบการทำงานแลวอยในสถานะทไมใชสถานะสนสด แลวเครองจะไมยอมรบสตรงนน
ออโตมาตาจำกดม 2 แบบ คอ ออโตมาตาจำกดเชงกำหนด (deterministic finite automata) และออโตมาตาจำกดเชงไมกำหนด (non-deterministic finite automata) เราเรยกออโตมาตาจำกดเชงกำหนด และออโตมาตาจำกดเชงไมกำหนดอยางสนๆ วา DFA และ NFA ตามลำดบ
ออโตมาตาจำกดเชงกำหนดเปนออโตมาตาทมการเปลยนสถานะเชงกำหนด คอ เมอเครองอยในสถานะหนงและอานไดสญลกษณหนง เครองสามารถเปลยนสถานะไปยงสถานะถดไปไดเพยงสถานะเดยว เชน ถาออโตมาตาจำกดเชงกำหนด M เปลยนสถานะจากสถานะ p ไปยงสถานะ q เมออานสญลกษณบนเทปเปน 1 แลว ทกครงท M อยในสถานะ p และอานไดสญลกษณ 1 บนเทปแลว M จะเปลยนไปยงสถานะ q เสมอ ดงนน ออโตมาตาจำกดเชงกำหนดมการเปลยนสถานะซงอธบายไดดวยฟงกชนของสถานะปจจบนและสญลกษณทอานได ตวอยางตอไปนแสดง DFA ทยอมรบชอในภาษาโปรแกรมทอธบายดวยนพจนปกต [A-Za-z_][A-Za-z0-9_]*
ตวอยาง 2.4
ออโตมาตาจำกดเชงไมกำหนดเปนออโตมาตาทมการเปลยนสถานะเชงไมกำหนด คอ เมอเครองอยในสถานะหนงและอานไดสญลกษณหนง เครองสามารถเปลยนสถานะไปยงสถานะถดไปไดมากกวาหนงสถานะ เชน จากออโตมาตาจำกดเชงไมกำหนด M ขางลางน เมอ M อยในสถานะ p และอานสญลกษณบนเทปเปน 1 แลวอาจเปลยนไปยงสถานะ q หรอสถานะ r กได
การเปลยนสถานะเชงไมกำหนดอกแบบ คอ เมอเครองอยในสถานะหนงแลวเครองสามารถเปลยนสถานะไปยงสถานะถดไปโดยไมอานสญลกษณใดเลยหรออาจยงคงอยในสถานะเดมกได เชน จากออโตมาตาจำกดไมเชงกำหนด M ขางลางน เมอ M อยในสถานะ p แลวอาจเปลยนไปยงสถานะ q โดยไมอานสญลกษณบนเทป หรอ อยในสถานะ p จนกวาจะอานสญลกษณถดไปบนเทป
p 1 q
1 r
p e q
1 r
s A, B,…, Z, a, b, …, z, _
f
0, 1,…, 9, A, B,…, Z, a, b,…, z, _
Programming Language Principles and Processing
20
ดงนน ฟงกชนเปลยนสถานะของออโตมาตาจำกดเชงไมกำหนดระบวาหากเครองอยทสถานะหนงและอานสญลกษณหนงแลวสถานะถดไปของเครองเปนสถานะใดไดบาง ตวอยางตอไปนแสดง NFA ทยอมรบจำนวนจรงในภาษาโปรแกรมทอธบายดวยนพจนปกต (+|-)? [0-9]+ . [0-9]* ((e|E) (+|-)?[0-9]+)?
ตวอยาง 2.5 ออโตมาตาจำกดเชงไมกำหนดนยอมรบจำนวนเตมทไมมสวนยกกำลงโดยจบการทำงานทสถานะ r และยอมรบจำนวนเตมทไมสวนยกกำลงโดยจบการทำงานทสถานะ f สญลกษณ e แทนสตรงวาง
2.3.2 การสรางออโตมาตาจำกดจากนพจนปกต
จากตวอยาง 2.4 และ 2.5 จะเหนวาเราสรางออโตมาตาจำกดตามนพจนปกตทกำหนดใหได อยางไรกตามยงมขนตอนวธทใชแปลงนพจนปกตเปนออโตมาตาจำกดได โดยสรางออโตมาตาจำกดสำหรบนพจนปกตทเลกสดกอนแลวคอยนำออโตมาตาจำกดนมาประกอบกนตอไป วธประกอบออโตมาตาจำกดยอยเขาดวยกนนขนอยกบตวกระทำทใชสรางนพจนปกตทใหญขน รปขางลางนแสดงการประกอบออโตมาตาจำกดทสรางตามนพจนปกตทสรางดวยตวกระทำ การเชอม การรวม และ การซำ ตามลำดบ ในทนให M1 และ M2 เปนออโตมาตาจำกดทสรางจาก r1 และ r2 ตามลำดบ
สำหรบนพจนปกตทมขนาดเลกสด เชน นพจนปกตของเซตวาง นพจนปกตของสตรงวาง และ นพจนปกตของสญลกษณตวเดยว เราสามารถสรางออโตมาตาจำกดสำหรบนพจนปกตเหลานไดดงแสดงในรปขางลางน
f s +, -, e p
. q r 0, 1,…, 9
0, 1,…, 9
u e, E
0, 1,…, 9
+, -, e v 0, 1,…, 9
0, 1,…, 9
… … e e e
…
… e
e
e
e …
e
e
e
e
a e
หลกการและการประมวลภาษาโปรแกรม
21
ตวอยาง 2.5 แสดงออโตมาตาจำกดสำหรบนพจนปกต (+|-)? [0-9]+ . [0-9]* ((e|E) (+|-)?[0-9]+)? สงเกตไดวาจำนวนจรงสรางจากจำนวนเตม ตอดวย. และตอดวย เลขหลงจดทศนยมหรอไมกได จากนนตามดวยตวอกขระ e หรอ E แลวตามดวยจำนวนเตมอกชดหนง ออโตมาตานสรางจากการประกอบออโตมาตาสำหรบนพจนปกตเลก ๆ ขนมา
นพจนปกต (+|-)? แทนดวยการเปลยนสถานะจาก s ไปยง p
นพจนปกต [0-9]+ แทนดวยการเปลยนสถานะจาก p ไปยง q
นพจนปกต . แทนดวยการเปลยนสถานะจาก q ไปยง r
นพจนปกต [0-9]* แทนดวยการเปลยนสถานะจาก r ไปยง r
นพจนปกต ((e|E) (+|-)?[0-9]+) แทนดวยการเปลยนสถานะจาก r ไปยง f
ดงนนเราจะไดออโตมาตาจำกดเปลยนสถานะจาก s ไปยง r เมออานไดจำนวนจรงทไมมสวนยกกำลง และเปลยนจากสถานะ r ไปยง f เมออานไดสวนยกกำลง
เมอเราสรางออโตมาตาจำกดสำหรบโทเคนแตละชนดแลว จะตองนำออโตมาตาจำกดเหลานมาประกอบกนเปนออโตมาตาตวเดยวดวยตวกระทำการรวม โดยใชการเปลยนสถานะดวยสตรงวางจากสถานะเรมตนทสรางขนมาใหมไปยงสถานะเรมตนของออโตมาตาสำหรบแตละโทเคน ออโตมาตาทไ ดจะเปนออโตมาตาจำกดเชงไมกำหนดทยอมรบโทเคนแตละชนด และมสถานะสนสดสำหรบโทเคนแตละชนดทแยกกน
ตวอยางตอไปนแสดงออโตมาตาจำกดทยอมรบโทเคนชนด จำนวนเตม จำนวนจรง ชอ สตรง และ คอมเมนทในภาษาซ เราจะใช other สำหรบการเปลยนสถานะเพอระบวาการเปลยนสถานะนนเกดขนเมออานไดสญลกษณทไมไดระบไวในการเปลยนสถานะอน ๆ จากสถานะนน
ตวอยาง 2.6 ออโตมาตาจำกดเชงไมกำหนดนยอมรบโทเคนชนด จำนวนเตม จำนวนจรง ชอ สตรง และ คอมเมนทในภาษาซ ตามลำดบ
+, -, e
. 0, 1,…, 9
0, 1,…, 9
e, E
0, 1,…, 9
+, -, e 0, 1,…, 9
0, 1,…, 9
+, -, e
0, 1,…, 9 0, 1,…, 9
A, B,…, Z, a, b, …, z, _
0, 1,…, 9, A, B,…, Z, a, b,…, z, _
"
other
"
/ * *
other
other
/
Programming Language Principles and Processing
22
ในหวขอถดไปเราจะแสดงการนำออโตมาตาจำกดนไปสรางเปนโปรแกรมสแกนเนอร
2.4 โปรแกรมสแกนเนอร
2.4.1 การปรบออโตมาตาจำกดเพอสรางสแกนเนอร
เม อสรางออโตมาตาจำกดท ตรวจสอบโทเคนทงหมดในภาษาโปรแกรมแลว เราสามารถสรางสแกนเนอรจำลองการทำงานของออโตมาตาจำกดน อยางไรกตาม การทำงานของออโตมาตาจำกดตางจากการทำงานของสแกนเนอรเปนบางสวน ออโตมาตาจำกดหยดทำงานและบอกวาสายอกขระทรบเขามาเปนโทเคนทยอมรบหรอไมเมออานสายอกขระนนจบ แตโปรแกรมสแกนเนอรรบสายอกขระทมหลายหนวยภาษาเรยงตอกน ดงนนสแกนเนอรตองบอกไดวาหนวยภาษาแตละหนวยจบลงทใด สายอกขระ ab1 อาจแบงเปนโทเคนไดหลายแบบ เชน เปนชอ a และ ชอ b กบ จำนวนเตม 1, เปนชอ ab กบ จำนวนเตม 1, เปนชอ ab1 ดงนนสแกนเนอรตองระบวาจะเลอกแบบใด หลกการทใชท วไปคอใหเลอกสายอกขระทยาวทสด ตรงกบรปแบบของโทเคนชนดหนง ในกรณของสายอกขระ ab1 น จะเลอกใหไดโทเคนเดยวเปนชอ ab1
ในการใชหลกเกณฑนสแกนเนอรอาจตองมองไปขางหนา (look ahead) จนพบตวอกขระทไมทำใหหนวยภาษานนตรงกบโทเคนใด ๆ ตวอยาง เชน สายอกขระ ab1+ จะถกแบงเปนชอ ab1 เมออานพบตวอกขระ + ซงทำให ab1+ ไมตรงกบโทเคนใดในภาษา สแกนเนอรจงตดสนใจไดวา ab1 เปนหนวยภาษาทใหญสดทเปนไปได ตวอกขระ + จะไมถกรวมอยในหนวยภาษาน และเรยกวาเปนสญลกษณมองขางหนา (look-ahead symbol) จากนนสแกนเนอรตองทำเสมอนวายงไมไดอานอกขระ + เขามาเรยกวาการคน หรอ unget สแกนเนอรอานสายอกขระตอไปโดยเรมจากตวอกขระ + น
จากทกลาวมาแลวเราจะตองระบการมองไปขางหนาและการคนตวอกขระโดยจะแสดงไวในออโตมาตาจำกดดวยสญลกษณทอยใน [ ] เชน [+] ระบวาการเปลยนสถานะนนเกดเมออานตวอกขระ + โดย + เปนสญลกษณมองขางหนาและจะคน + กลบไปเปนตวอกขระทยงไมไดอาน ตวอยางขางลางนระบการมองไปขางหนาทจำเปนสำหรบการทำงานของสแกนเนอรทสรางจากออโตมาตาจำกดในหวขอทผานมา
ตวอยาง 2.7 ออโตมาตาจำกดนระบการมองไปขางหนาทจำเปนสำหรบการทำงานของสแกนเนอรทแสดงดวยเสนประสฟา
หลกการและการประมวลภาษาโปรแกรม
23
ขอสงเกต: - การมองไปขางหนาไมไดจำเปนสำหรบทกโทเคน - สญลกษณมองไปขางหนามกเปนสญลกษณอนทแสดงดวย other แต other อาจใชในกรณอน
นอกจากการมองไปขางหนา - สแกนเนอรมกคนสญลกษณมองไปขางหนา แตไมจำเปนตองทำเสมอ
ขนตอนถดไปของ การสรางสแกนเนอร คอ การนำออโตมาตาสำหรบแตละโทเคนมารวมใหเปนออโตมาตาเดยวดวยตวกระทำการรวม ดงนนจะสรางสถานะเรมตนใหม แลวเพมการเปลยนสถานะดวยสตรงวางจากสถานะเรมตนใหมนไปยงสถานะเรมตนของออโตมาตาของแตละโทเคน ออโตมาตานไปถงสถานะสนสดสถานะกจะบอกได จากสถานะนนวาโทเคนทไดเปนชนดใด ออโตมาตาในรปขางลางนเปนออโตมาตาทใชสำหรบสแกนเนอรของโทเคนจำนวนเตม ชอ สตรง และ คอมเมนต
"
other
"
/ * *
other
other
/
+, -, e
0, 1,…, 9
0, 1,…, 9
[other]
+, -, e
. 0, 1,…, 9
0, 1,…, 9
e, E
0, 1,…, 9
+, -, e 0, 1,…, 9
0, 1,…, 9
[other]
[other]
A, B,…, Z, a, b, …, z, _
0, 1,…, 9, A, B,…, Z, a, b,…, z, _
[other]
+, -, e p n 0, 1,…, 9
0, 1,…, 9
q [other]
s A,B,…,Z,a,b,…,z, _ i
0, 1,…, 9, A, B,…, Z, a, b,…, z, _
r [other]
" t
other
" v
/
* * other
other
/
Programming Language Principles and Processing
24
2.4.2 โปรแกรมจำลองการทำงานของออโตมาตาจำกดเพอสรางสแกนเนอร
เมอปรบออโตมาตาเพอสรางสแกนเนอรแลวเราสรางสแกนเนอรโดยเขยนโปรแกรมจำลองการทำงานของออโตมาตานน ในทนแสดงตวอยางโปรแกรมในภาษาไพธอนสำหรบออโตมาตาทยอมรบโทเคนจำนวนเตมชอและสตรงทแสดงขางลางน ออโตมาตานสรางจากการรวมออโตมาตาของโทเคนจำนวนเตม ชอ และ สตรง แลวนำมาปรบลดจำนวนสถานะลง
ในโปรแกรมขางลางน ตวแปร states เกบสถานะของออโตมาตาเปนเซตของชอสถานะ ตวแปร startState เกบชอสถานะเรมตน ตวแปร finalStates เกบเซตของชอสถานะสนสด ตวแปร tFunc เปน dictionary ทเกบฟงกชนการเปลยนสถานะ ตวแปร ungetTr เกบเซตของคลำดบของสถานะสนสด f และสญลกษณ a เพอระบวาตองคนสญลกษณ a หากออโตมาตาไปถงสถานะสนสด f ดวยสญลกษณ a จะเหนไดวาตวแปรเหลานเกบขอมลทงหมดของออโตมาตาทใชสรางสแกนเนอร # Scanner for integer:(+|-|e)[0-2]+
# string: "[a-dA-D0-2+-_ ]*"
# identifier: [a-dA-D_][a-dA-D0-2_]*
states=set(['s', 'p', 'q', 'r', 'v', 'n', 't', 'i']) # set of states
startState='s' # start state
finalStates=set(['n', 't', 'i']) # set of final states
# transition function
tFunc = {('s','"'):set(['r']), ('s','_'):set(['v']), ('s','+'):set(['p']),
..., ('n','e'):set([]), ('t','e'):set([]), ('i','e'):set([])}
ungetTr = set([('n','+'),('n','-'),('n','_'),('n','"', ... ,
('i','+'),('i','-'),('i',' '),('i','"')]) # unget transition
tokenMap = {'n':'integer', 't':'string', 'i':'identifier'}
buffer='-11 a_b 12 "a1- +12"22""' # source code
# Find the closure of each state
setClosure={}
for state in states:
setClosure[state]=closure(set([state]))
# main loop call scanner
bufferPtr=0
while bufferPtr<len(buffer):
tk,bufferPtr=scan(bufferPtr)
print(tk)
+, -, e p n 0, 1,…, 9
0, 1,…, 9
q [other]
s A,B,…,Z,a,b,…,z, _ i
0, 1,…, 9, A, B,…, Z, a, b,…, z, _
r [other]
" t other " v
หลกการและการประมวลภาษาโปรแกรม
25
ฟงกชน closure คำนวณหาเซตของสถานะทอยในสวนปดคลม (closure) ของสถานะทกำหนด นนคอการหาวาออโตมาตาสามารถเปลยนจากสถานะทกำหนดไปอยในสถานะใดดวยสตรงวางไดบาง ฟงกชนนทำงานโดย ใหเสรจของสถานะทกำหนดมาอยในสวนปดคลม เกบในตวแปร clsSet กอน จากนนหาวามการเปลยนสถานะดวยสตรงวางจากเซตของสถานะในตวแปร clsSet ไปยงสถานะใดไดบาง แลวเพมสถานะเหลานนในตวแปร clsSet จนไมไดสถานะใหมเพมขนมา
def closure(states): # find closure of a set of states from lambda
transiton
clsSet=states
for s in states:
clsSet=clsSet.union(tFunc[(s,'e')])
if clsSet.issubset(states):
return states
else:
return states.union(closure(clsSet))
ฟงกชน scan อาน ตวอกขระหรอสญลกษณทเกบในตวแปร buffer โดยเรมทตำแหนงทระบดวยพารามเตอร p ของฟงกชน สถานะเรมตนของออโตมาตาเกบในตวแปร currentState ซงเมอเรมตนทำงานกำหนดใหเปนสวนปดคลมของสถานะเรมตน จากนนในการวนซำแตละครง จะอานสญลกษณจากตวแปร buffer มาเกบในตวแปร sym และหาวาออโตมาตาสามารถเปล ยนสถานะจากแตละสถานะในตวแปร currentState ไปยงสถานะใดไดบางโดยดจากฟงกชนเปลยนสถานะในตวแปร tFunc แลวหาสวนปดคลมของสถานะเหลานน เกบในตวแปร nextState การวนซำนจะหยดเมอออโตมาตาไปถงสถานะสนสดสถานะหนงได เมอถงสถานะสนสดจะสามารถบอกไดวาสายอกขระทอานมาไดเปนหนวยภาษาของโทเคนใด และตองมการคนตวอกขระทอานมาหรอไม หากตรวจสอบแลวสถานะสนสดนนและตวอกขระทอานมาเปนสถานะทตองมการคนตวอกขระทอานเขามาตามทเกบในตวแปร ungetTr กจะถอยตำแหนงของอกขระทอานกลบไป 1 ตว ฟงกชนนคนโทเคนทเปนผลลพธและตำแหนงใน buffer ทตองอานตอไป
# ------------- function for scanner -----------
def scan(p):
global states
global startState
global finalStates
global ungetTr
global buffer
currentState=setClosure[startState]
tk=""
while not currentState.intersection(finalStates):
sym=buffer[p]
p=p+1
nextState=set([])
for st in currentState:
for nxt in tFunc[(st,sym)]:
nextState=nextState.union(setClosure[nxt])
currentState=nextState
tk=tk+sym
[tState]=currentState.intersection(finalStates)
if tState in set([st for (st, a) in ungetTr if a==sym]):
p=p-1
Programming Language Principles and Processing
26
tk=tk[:-1]
return (tokenMap[tState], p)
2.4.3 ตารางสญลกษณ
ตารางสญลกษณเปนโครงสรางขอมลทใชเกบชอหรอคาคงททใชในโปรแกรม ดงนนสงทถกเกบไวในตารางสญลกษณอาจเปนชอตวแปร ชอฟงกชน ชอคลาส หรอ สตรง ตารางนใชในหลายขนตอนการทำงานของตวแปลภาษา สแกนเนอรเปนสวนแรกของตวแปลภาษาทจะนำชอหรอคาคงทในโปรแกรมเกบไวในตารางสญลกษณ ดงนนเมอสแกนเนอรอานไดโทเคนทเปนชอหรอคาคงทอนทตองการเกบในตารางสญลกษณกจะ มาใสเพมไว หากชอหรอคาคงทนนถกเกบไวในตารางสญลกษณแลวกจะใสซำอก ดงนนทกครงทพบชอหรอคาคงทในโปรแกรมสแกนหนาตองตรวจสอบวามชอหรอคานนในตารางสญลกษณแลวหรอยง โครงสรางขอมลทใชสำหรบตารางสญลกษณจงควรเปนโครงสรางของขอมลทเขาถงไดเรว เชน ตารางแฮช (hash table)
ข นตอนการวเคราะหความหมายเกบชนดของตวแปรหรอขอมลเก ยวกบฟงก ชนเพ มในตารางสญลกษณและใชเพอตรวจสอบการใชตวแปรและฟงกชนใหถกชนดและตรวจสอบขอบเขตของตวแปรดวย จากนน ในการสรางรหสจะกำหนดตำแหนงในหนวยความจำสำหรบชอเหลานเพออางถงในรหสทสราง
2.4.4 การสรางสแกนเนอรใหหาคำหลก
คำหลกหรอคำสงวนเปนคำทมรปแบบตรงกบชอทใชในภาษาโปรแกรม โดยทคำหลกแตละคำมความหมายเฉพาะ สำหรบแตละคำ คำหลกแตละคำจงเปนโทเคนทตางกนไป หากเราสรางออโตมาตาจำกดสำหรบคำหลกแตละคำ แลวนำมารวมกนสรางสแกนเนอร ออโตมาตาของสแกนเนอรจะใหญมาก ดง นนสแกนเนอรมกตรวจสอบหาชอและคำหลกรวมไปดวยกน จากนนจงนำมาพจารณาวาเปนชอหรอคำหลกโดยอาศยตารางสญลกษณ เนองจากเราตองนำชอไปตรวจสอบวามอยในตารางสญลกษณแลวหรอยง จงสามารถใชการตรวจสอบนเพอหาวาชอนนเปนคำหลกหรอไมโดยใหเกบคำหลกทงหมดไวในตารางสญลกษณกอน เมอนำหนวยคำทไดไป หาในตารางสญลกษณแลวพบวาหนวยคำนนเปนคำสงวนกจะบอกไดวาไมเปนชอและสงกลบ โทเคนของคำสงวนนนทเกบไวในตารางสญลกษณไป หากหนวยคำนนอยในตารางสญลกษณโดยระบวาเปนชอ กจะสงคากลบวาเปนโทเคนชนดชอ หากตรวจสอบแลวไมพบวาอยในตารางสญลกษณหมายความวาหนวยคำนนเปนชอทยงไมเคยเกบไว วธการ ทำงานแบบนทำใหออโตมาตาของสแกนเนอรมขนาดเลกลงและสแกนเนอรทำงานได อยางมประสทธภาพ
2.4.5 การใชตวอกษรตวใหญ/ตวเลก
ในภาษาโปรแกรมสวนใหญทไมถอวาตวอกขระตวใหญและตวเลกตางกน สแกนเนอรสามารถเกบชอทงหมดเปนตวอกขระตวใหญทงหมด (หรอ ตวอกขระตวเลกทงหมด) และแปลงชอทพบเปนตวอกขระตวใหญทงหมดกอนนำไปเปรยบเทยบในตารางสญลกษณ
หลกการและการประมวลภาษาโปรแกรม
27
3. ตวแจงสวน (Parser)
ตวแจงสวนทำหนาทตรวจสอบไวยากรณของโปรแกรมทตองการแปล ดงนนผออกแบบภาษาตองกำหนดไวยากรณของภาษากอน หวขอ 3.1 กลาวถงประเดนในการออกแบบภาษาทเกยวของกบตวแจงสวน ภาษาโปรแกรมเปนภาษาทไมพงบรบท (context-free language) นนคอกฎการสรางหนวยของภาษา (เชน นพจน คำสง if ฟงกชน) ไมขนกบสงทอยรอบขางหนวยของภาษานน ไวยากรณของภาษาโปรแกรมอธบายไดดวยไวยากรณทเรยกวาไวยากรณไมพงบรบท (context-free grammar) ซงอธบายในหวขอ 3.2 หวขอ 3.3 อธบายออโตมาตาพชดาวน (pushdown automata) ทเปนตวแบบทใชในการทำงานของตวแจงสวน หวขอ 3.4 แสดงขนตอนวธแจงสวนทใชออโตมาตาพชดาวนทเรยกวา การแจงสวนแบบ LL(1) หวขอ 3.5 แสดงขนตอนวธแจงสวนแบบ LR(1) ทเปนการแจงสวนอกวธทใชสแตค (stack) ประกอบกบออโตมาตาจำกด
3.1 แนวคดในภาษาโปรแกรมทเกยวของกบตวแจงสวน
ในการออกแบบภาษาโปรแกรม ผออกแบบจะเลอกรปแบบของคำสงหรอสวนของโปรแกรมเพอใหอานเขาใจไดงาย นอกจากนนยงตองทำใหวเคราะหโครงสรางของภาษาไดงายดวย นนคอทำใหตวแจงสวนแยกสวนประกอบในโปรแกรมไดอยางถกตอง เมอโครงสรางในภาษาทำใหตความหมายไดมากกวาหนงแบบ ผออกแบบตองเลอกระบความหมายทตองการเพยงแบบเดยว ทงนเพอใหผทสรางตวแปลภาษาใชความหมายเดยวกนและตวแปลภาษาทกตวสรางโปรแกรมใหทำงานไดเหมอนกน
ในหวขอนเราจะพจารณาประเดนในการออกแบบภาษาโปรแกรมทมสวนเกยวของกบการสรางตวแจงสวน
3.1.1 ลำดบการทำงานในนพจน
รปแบบของนพจนในภาษาโปรแกรมถกออกแบบใหคลายกบนพจนทางคณตศาสตรและตรรกศาสตร แตลำดบการทำงานของตวกระทำในนพจนทใชกนในภาษาคณตศาสตรสามารถแสดงไดดวยวธเขยนทตาง ๆ
กน เชน สำหรบ 3+𝑥
𝑦 เรารไดวาตองบวก 3 กบ 𝑥 กอน แลวจงเอาผลลพธทไดหารดวย 𝑦 แตเราไมสามารถใช
รปแบบของนพจนเชนนในภาษาโปรแกรม นอกจากนนเรายงตองการใหตวแปลภาษาทกตวแปลใหไดลำดบการทำงานในนพจนออกมาตรงกนเสมอ ดงนนภาษาโปรแกรมแตละภาษาจะกำหนดลำดบความสำคญ (precedence) ของตวกระทำเพอกำหนดวาตวกระทำใดในนพจนจะทำงานกอน ลำดบความสำคญทกำหนดนจะใกลเคยงกบทมนษยตความนพจนทางคณตศาสตร ตวอยาง เชน จากนพจน 3𝑥2 − 5 จะทำ 𝑥2 กอนแลวจงคณดวย 3 แลวลบดวย 5 ดงนนการยกกำลงมลำดบความสำคญสงกวาการคณ และ การคณมความลำดบสำคญสงกวาการลบ เปนตน ตารางตอไปนแสดงลำดบความสำคญของตวกระทำในภาษาซและภาษาไพธอน
Programming Language Principles and Processing
28
ตารางแสดงลำดบความสำคญของตวกระทำในภาษาซและภาษาไพธอนเรยงจากตำไปสง
ภาษาซ ภาษาไพธอน || (logical OR) or
&& (logical AND) and | (bitwise OR) not
^ (bitwise XOR) in, not in, is, is not, <, <=, >, >=,!=, ==
& (bitwise AND) | ==, != ^
<, <=, >, >= & <<, >> (bitwise shift) <<, >> (bitwise shift)
+, - +, - *, /, % *, @, /, //, %
+x, -x, ~x +x, -x, ~x **
( ) ( )
นอกจากนนยงตองกำหนดลำดบการทำงานสำหรบตวกระทำทมลำดบความสำคญเทากน พจารณานพจน 𝑥 − 𝑦 − 𝑧 เราจะทำ 𝑥 − 𝑦 กอนแลวจงนำไปลบดวย 𝑧 แตสำหรบนพจน 𝑥23 เราจะทำ 23 กอน แลวจงนำมาเปนกำลงของ 𝑥 หลกการทใชในการกำหนดลำดบการทำงานของตวกระทำทมความสำคญเทากนเรยกวา สมบตการเชอมโยง (associativity) เมอตวกระทำสองตวอยทางซายและขวาของตวถกกระทำ 𝑥 ดงน ... 𝑥 ...
- หาก 𝑥 ทำงานกบตวกระทำทางซายกอน (คอ (... 𝑥) ... ) เราเรยกวาตวกระทำ มสมบตการเชอมโยงทางซาย
- หาก 𝑥 ทำงานกบตวกระทำทางขวากอน (คอ ... ( 𝑥...) ) เราเรยกวาตวกระทำ มสมบตการเชอมโยงทางขวา
ภาษาโปรแกรมโดยทวไปจะใหตวกระทำมสมบตการเชอมโยงทางซาย ยกเวนตวกระทำยกกำลง
3.1.2 Dangling else
โครงสราง if เปนโครงสรางการทำงานแบบทางเลอกทมอยในเกอบทกภาษาโปรแกรม โครงสราง if นสามารถนำมาวางซอนกนไดดงแสดงในโปรแกรมภาษาซขางลางน
if (x<=0)
if (y<=0)
y=10;
else
y--;
else
x--;
หลกการและการประมวลภาษาโปรแกรม
29
โครงสราง if อาจไมมสวน else ได เชน if (x==0) x=10; เมอนำโครงสราง if สองแบบนมาซอนกน โครงสรางจะม if 2 ทและ else 1 ท แลวสามารถตความให else เปนสวนของ if ทตำแหนงแรกหรอตำแหนงทสองกได ในภาษาโปรแกรมสวนใหญ เชน ภาษาซจะให else จบคกบ if กอนหนาทใกลทสดทไมม else อย เชน
if (x==0) // if ตวท 1 if (y==0) // if ตวท 2 if (z==0) // if ตวท 3 z++;
else // else ตวท 1 z=0;
else // else ตวท 2 y=0;
ในโครงสรางน else ตวท 1 เปนสวนของ if ตวกอนหนาทใกลสดคอ if ตวท 3 และ else ตวท 2 เปนสวนของ if ตวกอนหนาทใกลสดทยงไมม else นนคอ if ตวท 2 ดงนน if ตวท 1 จะเปน if ทไมม elseโปรแกรมเมอรสามารถเปลยนการจบค if-else ไดโดยใช { } กำหนดบลอคของโปรแกรมไดดงตวอยางขางลางน
if (x==0) // if ตวท 1 if (y==0) // if ตวท 2 { if (z==0) // if ตวท 3 z++;
}
else // else ตวท 1 z=0;
else // else ตวท 2 y=0;
ในภาษาไพธอน การจบค if-else ระบอยางชดเจนดวยบลอคของโปรแกรมซงกำหนดดวยการจดยอหนา (indentation)
3.1.3 ตำแหนงของคำหลกในโครงสราง
คำส งหรอโครงสรางในภาษาจะมรปแบบทแตกตางกนอยางชดเจน ตวอยาง เชน โครงสราง if โครงสราง while และ โครงสราง for เร มตนดวยคำหลก if, while และ for เพ อใหตวแจงสวนร วาเปนโครงสรางชนดใดและทำใหโปรแกรมมาอานเขาใจไดดวย อยางไรกตามการใชคำหลกเพอบงบอกโครงสรางอาจไมเหมาะกบบางโครงสรางบาง เชน ประโยคกำหนดคา (assignment statement) ภาษาโปรแกรมสวนใหญจะใชช อตวแปรตามดวยเครองหมาย = เพอบงบอกวาเปนประโยคกำหนดคา แตไมใชคำหลกระบโครงสราง เชน assign x 10 เนองจากคนทวไปจะเขาใจการใชเครองหมาย = เพอกำหนดคาไดงายกวา
Programming Language Principles and Processing
30
3.2 การอธบายภาษาโปรแกรมดวยไวยากรณไมพงบรบท
โครงสรางทางไวยากรณของภาษาโปรแกรมอธบายไดดวยการแบงเปนองคประกอบยอยคลายกบไวยากรณในภาษาธรรมชาต ไวยากรณท ใชอธบายภาษาโปรแกรมไมซบซอนเทาไวยากรณท ใช อธบายภาษาธรรมชาต ในหวขอนเราจะนยามไวยากรณทเรยกวา ไวยากรณไมพงบรบทซงใชอธบายภาษาโปรแกรมและแสดงการเขยนไวยากรณสำหรบสวนยอยของภาษาโปรแกรม นอกจากนนจะแสดงการเขยนไวยากรณเพอกำหนดลำดบการทำงานของตวกระทำในนพจนตามลำดบความสำคญและการเชอมโยงของตวกระทำ
3.2.1 ไวยากรณไมพงบรบท
ไวยากรณไมพงบรบทระบกฎการสรางสวนประกอบยอยในภาษาจนเปนประโยคในภาษา ในกฎเหลานใชสญลกษณแทนองคประกอบยอยหรอคำในภาษา สญลกษณทใชแบงเปน 2 ชนด คอ สญลกษณปลาย (terminal symbol) และสญลกษณไมปลาย (non-terminal symbol) สญลกษณปลาย เปนสญลกษณทใชในประโยคในภาษา (เชน คำในภาษาธรรมชาต) สญลกษณไมปลายเปนสญลกษณแทนองคประกอบในภาษา (เช น วล ภาคแสดง ในภาษาธรรมชาต) กฎในไวยากรณระบว าองคประกอบแตละตวประกอบดวยสวนประกอบยอยใด กฎในไวยากรณไมพงบรบทอยในรปของ X → W เมอ X เปนสญลกษณไมปลายและ W สตรงทสรางจากสญลกษณใด ๆ ตอกน
ตวอยาง 3.1 ถาให S เปนสญลกษณไมปลาย ( และ ) เปนสญลกษณปลาย
S → ( S ) S S → e
เปนกฎทอธบายการสรางวงเลบทจบคเปดปดกนอยางถกตอง เชน ( ), ( )( ), ( ( ) ), ( ( ) ( ) ) ( ( ) ) เปนตน
สงเกตวาทางซายมอของกฎในไวยากรณไมพงบรบทมสญลกษณไมจบเพยงตวเดยว นนหมายความวาการระบวาองคประกอบทแทนดวยสญลกษณนนสรางจากองคประกอบใดบางจะไมขนกบบรบท (context) หรอสงทอยรอบขางของสญลกษณนน นอกจากนนในไวยากรณจะระบสญลกษณทเรยกวาสญลกษณเรมตน (start symbol) ไว และสงทสรางจากสญลกษณเรมตนตามกฎในไวยากรณนนเปนสงทอยในภาษานน
เราอาจนยามไวยากรณไมพงบรบทไดดงน
G = (V, T, P, S) อธบายไวยากรณไมพงบรบทเมอ V เปนเซตของสญลกษณไมปลาย, T เปนเซตของสญลกษณปลาย, S เปนสญลกษณเรมตนทอยใน V และ P เปนเซตของกฎทใชสรางสตรงในภาษาโดยทกฎ X → W ใน P X ตองมาเปนสญลกษณไมจบและ W สรางจากสญลกษณใด ๆ ในภาษาตอกน
ตวอยาง 3.2 ไวยากรณทอธบายในตวอยาง 3.1 กอนหนานสามารถเขยนไดเปน ({S}, { (, )}, {S → ( S ) S, S → e}, S}
หลกการและการประมวลภาษาโปรแกรม
31
การแปลง (derivation) เปนขนตอนการใชกฎในไวยากรณเพอสรางประโยค และใชเครองหมาย เพอบอกการแปลงสญลกษณไมปลายหนงตวในประโยคตามกฎในไวยากรณ ตวอยางตอไปนแสดงการแปลงททำใหได ( ), ( )( ), ( ( ) ), ( ( ) ( ) ) ( ( ) )
ตวอยาง 3.3 ลำดบการแปลงขางลางนแสดงการแปลงทให ( ), ( )( ), ( ( ) ), ( ( ) ( ) ) ( ( ) ) ตามลำดบ
S ( S ) S ( S ) ( )
S ( S ) S ( S ) ( S ) S ( ) ( S ) S ( ) ( ) S ( ) ( )
S ( S ) S ( ( S ) S ) S ( ( S ) S ) ( ( ) S ) ( ( ) )
S ( S ) S ( ( S ) S ) S ( ( ) S ) S ( ( ) ( S ) S ) S ( ( ) ( ) S ) S ( ( ) ( ) ) S ( ( ) ( ) ) ( S ) S ( ( ) ( ) ) ( ( S ) S ) S ( ( ) ( ) ) ( ( ) S ) S ( ( ) ( ) ) ( ( ) ) S ( ( ) ( ) ) ( ( ) )
สตรงทไดจากการแปลงแตละขนเรยกวาแบบประโยค (sentential form) สญลกษณไมปลายในแบบประโยคถกเปลยนตามกฎในแตละขนของการแปลง หากการแปลงแตละขนเลอกแปลงสญลกษณไมปลายตวซายสด การแปลงนนเรยกวา การแปลงซายสด (leftmost derivation) หากการแปลงแตละขนเลอกแปลงสญลกษณไมปลายตวขวาสด การแปลงนนเรยกวา การแปลงขวาสด (rightmost derivation)
บางครงการแปลงประกอบดวยหลายขนตอน เราใชสญลกษณ * แสดงการแปลงหลายขนทตอกนดงแสดงในตวอยางขางลางน
ตวอยาง 3.4 ลำดบการแปลงขางลางนแสดงการแปลงทให ( ( ) ( ) ) ( ( ) ) โดยใช *
S ( S ) S ( ( S ) S ) S ( ( ) S ) S ( ( ) ( S ) S ) S * ( ( ) ( ) ) S ( ( ) ( ) ) ( S ) S ( ( ) ( ) ) ( ( S ) S ) S * ( ( ) ( ) ) ( ( ) )
ขนตอนการแปลงสามารถแสดงไดเปนตนไมทมรากเปนสญลกษณเรมตน การแตกกงของโหนดภายในแตละโหนดเปนไปตามการแปลงดวยกฎในไวยากรณหนงครงซงโหนดพอเปนสญลกษณทางซายมอของกฎและโหนดลกเปนสญลกษณทอยทางขวามอของกฎ ตนไมนเรยกวา ตนไมแจงสวน (parse tree)
กำหนดไวยากรณ G = (V, T, P, S) และสตรง w ทสรางจากไวยากรณ G ตนไมแจงสวนของ w มสมบตดงน
- รากของตนไมนเปนโหนดทแทนสญลกษณเรมตน S, - โหนดภายในแทนสญลกษณปลาย, - โหนดใบแทนสญลกษณปลายซงเมอเรยงสญลกษณของโหนดใบจากซายไปขวาจะได w, และ - สำหรบโหนดภายในทแทนสญลกษณ X ลกของเปนโหนดนนแทนสญลกษณ K L … M โดย X → K L … M อยใน P
Programming Language Principles and Processing
32
ตวอยาง 3.5 ตนไมขางลางนเปนตนไมการแจงสวนของสตรง ( ( ) ( ) ) ( ( ) ) ทแสดงการแปลงในตวอยาง 3.4
ภาษาทสรางจากไวยากรณคอเซตของสตรงทไดจากการแปลงสญลกษณเรมตนตามกฎในไวยากรณ นนคอ
ภาษาทสรางจากไวยากรณ G = (V, T, P, S) เขยนแทนดวย L(G) คอ {w| S * w}
ตวอยาง 3.6 กำหนดไวยากรณ G1 = ({S}, { (, )}, {S → ( S ) S, S → e}, S)
L(G1) = {w| w เปนสตรงทมวงเลบเปดและปดทจบคกนไดอยางถกตอง}
จาก S → e จะเหนวาสตรงเลกสดทสรางจาก S เปนสตรงวาง นนคอหากจบควงเลบเปดและปดท จะจบคกนไดถกตอง จาก S → ( S ) S ถา S ทางขวาทง 2 ตวเปนสตรงทมวงเลบเปดและปดทจบคกนไดอยางถกตอง จะเหนวาสตรงทสรางตามกฎนจะตองมวงเลบเปดและปดทจบคกนไดอยางถกตองดวย
ตวอยาง 3.7 กำหนดไวยากรณ G2 = ({ E, A }, { id, num, +, -, *, / }, P, E) โดยท P = { E → E A E, E → id, E → num, A → +, A → -, A → *, A → / }
L(G2) เปนเซตของสตรงทเปนนพจนทางคณตศาสตรทมตวกระทำ +, -, *, / และตวถกกระทำเปนโทเคน id และ num
จาก E → id, E → num จะเหนวานพจนเลกสดคอ id หรอ num จาก E → E A E นพจนสรางจาก 2 นพจนเชอมดวยตวกระทำ +, -, *, /
ตวอยาง 3.8 กำหนดไวยากรณ G3 = ({ K, R, E, A }, { id, num, +, -, *, /, >, <, == }, P, K ) โดยท P = { K → E R E, E → E A E, E → id, E → num, A → +, A → -, A → *, A → /, R → >, R → <, R → == }
L(G3) เปนเซตของสตรงทเปนนพจนการเปรยบเทยบนพจนทางคณตศาสตรดวยตวกระทำ >, <, ==
S
S S ) (
S S ) (
e S S ) (
e e
S S ) (
S S ) (
e e
e
หลกการและการประมวลภาษาโปรแกรม
33
ในไวยากรณน E เปนชอ (id) หรอจำนวน (num) จาก K → E R E นพจนการเปรยบเทยบสรางจากนพจนทางคณตศาสตรเชอมดวยตวกระทำเปรยบเทยบ >, <, ==
ตวอยาง 3.9 กำหนดไวยากรณ G4 = ({ S, F, As, K, R, E, A }, { if, else, id, num, =, >, <, == }, P, S ) โดยท P = { S → F, S → As, F → if K S, F → if K S else S, As → id = E, K → E R E, E → id, E → num, R → >, R → <, R → == }
L(G4) เปนเซตของสตรงทเปนคำสง if หรอคำสงกำหนดคา (assignment)
จาก F → if K S, F → if K S else S F เปนคำสง if ทประกอบดวยโทเคน if, นพจนเปรยบเทยบ, คำสงใดๆ ทเปน then part และอาจม else part หรอไมกได else part ประกอบดวยโทเคน else และคำสงใดๆ จาก As → id = E As เปนคำสงกำหนดคาทประกอบดวยโทเคน id, โทเคน = และนพจนทางคณตศาสตร สดทาย S เปนคำสง if หรอคำสงกำหนดคาจาก S → F, S → As
3.2.2 ไวยากรณกำกวม
เราสามารถอธบายไวยากรณของภาษาโปรแกรมไดดงแสดงในหวขอ 3.2.1 ไวยากรณ G3 และ G4 เปนไวยากรณทเรยกวาไวยากรณกำกวม (ambiguous grammar) เนองจากเราสามารถสรางตนไมแจงสวนมากกวาหนงแบบสำหรบสายของโทเคนหนง ไวยากรณกำกวมทำใหเกดปญหาในการสรางตวแปลภาษาเนองจากโปรแกรมเมอรทสรางตวแปลภาษา 2 ตวอาจเลอกสรางตนไมทตางกนและทำใหโปรแกรมทไดจากตวแปลภาษา 2 ตวทำงานตางกน ตวอยางตอไปนแสดงตนไมแจงสวน 2 แบบของนพจนทางคณตศาสตรหนง
ตวอยาง 3.10 สำหรบนพจน x–y–z ซง x, y, z เปนโทเคน id สายของโทเคนทสแกนเนอรสงใหตวแจงสวนคอ id – id – id เราสามารถสรางตนไมแจงสวนของนพจนนตามไวยากรณ G3 ได 2 แบบดงน
หาก x, y, z มคา 8, 5, 2 ตามลำดบ ตนไมทางซายทำใหนพจนนใหคา (8-(5-2)) = 5 สวนตนไมทางขวาทำใหนพจนนใหคา ((8-5)-2) = 1
ตวอยางตอไปแสดงตนไมแจงสวน 2 แบบของคำสง if ทซอนกน
E
E E -
E E -
id (y) id (z)
id (x)
E
E E -
E E - id (z)
id (x) id (y)
Programming Language Principles and Processing
34
ตวอยาง 3.11 สำหรบคำสง if ทซอนกนดงน if x==y if x==0 y=0 else x=0
ซง x, y, z เปนโทเคน id เราสามารถสรางตนไมแจงสวนของนพจนนตามไวยากรณ G4 ได 2 แบบ ตนไมแบบแรกจบค else กบ if ตวแรกดงน
if x==y {if x==0 y=0} else x=0
ตนไมแบบทสองจบค else กบ if ตวทสองดงน if x==y {if x==0 y=0 else x=0}
ตนไมแจงสวนทงสองแบบแสดงในรปตอไปน
เนองจากเราตองการใหตวแปลภาษาทกตวแปลโปรแกรมแลวทำงานไดผลลพธเหมอนกน ไวยากรณของภาษาตองไมกำกวม เราจะอธบายการเขยนไวยากรณของภาษาใหไมกำกวมในหวขอตอไป
F
K S S if
R F E E
== K S if
As
id (x) E =
num (0)
S
else
id (x) id (y)
R E E
== id (x) num (0)
As
id (y) E =
num (0)
F
K
S
S if
R F
E E
== K S if
As
id (x) E =
num (0)
S
else id (x) id (y)
R E E
== id (x) num (0)
As
id (y) E =
num (0)
หลกการและการประมวลภาษาโปรแกรม
35
3.2.3 การเขยนไวยากรณเพอบงคบลำดบการทำงานของตวกระทำในนพจน
หวขอ 3.1.1 อธบายการกำหนดลำดบการทำงานของตวกระทำในภาษาโปรแกรมดวยลำดบความสำคญและสมบตการเชอมโยง ในหวขอน เราจะใชลำดบการทำงานของตวกระทำทกำหนดในหวขอ 3.1.1 แกความกำกวมของไวยากรณ G3 โดยเขยนไวยากรณใหบงคบลำดบการทำงานของตวกระทำตามลำดบความสำคญและสมบตการเชอมโยง การบงคบลำดบทำไดโดยสรางสญลกษณไมปลายสำหรบนพจนทมตวกระทำทมลำดบความสำคญตาง ๆ กนดงตวอยางตอไปน
ตวอยาง 3.12 เราสามารถแกไวยากรณ G3 ในตวอยาง 3.8 ใหกำหนดลำดบความสำคญของการคณและหารสงกวาการบวกและลบไดดงแสดงในไวยากรณ G5 = ({E, AD, F, MUL }, { id, num, +, -, *, / }, P, E ) โดยท P = { E → E AD E, E → F, AD → +, AD → -, F → F MUL F, F → id, F → num, MUL → *, MUL → / }
ในภาษาน ตวกระทำ + และ – มลำดบความสำคญเทากนแตนอยกวา * และ / เราให E เปนสญลกษณทสรางนพจนทมตวกระทำ +, –, * และ / สวน F เปนสญลกษณทสรางนพจนทมตวกระทำ * และ / เทานน
จากกฎ F → F MUL F และ F → id, F → num จะเหนวา F เปนสญลกษณทสรางนพจนทมตวกระทำ * และ / แตไมมตวกระทำ + และ – สวนกฎ E → E AD E ระบวา E เปนสญลกษณทสรางนพจนทมตวกระทำ + และ – แตจาก E → F ทำให E เปนสญลกษณทสรางนพจนทมตวกระทำ * และ / ไดดวย ดงนน E เปนสญลกษณทสรางนพจนทมตวกระทำ +, -, * และ / เนองจาก E F ได แต F * E ไมได โหนด F จะมโหนด E เปนลกหลานไมได ดงนนตวกระทำ * และ / ตองอยใกลโหนดใบมากกวาตวกระทำ + และ –
นพจน x+y*z ททำใหไดสายของโทเคน id + id * id และตนไมแจงสวนของ id + id * id แสดงในตนไมขางลางน
ถาตองการใหทำ + กอน * เราตองสรางจาก E F F MUL F แตเนองจากเราไมสามารถสราง id + id จาก F ได ดงนนนพจนจะทำ + กอน * ไมได
นนคอ เราสามารถกำหนดลำดบความสำคญของตวกระทำไดโดยแยกใชสญลกษณทสรางนพจนทมตวกระทำทมลำดบความสำคญตาง ๆ กน แลวใหสญลกษณทแทนนพจนทสรางดวยตวกระทำทมลำดบความสำคญนอยกวาแปลงเปนสญลกษณทแทนนพจนทสรางดวยตวกระทำทมลำดบความสำคญมากกวาได
E
F AD
F id MUL
id *
+
E
F
id
Programming Language Principles and Processing
36
นอกจากลำดบความสำคญแลว เรายงใชสมบตการเชอมโยงเพอบงคบลำดบการทำงานในนพจน เราสามารถเขยนไวยากรณทกำหนดสมบตการเชอมโยงของตวกระทำโดยเลอกใหสญลกษณทอยทางซายหรอขวาของตวกระทำนนเปนสญลกษณทแทนนพจนชนดเดมดงแสดงในตวอยางน
ตวอยาง 3.13 เราสามารถเขยนไวยากรณใหกำหนดสมบตความเชอมโยงของตวกระทำ + และ – เปนแบบเชอมโยงทางซายไดดงแสดงในไวยากรณ G6 = ({ E, AD }, { id, num, +, - }, P, E ) โดยท P = { E → E AD id, E → E AD num, E → id, E → num, AD → +, AD → - }
จาก E → E AD id จะเหนวาเราสามารถสรางตนไมแจงสวนของ id + id + id ดงแสดงในรปขางลาง ในตนไมน จะบวกดวยตวกระทำ + ทอยทางซายของนพจนกอน ดงนนตวกระทำนมสมบตการเชอมโยงทางซาย
ไวยากรณในตวอยางตอไปนกำหนดใหตวกระทำ + และ - มสมบตการเชอมโยงทางขวา
ตวอยาง 3.14 กำหนดไวยากรณ G7 = ({ E, AD }, { id, num, +, - }, P, E ) โดยท P = { E → id AD E, E → num AD E, E → id, E → num, AD → +, AD → - }
จาก E → id AD E จะเหนวาเราสามารถสรางตนไมแจงสวนของ id + id + id ดงแสดงในรปขางลาง ในตนไมน จะบวกดวยตวกระทำ + ทอยทางขวาของนพจนกอน ดงนนตวกระทำนมสมบตการเชอมโยงทางขวา
เราสามารถเขยนไวยากรณทกำหนดทงลำดบความสำคญและสมบตการเชอมโยงไดดงแสดงในตวอยางตอไปน
ตวอยาง 3.15 กำหนดไวยากรณ G8 = ({E, AD, F, MUL }, { id, num, +, -, *, / }, P, E ) โดยท P = { E → E AD F, E → F, AD → +, AD → -, F → F MUL id, F → F MUL num, F → id, F → num, MUL → *, MUL → / }
E
E AD
E id AD
id +
+
id
E
E AD
E id AD
id +
+
id
หลกการและการประมวลภาษาโปรแกรม
37
การแปลงทใหสายของโทเคน num * id + num + id * num แสดงไดดงน
E E AD F E AD F AD F F AD F AD F
F MUL id AD F AD F num MUL id AD F AD F num * id AD F AD F
num * id AD F AD F num * id + F AD F num * id + num AD F
num * id + num + F num * id + num + F MUL num num * id + num + id MUL num num * id + num + id * num
ตนไมแจงสวนขางลางนแสดงการแปลงของ num * id + num + id * num
3.2.4 การเขยนไวยากรณเพอกำหนดการจบคของ else กบ if
จากหวขอ 3.1.2 ภาษาโปรแกรมกำหนดให else จบคกบ if กอนหนาทใกลสดทยงไมม else คดวย เราสามารถแกปญหาไวยากรณกำกวมสำหรบคำสง if ไดโดยเขยนไวยากรณใหบงคบการจบคของ else กบ if ดงท กำหนดน เราสรางสญลกษณ Matched สำหรบ คำส ง if ทม else จบคกนไดครบและสญลกษณ Unmatched สำหรบคำสง if ทม else จบคกนไดไมครบ ดงตวอยางตอไปน
ตวอยาง 3.16 เราสามารถแกไวยากรณ G4 ในตวอยาง 3.9 ทเปนไวยากรณกำกวมใหกำหนดการจบค else กบ if โดยแยกคำสงเปน 2 ประเภท คอ คำสงถาม if แลวจะม else จบคกบ if ไดครบ และ คำสงทม else จบค ก บ if ไมครบ คำส งแบบแรกแทนดวยสญลกษณ Matched และแบบหลงแทนดวยส ญลกษณ Unmatched คำสงทแทนดวย Matched ไดแก
x=0,
if x==0 x=x+1 else x=0,
if x==0 x=x+1 else if x>0 x=x-1 else x=x+1
คำสงเหลานอธบายไดดวยกฎ Matched → As และ Matched → if K Matched else Matched
คำสงทแทนดวย Unmatched ไดแก if x==0 x=x+1,
if x>=0 if x>0 x=x-1 else x=x+1
E
F ADD
F num MUL
id *
+
E
F E ADD
num + F id MUL
num *
Programming Language Principles and Processing
38
คำสงเหลานอธบายไดดวยกฎ Unmatched → if K Matched และ Unmatched → if K Matched else Unmatched กฎทงสองนบงคบใหจบค else กบ if ทไดจาก Matched จากขางในกอนและปลอยให if ทเหลอทายสดไมม else
ไวยากรณ G9 ตอไปนไมกำกวมเพราะบงคบให else จบคกบ if กอนหนาทใกลสดทยงไมจบคกบ else ใ ด G9 = ( { S, Matched, Unmatched, As, K, R, E }, { if, else, id, num, =, >, <, == }, P, S ) โ ด ยท P = { S → Matched, S → Unmatched, Matched → As, Matched → if K Matched else Matched, Unmatched → if K Matched, Unmatched → if K Matched else Unmatched, As → id = E, K → E R E, E → id, E → num, R → >, R → <, R → == }
คำสง if x==y if x==0 y=0 else x=0 ทเปนสายของโทเคน if id == id if id == num id = num else id = num สายของโทเคนนสรางดวยไวยากรณ G9 ไดดงน
S Unmatched (หากใชกฎ S → Matched จะแปลงจนจบไมได) if K Matched (ใช Unmatched → if K Matched else Unmatched แลวม else เกน) if K if K Matched else Matched
if E R E if K Matched else Matched
* if id == id if K Matched else Matched if id == id if E R E Matched else Matched * if id == id if id == num Matched else Matched * if id == id if id == num As else Matched * if id == id if id == num id = num else Matched if id == id if id == num id = num else As * if id == id if id == num id = num else id = num
การแปลงนแสดงดวยตนไมแจงสวนขางลางทให else จบคกบ if ตวกอนหนาทยงไมม else
Unmatched
K
Matched
Matched if
R E E
==
K Matched if
Ass
id (x)
E =
num (0)
S
else
id (x)
id (y)
R E E
== id (x
num (0)
As
id (y
E =
num (0)
หลกการและการประมวลภาษาโปรแกรม
39
3.3 ออโตมาตาพชดาวน
จากการศกษาดานภาษาและออโตมาตา ภาษาทอธบายดวยไวยากรณไมพงบรบทสามารถตรวจสอบดวยออโตมาตาพชดาวนได (ในทำนองเดยวกบทภาษาทอธบายดวยนพจนปกตสามารถตรวจสอบดวยออโตมาตาจำกดได) นอกจากนนการทำงานของตวแจงสวนบางประเภทกเปนการจำลองการทำงานของออโตมาตาพชดาวน ออโตมาตาพชดาวนคลายกบออโตมาตาจำกดคอมสวนควบคมทมสถานะเปนจำนวนจำกด มเทปซงเกบสตรงทตองการตรวจสอบโดยอานจากซายไปขวาเทานน แตสวนทออโตมาตาพชดาวนมเพมขนมา คอ สแตค (stack) ทสามารถเกบสญลกษณใดใดทตองการไดโดยอานและเขยนขอมลตวบนสดของสแตคเทานน ออโตมาตาพชดาวน มสองแบบทตางกนตามชนดของการเปลยนสถานะ ออโตมาตาพชดาวนแบบกำหนดมการเปลยนสถานะแบบกำหนด คอ เมอเครองอยในสถานะหนง อานไดสญลกษณหนงบนเทปและอานไดสญลกษณหนงจากสแตคแลว เครองมสถานะถดไปทเปนไปไดเพยงสถานะเดยว สวนออโตมาตาพชดาวนแบบไมกำหนดมการเปลยนสถานะแบบไมกำหนด คอ เมอเครองอยในสถานะหนง อานไดสญลกษณหนงบนเทปและอานไดสญลกษณหนงจากสแตคแลว เครองอาจมสถานะถดไปทเปนไปไดมากกวาหนงสถานะหรอเลอกเปลยนสถานะโดยไมอานสญลกษณบนเทปและสแตคเลย เครองจะเลอกเปลยนสถานะไปยงสถานะททำใหออโตมาตายอมรบสตรงรบเขาหากเปนไปได แตในการสรางตวแจงสวนใชออโตมาตาพชดาวนแบบกำหนดเทานน
ออโตมาตาพชดาวนนยามไดดวย (Q, S, T, d, s, F) ซง Q เปนเซตจำกดของสถานะทเปนไปไดของออโตมาตาโดยม s เปนสถานะเรมตนและ F เปนเซตของสถานะสนสด S และ T เปนเซตจำกดของสญลกษณทใชบนเทปและสแตคตามลำดบ d เปนฟงกชนเปลยนสถานะโดย d(p, a, b) = (q, c) หมายความวาเมอออโตมาตาอยในสถานะ p และอานไดสญลกษณ a จากเทปและสญลกษณ b จากสแตค แลวออโตมาตาจะเปลยนสถานะไปยงสถานะ q และ เขยน c ลงบนสแตคแทน b ดงนนหาก c เปนสตรงวาง หมายความวา b จะถก pop ออกจากสแตค และหาก c เปน db หมายความวา d จะถกใสเพมบนสแตค ออโตมาตาพชดาวนจะหยดทำงานเมออานสตรงบนเทปหมดและสแตควาง หากเครองจบการทำงานทสถานะสนสดสถานะหนง เครองจะยอมรบสตรงรบเขา ออโตมาตาพชดาวน แสดงเปนแผนภาพไดโดยให แทนสถานะ แทนสถานะเรมตน แทนสถานะสนสด และเสนเชอมระหวางสถานะอธบายฟงกชนการเปลยนสถานะดงรปขางลางทแสดง d(p, a, b) = (q, c)
ตวอยางตอไปนเปนออโตมาตาพชดาวนทยอมรบสตรงทมสญลกษณเปดวงเลบและปดวงเลบทจบคกนไดอยางถกตอง
ตวอยาง 3.17 กำหนด M = ( {s, q}, { (, ) }, { (, ) }, d, s, {s, q} ) โดยท d เปนฟงกชนเปลยนสถานะทแสดงในรปขางลาง
p q a, b, c
s q
(, e, (
(, e, ( ), (, e
), (, e
Programming Language Principles and Processing
40
เราใช (q, x, y) เปนโครงแบบ (configuration) ของออโตมาตาพชดาวนทบอกวา q เปนสถานะของเครองในขณะนนโดย x เปนสตรงบนเทปทยงไมไดอานและ y เปนสตรงในสแตค นอกจากนน (p, v, x) |- (q, w, y) แสดงการเปลยนจากโครงแบบ (p, v, x) ไปยงโครงแบบ (q, w, y) ในหนงข น เมอ w=av และม d(p, a, b) = (q, c) โดย x = bz, y = cz สำหรบบางสตรง z ตวอยางตอไปนแสดงการเปลยนโครงแบบของออโตมาตาในตวอยาง 3.17
ตวอยาง 3.18 สมมตใหสตรงรบเขาบนเทปของออโตมาตาในตวอยาง 3.17 เปน ()(()(())) ออโตมาตาทำงานโดยมการเปลยนโครงแบบดงตอไปน
(s, ()(()(())), e) |- (q, )(()(())), ( ) |- (s , (()(())), e) |- (q, ()(())), ( ) |- (q, )(())), (( ) |- (s, (())), ( ) |- (s, ())), (( ) |- (s, ))), ((( ) |- (q, )), (( ) |- (q, ), ( ) |- (q, e, e)
ออโตมาตาพชดาวน M ยอมรบสตรง w กตอเมอให M เรมทำงานดวยสแตควางและมสตรง w บนเทปแลวเมอ M อานสตรง w หมดจะจบการทำงานทสถานะสนสดและสแตควาง จากตวอยาง 3.18 เมอให ()(()(()) เปนสตรงทอยบนเทปเมอ M เรมตนทำงาน แลวเมอ M อานสตรงบนเทปหมด M อยในโครงแบบ (q, e, e) ท q เปนสถานะสนสด ดงนน M ยอมรบ ()(()(()) สดทายเรานยามใหภาษาทยอมรบดวยออโตมาตาหนงเปนเซตของสตรงทออโตมาตานนยอมรบ ดงนนภาษาทยอมรบดวยออโตมาตาในตวอยาง 3.17 เปนเซตของสตรงทมวงเลบเปดและวงเลบปดจบคกนไดอยางถกตอง
ในการสรางตวแจงสวน เราใชออโตมาตาพชดาวนทใชในการพสจนวาออโตมาตาพชดาวนสามารถยอมรบภาษาทสรางดวยไวยากรณไมพงบรบทได ออโตมาตาพชดาวนนสรางแบบประโยคทไดจากการแปลงเกบไวในสแตคและตรวจวาแบบประโยคทอยในสแตคมสวนหนาทตรงกบสวนหนาของสตรงบนเทปหรอไมและ pop สญลกษณทตรวจสอบไดแลวออกจากสแตค หากสญลกษณทอยบนสดของสแตคเปนสญลกษณไมปลายในไวยากรณ ออโตมาตาจะแปลงสญลกษณนนตามกฎในไวยากรณ เชน ถา X อยบนสดของสแตคและมกฎ X → ab ... c ออโตมาตาจะแทน X ดวย ab ... c ตวอยางตอไปนแสดงการสรางออโตมาตาพชดาวนจากไวยากรณในหวขอ 3.2.1
ตวอยาง 3.19 จากไวยากรณ G1 = ({S}, { (, )}, {S → ( S ) S, S → e}, S) เราสามารถสรางออโตมาตาพชดาวนทยอมรบ L(G1) ไดดงแสดงในรปขางลางน
เรมตน ออโตมาตาตองใสสญลกษณเรมตนในสแตคดงแสดงดวย d(p, e, e) = (q, S) จากนนทสถานะ q เราจะตรวจสอบวาสญลกษณทสรางตามไวยากรณตรงกบสญลกษณบนเทปดวย d(q, (, ( ) = (q, e) และ d(q, ), ) ) = (q, e) เราสรางฟงกชนเปลยนสถานะสำหรบกฎ S → ( S ) S และ S → e ใน G1 คอ d(q, e, S) = (q, (S)S) และ d(q, e, S) = (q, e) ตามลำดบ
p q e, e, S
e, S, (S)S e, S, e (, (, e ), ), e
หลกการและการประมวลภาษาโปรแกรม
41
รปขางลางนแสดงการเปล ยนสถานะของออโตมาตาพชดาวนเทยบกบการแปลงดวยไวยากรณ สญลกษณทแสดงดวยตวหนาในการแปลงเปนสญลกษณทถก pop ออกจากสแตคแลว
การเปลยนสถานะครงท
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
การเปลยนสถานะของออโตมาตาพชดาวน ( p, ()((())()), e ) |- ( q, ()((())()), S ) |- ( q, ()((())()), (S)S ) |- ( q, )((())()), S)S ) |- ( q, )((())()), )S ) |- ( q, ((())()), S ) |- ( q, ((())()), (S)S ) |- ( q, (())()), S)S ) |- ( q, (())()), (S)S)S ) |- ( q, ())()), S)S)S ) |- ( q, ())()), (S)S)S)S ) |- ( q, ))()), S)S)S)S ) |- ( q, ))()), )S)S)S ) |- ( q, )()), S)S)S ) |- ( q, )()), )S)S ) |- ( q, ()), S)S ) |- ( q, ()), (S)S)S ) |- ( q, )), S)S)S ) |- ( q, )), )S)S ) |- ( q, ), S)S ) |- ( q, ), )S ) |- ( q, e, S ) |- ( q, e, e )
การแปลงดวยไวยากรณ S (S)S ()S ()(S)S ()((S)S)S ()(((S)S)S)S ()((()S)S)S ()((())S)S ()((())(S)S)S ()((())()S)S ()((())())S ()((())())
ในหวขอตอไป เราจะอธบายขนตอนวธแจงสวนทใชการทำงานของออโตมาตาพชดาวนทกลาวมาน
3.4 ขนตอนวธแจงสวนแบบ LL(1)
การแจงสวนแบบ LL(1) อานสายของโทเคนจากซายไปขวา (แสดงในชอLL(1) ดวย L ตวแรก) และเลยนแบบการทำงานของพชดาวนออโตมาตาซงจำลองการแปลงซายสด (แสดงในชอLL(1) ดวย L ตวหลง) วธนสรางตนไมแจงสวนจากบนลงลาง (topdown) นอกจากนนวธนดโทเคนถดไป 1 ตวเพอเลอกกฎทใชใน
Programming Language Principles and Processing
42
การแปลง (แสดงในชอLL(1) ดวย 1) หวขอนอธบายขนตอนวธแจงสวนแบบ LL(1) พรอมทงอธบายหลกการทใชในขนตอนวธน
3.4.1 ขนตอนวธจำลองการทำงานของออโตมาตาพชดาวน
ตวแจงสวนทำหนาทตรวจสอบไวยากรณของโปรแกรมทตองการแปลและสรางตนไมแจงสวนทแยกองคประกอบของโปรแกรมเพอนำไปแปลเปนรหสเปาหมาย เนองจากออโตมาตาพชดาวนสามารถเลยนแบบการแปลงสตรงตามไวยากรณทกำหนดได เราสามารถสรางตวแจงสวนโดยเขยนโปรแกรมจำลองการทำงานของออโตมาตาพชดาวนดงทกลาวในหวขอกอนหนาน ขนตอนวธทจำลองการทำงานมดงน
1. push(d, S) // S เปนสญลกษณเรมตนและ d เปนสแตค 2. t = scan_next_token() 3. WHILE d ไมเปนสแตควาง และ t ไมเปน null
top = pop(d) IF top เปนสญลกษณไมปลาย
เลอกกฎ head → body ท head=top // ทำการแปลง push(d, reverse(body))
ELSE // top เปน สญลกษณปลาย IF t==top // token t ตรงกบสญลกษณบนสดในสแตค
t = scan_next_token() // ทง token เดม ELSE // token t ไมตรงกบสญลกษณบนสดในสแตค
BREAK // มขอผดพลาด 4. IF d เปนสแตควาง และ t เปน null // ตรวจสอบ token ตรงกบทแปลงได
RETURN TRUE ELSE // ตรวจสอบ token ไมตรงกบทแปลงได
RETURN FALSE
scan_next_token() เปนฟงกชนท ทำหนาท เปนสแกนเนอรทอานโทเคน push และ pop เปนฟงกชนทใสสญลกษณลงบนสแตคและอานสญลกษณบนสดจากสแตค reverse เปนฟงกชนทเรยงสญลกษณในสตรงยอนจากหลงไปหนา
ขนตอนวธนจำลองการทำงานของออโตมาตาพชดาวนไดดงแสดงในตวอยางน
ตวอยาง 3.20 กำหนด S → ( S ) S, S → e เปนกฎในไวยากรณ และใหสายของโทเคนเปน ( ) ( ( ( ) ) ( ) )
ขนตอนวธจำลองการทำงานของออโตมาตาพชดาวนขางบนเลยนแบบการทำงานของออโตมาตาในตวอยาง 3.19 ดงแสดงตอไปน ขนตอนวธนอานสายของโทเคนจากซายไปขวาและสญลกษณทเปนตวหนาเปนโทเคนทอานมาเกบในตวแปร t คอลมนท 1 และ 2 ในตารางนแสดงคาในสแตคและโทเคนทอานเมอทำการ
หลกการและการประมวลภาษาโปรแกรม
43
วนซำหนงครง โทเคนทอานในขณะนนแสดงดวยตวอกขระเขม คอลมนท 3 อธบายการกระทำททำใหคาในสแตคเปลยน คอลมนท 4 เทยบการทำงานแตละขนกบการทำงานของออโตมาตาพชดาวน
สแตค d (top bottom)
S S ) S S S ) S S ) S ) S S ) S ) S ) S S ) S ) S S ) S S ) S ) S S ) S S empty
สายของโทเคน ( ) ( ( ( ) ) ( ) ) ( ) ( ( ( ) ) ( ) ) ( ) ( ( ( ) ) ( ) ) ( ) ( ( ( ) ) ( ) ) ( ) ( ( ( ) ) ( ) ) ( ) ( ( ( ) ) ( ) )
( ) ( ( ( ) ) ( ) ) ( ) ( ( ( ) ) ( ) ) ( ) ( ( ( ) ) ( ) ) ( ) ( ( ( ) ) ( ) ) ( ) ( ( ( ) ) ( ) ) empty
การกระทำ
(A) แทน S ดวย ( S ) S และ pop ( (B) แทน S ดวย e และ pop ( (C) แทน S ดวย ( S ) S และ pop ( (D) แทน S ดวย ( S ) S และ pop ( (E) แทน S ดวย ( S ) S และ pop ( (F) แทน S ดวย e และ pop ) (G) แทน S ดวย e และ pop ) (H) แทน S ดวย ( S ) S และ pop ( (I) แทน S ดวย e และ pop ) (J) แทน S ดวย e และ pop ) (K) แทน S ดวย e
การเปลยนสถานะ
ครงท 2-3 ครงท 4-5 ครงท 6-7 ครงท 8-9 ครงท 10-11 ครงท 12-13 ครงท 14-15 ครงท 16-17 ครงท 18-19 ครงท 20-21 ครงท 22
เราสามารถสรางตนไมแจงสวนจากบนลงลางระหวางการทำงานนไดดงแสดงในรปขางลาง สญลกษณแตละตวในสแตคแทนโหนดในตนไม เรมตนเมอ push สญลกษณเรมตนตวแรกมา เราใหสญลกษณเรมตนนนเปนรากของตนไม เมอเลอกกฎทแปลงสญลกษณบนสดของสแตคและ push สตรงทใชแทนในสแตค เราจะเพมโหนดสำหรบสญลกษณในสตรงในตนไมดวย ดงนนเมอสแตควางละใชโทเคนหมด ตนไมทไดเปนตนไมแจงสวนของสายของโทเคนทอานมา
Programming Language Principles and Processing
44
จากตวอยางนจะเหนวาการแทน (A) ใชกฎ S → (S)S แตการแทน (B) ใชกฎ S → e หากไมเลอกใช
กฎตามนแลวจะสรางตนไมแจงสวนไมได แตขนตอนทแสดงน ไมไดระบวาเลอกใชกฎใด ขนตอนวธแจงสวนแบบ LL(1) กำหนดใหเลอกกฎโดยพจารณาวาสามารถสรางสญลกษณถดไปตรงกบโทเคนทตองการได
3.4.2 ขนตอนวธแจงสวนแบบ LL(1)
ขนตอนวธแจงสวนแบบ LL(1) ใชกฎททำการแปลงแลวไดโทเคนทตองการเปนลำดบถดไปซงอธบายดวยแนวคดของ first set กบ follow set ดงตอไปน
First set
ถา N เปนสญลกษณไมปลายแลว first set ของ N (เขยนแทนดวย first(N)) เปนเซตของสญลกษณปลายทเปนสญลกษณแรกของสตรงทไดจากการแปลง N
ตวอยาง 3.21 กำหนดไวยากรณ S → ( S ) S, S → e
สตรงท ไดจากการแปลง S ไดแก e, (), ()(), (()), (()()), ... ดงน นสญลกษณ ( ตองอย ใน first(S) นอกจากนน e อยใน first(S) เพราะ S * e ดวย
เราสามารถนยาม first(N) เมอ N เปนสญลกษณไมปลายไดดงน
ให N เปนสญลกษณไมปลาย first(N) = {a| N * aB a เปนสญลกษณปลายและ B เปนสตรงใด ๆ} ถา N ไมสามารถแปลงเปน e ได first(N) = {a| N * aB a เปนสญลกษณปลายและ B เปนสตรงใด ๆ} U {e} ถา N แปลงเปน e ได
เราสามารถขยายนยามของ first ใหใชกบสญลกษณปลายไดดงน
first(N) = { N } เมอ N เปนสญลกษณปลาย
S
S S ( ) (A)
e
(B) S S ( )
(C)
S S ( ) (D)
S S ( ) (E)
S S ( ) (H)
e
(F) e
(G) e
(I) e
(J)
e
(K)
หลกการและการประมวลภาษาโปรแกรม
45
นอกจากนนเรายงสามารถนยาม first set ของสตรงไดดงน
ถา N เปนสตรงวาง แลว first(N) = {e}
ถา N = xY เปนสตรง และ x เปนสญลกษณใด ๆ แลว
- first(x)-{e} first(N) - first(Y) first(N) ถา e first(x) - e first(N) ถา e first(x) และ e first(Y) - สญลกษณอนทไมไดระบในเงอนไข 3 ขอน ไมอยใน first(N)
นอกจากนน เราสามารถนยาม first set จากกฎในไวยกรณไดดงน
ให N เปนสญลกษณไมปลาย และ N → X1 X2 … Xn โดยท X1 X2 … และ Xn เปนสญลกษณใด ๆ
- first(X1) – {e} first(N) - สำหรบ 1<i<n first(Xi) – {e} first(N) ถา e first(X1 X2 … Xi-1) - e first(N) ถา e first(X1 X2 … Xn)
จากนยามของ first set น เราสามารถสรางขนตอนวธการหา first set ไดดงน
ขนตอนวธการหา first set
1. FOR EACH non-terminal X: first(X) = {}
2. FOR EACH production L → e : first(L) = {e}
3. DO FOR EACH production L → R1 R2 … Rn :
i = 1 emptyPrefix = TRUE WHILE emptyPrefix AND i n :
first(L) = first(L) first(Ri) – {e} emptyPrefix = emptyPrefix AND (e first(Ri)) i = i+1
IF emptyPrefix : first(L) = first(L) {e}
WHILE there is a change in first(X), for some nonterminal X
ตวอยางตอไปนแสดงการคำนวณหา first set ดวยขนตอนวธขางบน
Programming Language Principles and Processing
46
ตวอยาง 3.22 กำหนดไวยากรณ G10 ทมกฎตอไปน E → F T, T → AD F T, T → e, AD → +, AD → -, F → L K, K → MUL L K, K → e, MUL → *, MUL → /, L → ( E ), L → id เราคำนวณหา first set ของสญลกษณไมปลายตามขนตอนวธขางบนนไดดงน
ขนท 1 กำหนดให first set ของสญลกษณไมปลายทกตวเปนเซตวาง ขนท 2 เพม e ใน first(T) และ first(K) set เพราะมกฎ T → e และ K → e ขนท 3 เราบอกจากกฎในไวยากรณไดวา
first(F)-{e} first(E), first(T)-{e} first(E) ถา e first(F), first(AD)-{e} first(T), {+, -} first(AD), first(L)-{e} first(F), first(K)-{e} first(F) ถา e first(L), {(, id} first(L), first(MUL)-{e} first(K) และ {*, /} first(MUL) ดงนน ในรอบท 1 จะได + และ - เพมใน first(AD), ( และ id เพมใน first(L), * และ / เพมใน
first(MUL) ในรอบท 2 จะได + และ - เพมใน first(T), ( และ id เพมใน first(F), * และ / เพมใน
first(K) ในรอบท 3 จะได ( และ id เพมใน first(E) ในรอบท 4 ไมมการเปลยนคา จงหยดทำงานได
ตารางตอไปนแสดง first set ทคำนวณไดในการทำงานแตละขนของขนตอนวธขางบน
Nonterminals ขนท 1 ขนท 2 ขนท 3 รอบท 1 ขนท 3 รอบท 2 ขนท 3 รอบท 3 ขนท 3 รอบท 4 E {} {} {} {} {(, id} {(, id} T {} {e} {e} {e, +, -} {e, +, -} {e, +, -}
AD {} {} {+, -} {+, -} {+, -} {+, -} F {} {} {} {(, id} {(, id} {(, id} K {} {e} {e} {e, *, /} {e, *, /} {e, *, /}
MUL {} {} {*, /} {*, /} {*, /} {*, /} L {} {} {(, id} {(, id} {(, id} {(, id}
หลกการและการประมวลภาษาโปรแกรม
47
Follow Set
ถา N เปนสญลกษณไมปลายแลว follow set ของ N (เขยนแทนดวย follow(N)) เปนเซตของสญลกษณปลายทอาจปรากฏอยหลง N ในการแปลงทเรมตนจากสญลกษณเรมตน
ตวอยาง 3.23 กำหนดไวยากรณ S → (S)S, S → e
สญลกษณ ) ตองอย ใน follow(S) เน องจาก S ท สรางจากกฎ S → (S)S ตองตามดวย ) เสมอ เนองจากเราตองตรวจสอบวาสายของโทเคนจบทใด เราใช $ แทนสญลกษณสนสดสายของโทเคน ดงนน $ อยใน follow(S) ดวยเพราะ S เปนสญลกษณเรมตนทแปลงไปจนไดสายของโทเคนทถกตองตามไวยากรณซงจบทายดวย $ เสมอ
เราสามารถนยาม follow set ของสญลกษณไมปลาย N ไดดงน
- a follow(N) ถา S * XNaY โดยท a เปนสญลกษณปลาย, S เปนสญลกษณเรมตน, X และ Y เปนสตรงใด ๆ
- $ follow(N) ถา S * XN โดยท S เปนสญลกษณเรมตน และ X เปนสตรงใด ๆ
นอกจากนน เราสามารถนยาม follow set จากกฎในไวยกรณไดดงน
- $ follow(S) ถา S เปนสญลกษณเรมตน - first(Y) – {e} follow(N) ถา L → XNY โดยท X และ Y เปนสตรงใด ๆ - follow(L) follow(N) ถา L → XN - follow(L) follow(N) ถา L → XNY และ e first(Y) โดยท X และ Y เปนสตรงใด ๆ
จากนยามของ follow set น เราสามารถสรางขนตอนวธการหา follow set ไดดงน
ขนตอนวธการหา follow set
1. FOR EACH non-terminal X: IF X is the start symbol:
follow(X) = {$} ELSE follow(X) = {}
2. DO FOR EACH production L → R1 R2 … Rn :
FOR EACH nonterminal Ri in R1 R2 … Rn : follow(Ri) = follow(Ri) (first(Ri+1 … Rn) – {e}) IF e first(Ri+1 … Rn) :
follow(Ri) = follow(Ri) follow(L) WHILE there is a change in follow (X), for some nonterminal X
ตวอยางตอไปนแสดงการคำนวณหา follow set ดวยขนตอนวธขางบน
Programming Language Principles and Processing
48
ตวอยาง 3.24 จากไวยากรณใน G10 ตวอยาง 3.22 ทมกฎตอไปน E → F T, T → AD F T, T → e, AD → +, AD → -, F → L K, K → MUL L K, K → e, MUL → *, MUL → /, L → ( E ), L → id และ first set ตอไปน
first(E) = {(, id}, first(T) = {e, +, -}, first(AD) = {+, -}, first(F) = {(, id }, first(K) = {e, *, / }, first(MUL) = {*, /}, first(L) = {(, id}
เราคำนวณหา follow set ของสญลกษณไมปลายตามขนตอนวธขางบนไดดงน
ขนท 1 กำหนดให follow set ของสญลกษณไมปลายทกตวเปนเซตวาง เวนแตสญลกษณเรมตน E ทมfollow set เปน {$}
ขนท 2 จากกฎทงหมด เราบอกไดวา
กฎ ความสมพนธทไดจากกฎ E → F T first(T) - {e} = {+, -} follow(F) follow(E) follow(T) follow(E) follow(F) since first(T) T → AD F T first(F) - {e} = {(, id} follow(AD) first(T) - {e} = {+, -} follow(F) follow(T) follow(F) F → L K first(K) – {e} = {+, -} follow(L) follow(F) follow(K) follow(F) follow(L) since e first(K) K → MUL L K first(K) – {e} = {*, /} follow(L) first(L) – {e} = {(, id} follow(MUL) follow(K) follow(L) since e first(K) L → ( E ) { ) } follow(E)
นนคอ {+, -, )} follow(T) follow(E) follow(F), follow(E) follow(T), {(, id} follow(AD), {*, /} follow(F) follow(K) follow(L), follow(F) follow(K), {(, id} follow(MUL) และ { ) } follow(E)
ดงนน ขนตอนวธคำนวณหา follow set ทำงานไดดงแสดงในตารางขางลางน โดยขนท 2 หยดทำงานในรอบท 3 ซงไมมการเปลยน follow set ของสญลกษณใด ๆ
ตารางตอไปนแสดง follow set ทคำนวณไดในการทำงานแตละขนของขนตอนวธขางบน
หลกการและการประมวลภาษาโปรแกรม
49
Nonterminals ขนท 1 ขนท 2 รอบท 1 ขนท 2 รอบท 2 ขนท 2 รอบท 3 E {$} {$, )} {$, )} {$, )} T {} {$} {$, )} {$, )}
AD {} {(, id} {(, id} {(, id} F {} {+, -, $} {+, -, $ )} {+, -, $ )} K {} {+, -, $} {+, -, $, )} {+, -, $, )}
MUL {} {(, id } {(, id } {(, id } L {} {+, -, *, /, $} {*, /, +, -, $, )} {*, /, +, -, $, )}
เมอออโตมาตาพชดาวนจำลองการแปลงมการเปลยนสถานะเชงไมกำหนดเมอมกฎในการแปลงสญลกษณไมปลาย N ทอยบนสดของสแตคใหเลอกมากกวาหนงกฎ ขนตอนวธแจงสวนแบบ LL(1) ใชโทเคนทอานไดถดไปมาชวยตดสนใจ หากโทเคนถดไปทอานไดเปนโทเคน X เราจะเลอกกฎทแปลง N เปนสตรงทข นตนดวย X ได กฎทแปลงสญลกษณ N ไปเปนสตรงวางจะใชเม อ การทำใหสญลกษณ N หายไปแลวสญลกษณ ทตามมาเปนสญลกษณทแปลงเปนสตรงทขนตนดวยโทเคน X ได จากหลกการทกลาวมาทงสองขอนเราสามารถอธบายวธการเลอกกฎของการแปลงจาก first set และ follow set ไดดงน
ให N เปนสญลกษณไมปลายทอยบนสดของสแตค และ T เปนสญลกษณปลายหรอโทเคนทอานไดถดไป
กฎ N → R จะใชได ถา
T อยใน first(R) หรอ e first(R) (นนคอ R * e) และ T อยใน follow(N)
ดงนน ขนตอนวธแจงสวนแบบ LL(1) ใชเกณฑการเลอกกฎการแปลงทกลาวมานรวมกบขนตอนวธจำลองการแปลงดวยออโตมาตาพชดาวน โดยใชตารางทเรยกวาตารางกฎการแจงสวน (parsing table) เปนทเกบกฎทใชในกรณตาง ๆ แยกตามสญลกษณไมปลายทอยบนสดของสแตคและโทเคนทอานได ตวอยางตอไปนแสดงการสรางตารางกฎการแจงสวน
ตวอยาง 3.25 จากไวยากรณในตวอยาง 3.22 ทมกฎ E → F T, T → AD F T, T → e, AD → +, AD → -, F → L K, K → MUL L K, K → e, MUL → *, MUL → /, L → ( E ), L → id และ first set กบ follow set ทคำนวณในตวอยาง 3.23 และ 3.24 ดงน
Nonterminals E T AD F K MUL L first {(, id} {e, +, -} {+, -} {(, id} {e, *, /} {*, /} {(, id}
follow {$, )} {$, )} {(, id} {+, -, $ )} {+, -, $, )} {(, id } {*, /, +, -, $}
Programming Language Principles and Processing
50
เราสรางตารางกฎการแจงสวนไดดงแสดงในรปขางลาง
Nonterminals id ( ) + - * / $ E E → F T E → F T T T → e T → AD F T T → AD F T T → e
AD AD → + AD → - F F → L K F → L K K K → e K → e K → e K → MUL L K K → MUL L K K → e
MUL MUL → * MUL → / L L → id L → ( E )
เมอสรางตารางกฎการแจงสวนแลวเราสามารถใชขนตอนวธจำลองการแปลงดวยออโตมาตาพชดาวน รวมกบการเลอกกฎดวยตารางกฎการแจงสวนดงแสดงขางลางน
1. push(d, S) // S เปนสญลกษณเรมตนและ d เปนสแตค 2. t = scan_next_token() 3. WHILE d ไมเปนสแตควาง และ t ไมเปน null
top = pop(d) IF top เปนสญลกษณไมปลาย
(top → body) = parseT(top ,t) // ทำการแปลง push(d, reverse(body))
ELSE // top เปน สญลกษณปลาย IF t==top // token t ตรงกบสญลกษณบนสดในสแตค
t = scan_next_token() // ทง token เดม ELSE // token t ไมตรงกบสญลกษณบนสดในสแตค
BREAK // มขอผดพลาด 4. IF d เปนสแตควาง และ t เปน null // ตรวจสอบ token ตรงกบทแปลงได
RETURN TRUE ELSE // ตรวจสอบ token ไมตรงกบทแปลงได
RETURN FALSE
ตวอยางตอไปนแสดงการแจงสวนแบบ LL(1)
ตวอยาง 3.26 การแจงสวนแบบ LL(1) ของสายของโทเคน id + id * ( id + id ) โดยใชตารางกฎการแจงสวนในตวอยาง 3.25 แสดงตามลำดบขนไดดงน
หลกการและการประมวลภาษาโปรแกรม
51
stack tokens action $ E id + id * ( id + id ) $ ใช E → F T $ T F id + id * ( id + id ) $ ใช F → L K $ T K L id + id * ( id + id ) $ ใช L → id $ T K id id + id * ( id + id ) $ ทง id ในสแตคและสายโทเคน $ T K + id * ( id + id ) $ ใช K → e $ T + id * ( id + id ) $ ใช T → AD F T $ T F AD + id * ( id + id ) $ ใช AD → + $ T F + + id * ( id + id ) $ ทง + ในสแตคและสายโทเคน $ T F id * ( id + id ) $ ใช F → L K $ T K L id * ( id + id ) $ ใช L → id $ T K id id * ( id + id ) $ ทง id ในสแตคและสายโทเคน $ T K * ( id + id ) $ ใช K → MUL id K $ T K L MUL * ( id + id ) $ ใช MUL → * $ T K L * * ( id + id ) $ ทง * ในสแตคและสายโทเคน $ T K L ( id + id ) $ ใช L → ( E ) $ T K ) E ( ( id + id ) $ ทง ( ในสแตคและสายโทเคน $ T K ) E id + id ) $ ใช E → F T $ T K ) T F id + id ) $ ใช F → L K $ T K ) T K L id + id ) $ ใช L → id $ T K ) T K id id + id ) $
Programming Language Principles and Processing
52
ทง id ในสแตคและสายโทเคน $ T K ) T K + id ) $ ใช K → e $ T K ) T + id ) $ ใช T → AD F T $ T K ) T F AD + id ) $ ใช AD → + $ T K ) T F + + id ) $ ทง + ในสแตคและสายโทเคน $ T K ) T F Id ) $ ใช F → L K $ T K ) T K L Id ) $ ใช L → id $ T K ) T K id Id ) $ ทง id ในสแตคและสายโทเคน $ T K ) T K ) $ ใช K → e $ T K ) T ) $ ใช T → e $ T K ) ) $ ทง ) ในสแตคและสายโทเคน $ T K $ ใช K → e $ T $ ใช T → e $ $ ยอมรบ
จากขนตอนวธการแจงสวนแบบ LL(1) ทอธบายไป จะเหนไดวาขนตอนวธนไมสามารถเลอกกฎเพอใชในการแปลงไดหากมกฎมากกวาหนงขอสำหรบบางชองในตารางกฎการแจงสวน หากไวยากรณใดทำใหตารางกฎการแจงสวนมกฎมากกวาหนงขอในชองใดชองหนง เราถอวาไวยากรณนนไมเปนไวยากรณแบบ LL(1) ตวอยางตอไปนแสดงการตรวจสอบวาไวยากรณเปนไวยากรณแบบ LL(1) หรอไมจากตารางกฎการแจงสวนแบบ LL(1)
ตวอยาง 3.27 กำหนดไวยากรณ G11 สำหรบนพจนทมตวกระทำ +, -, *, / และตวถกกระทำ id โดยม ( ) ทมลำดบความสำคญสงสด ตวกระทำ * และ / มลำดบความสำคญรองลงมา ตวกระทำ + และ – มลำดบความสำคญตำสด นอกจากนนตวกระทำทงหมดเปนชนดทมการเชอมโยงทางซายดงแสดงดวยกฎดงน
E → E AD F, E → F, AD → +, AD → -, F → F MUL L , F → L, MUL → *, MUL → /, L → ( E ), L → id
หลกการและการประมวลภาษาโปรแกรม
53
จากกฎชดนเราได first(E)=first(F)=first(L) = { (, id }, first(AD) = {+, -} และ first(MUL) = {*, /} ซงทำใหสรางตารางกฎแจงสวนดงน
Nonterminals id ( ) + - * / $ E E → E AD F
E → F E → E AD F
E → F
AD AD → + AD → - F F → F MUL L
F → L F → F MUL L
F → L
MUL MUL → * MUL → / L L → id L → ( E )
เน องจาก first(E) = first(F) = {id, ( } ดงน นกฎ E → E AD F และ E → F ใชไดเม อสญลกษณบนสแตคเปน E และโทเคนถดไปเปน id หรอ ( ทำนองเดยวกน เนองจากกฎ F → F MUL L และ F → L ใชไดเมอสญลกษณบนสแตคเปน F และโทเคนถดไปเปน id หรอ ( นนคอไวยากรณนไมเปนไวยากรณแบบ LL(1)
การเวยนซำทางซาย (left recursion)
ปญหาหนงของขนตอนวธแจงสวนแบบ LL(1) เกดจากกฎทอยในรปแบบของ N → N X เราเรยกกฎแบบนวาม การเวยนซำทางซาย (left recursion) เมอ N อยบนสดของสแตค และโทเคนทอานไดอย ใน first(N) กฎ N → N X จะถกใชในการแปลง การแปลงดวยกฎนแทน N ในสแตคดวย N X หลงจากการแปลงครงท 1 สญลกษณทอยบนสดของสแตคยงเปน N และโทเคนทอานไดยงอยใน first(N) ดงนนกฎ N → N X จะถกใชในการแปลงซำไปเรอย ๆ และ ขนตอนวธแจงสวนแบบ LL(1) ไมสามารถทำงานได
เนองจากกฎทมการเวยนซำทางซายทำใหขนตอนวธแจงสวนแบบ LL(1) เราตองเขยนกฎใหสามารถอธบายไวยากรณไดเหมอนเดมแตไมมการเวยนซำทางซาย จากกฎ N → N X จะเหนวาตองมกฎ N → Y สำหรบสตรง Y ทไมขนตนดวย N ดวยจงจะใชอธบายภาษาได จากกฎ N → N X และ N → Y จะเหนไดวา N * Y X* ดงนนเราสามารถใชกฎตอไปนอธบาย N
N → Y K K → X K K → e
ตวอยาง 3.28 ไวยากรณ G11 ในตวอยาง 3.27 มการเวยนซำทางซาย เราสามารถกำจดการเวยนซำทางซายไดโดยแปลง
E → E AD F, E → F เปน E → F T, T → AD F T, T → e
และแปลง
Programming Language Principles and Processing
54
F → F MUL L, F → L เปน F → L K, K → MUL L K, K → e
ไวยากรณท ไดจากการกำจดการเวยนซำทางซายน คอไวยากรณ G10 ในตวอยาง 3.22 ทเปนไวยากรณแบบ LL(1) ดงแสดงในตารางกฎการแจงสวนแบบ LL(1) ในตวอยาง 3.25
หากมกฎทมการเวยนซำทางซายมากกวาหนงกฎดงน
N → N X1 N → N X2 ... N → N Xn
และมกฎทไมมการเวยนซำทางซายสำหรบ N ดงน
N → Y1 N → Y2 ... N → Ym
เราสามารถใชกฎตอไปนอธบาย N
N → Y1 K N → Y2 K ... N → Ym K K → X1 K K → X2 K ... K → Xn K K → e
นอกจากนนยงมการเวยนซำทางซาย ทผานสญลกษณไมปลายมากกวาหนงตว นนคอ N * N X ในกรณการกำจดการเวยนซำทางซายจะซบซอนมากขนและจะไมขออธบายไวในทน
การดงตวรวมทางซาย (Left factoring)
ขนตอนวธการแจงสวนแบบ LL(1) ทำงานไดถกตองเมอมกฎทเลอกใชในแตละขนตอนเพยงกฎเดยว สาเหตหนงททำใหเลอกใชกฎไดมากกวาหนงกฎในการแปลงคอ มกฎมากกวาหนงกฎททางซายเปนสญลกษณเดยวกนและ ดานขวาของกฎเรมตนดวยสญลกษณเดยวกนดวย เชน กฎ N → X Y และ N → X Z เมอ
หลกการและการประมวลภาษาโปรแกรม
55
สญลกษณทอยบนสดของสแตคเปน N และโทเคนทอานไดอยใน first(X) เราอาจเลอกกฎไดกฎหนงใชไดเชนกน ปญหานแกไดโดยเขยนกฎใหมดงน
N → X R, R → Y, R → Z
วธนเรยกวาการดงตวรวมทางซาย (left factoring) ตวอยางตอไปนแสดงการดงตวรวมทางซาย
ตวอยาง 3.29 ไวยากรณ G9 ในตวอยาง 3.16 เปนไวยากรณไมกำกวม แตไวยากรณนยงมตวรวมทางซายในกฎ Unmatched → if K Matched และ Unmatched → if K Matched else Unmatched เมอสรางตารางการแจงสวนแบบ LL(1) จะไดวากฎทใชสำหรบสญลกษณไมปลาย Unmatched และโทเคน if ม 2 กฎ คอ Unmatched → if K Matched และ Unmatched → if K Matched else Unmatched ดงแสดงในตารางขางลางน
Tokens Nonterminals if else id …
Unmatched Unmatched → if K Matched Unmatched → if K Matched else Unmatched
Matched Matched → if K Matched else Matched Matched → As …
เราจะดงตวรวมทางซายและแทนดวย Unmatched → if K Matched Elsepart, Elsepart → e และ Elsepart → else Unmatched เม อสรางตารางการแจงสวนแบบ LL(1) จะไดว ากฎท ใชสำหรบส ญลกษณไม ปลาย Unmatched และโทเคน if มเพยงกฎเด ยว ค อ Unmatched → if K Matched elsepart สวน Elsepart → else Unmatched ใชสำหรบสญลกษณไมปลาย Elsepart และโทเคน else และ Elsepart → e ใชสำหรบสญลกษณไมปลาย Elsepart และโทเคนทเปนสญลกษณแรกของคำสง เชน if, id ดงแสดงในตารางขางลางน
Tokens Nonterminals
if else id …
Unmatched Unmatched → if K Matched Elsepart Elsepart Elsepart → e Elsepart → else Unmatched Elsepart → e Matched Matched → if K Matched else Matched Matched → As …
ดงนนเมอตองการสรางตวแจงสวนแบบ LL(1) จะตองเรมจากไวยากรณทไมกำกวม (ไวยากรณกำกวมจะไมเปนไวยากรณแบบ LL(1)) จากนนจงตรวจสอบวา ไวยากรณนนมการเวยนซำทางซายหรอไม หากมกใหนำไวยากรณนนมากำจดการเวยนซำทางซาย แลวจงนำไปดงตวรวมทางซาย ถาม สำหรบสองขนตอนนเราจะตองกำจดการเวยนซำทางสายกอนดงตวรวมทางซาย เพราะเมอกำจดการเวยนซำทางซายแลวอาจไดกฎทมตวรวมทางซาย จากนนเราจงสรางตารางกฎการแจงสวนแบบ LL(1) แลวตรวจสอบวา เปนไวยากรณแบบ
Programming Language Principles and Processing
56
LL(1) หรอไม โดยตรวจสอบวาตารางกฎการแจงสวนแบบ LL(1) มชองทมกฎมากกวาหนงกฎหรอไม หากเปนไวยากรณแบบ LL(1) กใชตารางนสำหรบขนตอนการแจงสวนแบบ LL(1) ได
3.5 ขนตอนวธแจงสวนแบบ SLR(1)
การแจงสวนแบบ LR เปนการแจงสวนจากลางขนบน (bottom-up parsing) นนคอตนไมแจงสวนถกสรางจากใบขนไปสราก โทเคนถกอานจากซายไปขวาและสรางเปนใบของตนไมแจงสวน ระหวางการทำงาน เราจะไดตนไมยอยหลายตนทนำมาประกอบกนเปนตนไมทใหญขนเรอย ๆ การเลอกกฎทใชสรางตนไมพจารณาจากดานขวาของกฎวาตรงกบโหนดทมอยในขณะนนหรอไม หากโหนดในระดบสงสดของตนไมยอย ๆ เรยงกนไดเปน X Y Z ... และมกฎ A → X Y Z เราจะเลอกกฎนเพอสรางตนไมทมโหนด A เปนรากและ โหนด X, Y, Z เปนลกของโหนด A ดงแสดงในรปขางลาง การสรางตนไมแจงสวนนเสรจสมบรณเมอโหนดใบทงหมดรวมอยในตนไมตนเดยว
3.5.1 หลกการทำงานของการแจงสวนแบบ LR
ขนตอนวธแจงสวนแบบ LR ใชสแตคเพอเกบโหนดรากของตนไมยอยทสรางมาและใชออโตมาตาจำกดเพอจำวาโหนดรากทสรางมาเรยงตอกนเปนสวนของดานขวาของกฎไดบาง
การแจงสวนแบบ LR ทำงานเลยนแบบการแปลงขวาสด (rightmost derivation) ยอนจากขนสดทายไปถงขนแรก ในแตละขนเราเลอกระหวางการทำงานสองแบบ คอ การเลอน (shift) และ การลด (reduce) การเลอนเปนการเอาโทเคนทอานไวใสลงในสแตค การลดเปนการแทนสตรงทอยบนสดของสแตค ดวยสญลกษณไมปลาย การลดนตองเปนไปตามกฎในไวยากรณ เชน การลดตามกฎ A → X Y Z ทำไดเมอ Z Y X (อานจากบนลงลาง) อยบนสดของสแตคและเราลด Z Y X ไปเปน A การลดในทนเทยบไดกบการแปลงทใชกฎ A → X Y Z
ตวอยางตอไปนแสดงการแจงสวนแบบ LR ดวยการเลอนและการลด พรอมทงเปรยบเทยบกบการแปลงขวาสด
ตวอยาง 3.30 กำหนดไวยากรณ G ทมกฎ S → ( S ) S, S → e และสายของโทเคน ( ( ) ) ( ) การแจงสวนดวยการเลอนและการลดแสดงเทยบกบการแปลงขวาสดไดดงน
A
X Y Z … …
หลกการและการประมวลภาษาโปรแกรม
57
สแตค (ลาง -> บน) สายของโทเคน การกระทำ การแปลง $ ( ( ) ) ( ) $ เลอน $ ( ( ) ) ( ) $ เลอน $ ( ( ) ) ( ) $ ( ( ) ) ( ) ลด S → e $ ( ( S ) ) ( ) $ เลอน $ ( ( S ) ) ( ) $ ( ( S ) ) ( ) ลด S → e $ ( ( S ) S ) ( ) $ ( ( S ) S ) ( ) ลด S → ( S ) S $ ( S ) ( ) $ เลอน $ ( S ) ( ) $ เลอน $ ( S ) ( ) $ ( S ) ( ) ลด S → e $ ( S ) ( S ) $ เลอน $ ( S ) ( S ) $ ( S ) ( S ) ลด S → e $ ( S ) ( S ) S $ ( S ) ( S ) S ลด S → ( S ) S $ ( S ) S $ ( S ) S ลด S → ( S ) S $ S S
สงเกตวา การแปลงทแสดงขางบนสรางเปนตนไมแจงสวนไดดงน
SD
) ( eD
( ) ) (
SD
) ( eD
( ) ) (
S
eD
1
2
SD
) ( eD
( ) ) (
S
eD
S 3
SD
) ( eD
( ) (
S
eD
S
S
eD
) 4
1
2
3
4
5
6
7
Programming Language Principles and Processing
58
ขอสงเกต:
- การลดใชกบสตรงในสแตค ดงนนเราตองใสโทเคนในสแตคดวยการเลอนกอน - สตรงในสแตค (อานจากลางขนบน) ตอกบโทเคนทยงไมไดอาน รวมกนเปนแบบประโยค - เราเรยกการแจงสวนแบบ LR วา การแจงสวนแบบเลอนลด (shift-reduce parsing) เพราะทำงานดวย
การเลอนและการลด
3.5.2 ออโตมาตาจำกดของรายการ
ในการแจงสวนแบบ LR เรายงตองตดสนใจในแตละขนวาจะเลอนหรอลด ถาจะลดเราตองใชกฎใดในไวยากรณ หวขอนอธบายออโตมาตาจำกดทใชในการตดสนใจน
รายการ LR(0) (LR(0) item)
การแจงสวนแบบ LR อาจเลอกทำการลดไดเมอสงทอยบนสดของสแตคตรงกบดานขวาของกฎบางกฎในไวยากรณ อยางไรกตาม ตวแจงสวนอาจยงไมทำการลดแตเลอนโทเคนลงมาในสแตคเพอใชกฎอนตอไปกได เราจะสรางออโตมาตาจำกดทใชชวยตดสนใจเลอกระหวางการเลอนและการลดดวยกฎแตละกฎในไวยากรณ ออโตมาตานใชจำวาสตรงทอยบนสดของสแตคตรงกบดานขวาของกฎใดบาง รายการ LR(0) บอกวาสตรงทอยบนสดของสแตคตรงกบสวนหนา (prefix) ใดในดานขวาของกฎโดยสญลกษณ แสดงตำแหนงแยก (distinguished position) วาสวนหนาทอยในสแตคกบสวนทเหลอ
- รายการ L → X Y Z เปนรายการ LR(0) ทบอกวาสตรงทอยหนา (คอ X Y) เปนสตรงทอยบนสดของสแตค (นนคอไดสรางสวนของตนไมแจงสวนทมโหนดรากเปน X และ Y แลว) และจะใชกฎ L → X Y Z ทำการลดไดเมอสรางสตรงทอยหลง (คอ Z) ได
- รายการ L → X Y Z เปนรายการ LR(0) ทบอกวาสรางสตรง X Y Z ไวในสแตคแลว (นนคอไดสรางสวนของตนไมแจงสวนทมโหนดรากเปน X, Y และ Z แลว) ดงนนจะใชกฎ L → X Y Z ทำการลดได
ดงนน รายการ LR(0) ของไวยากรณใด ๆ ประกอบดวยกฎในไวยากรณทระบตำแหนงแยกในทกตำแหนงทเปนไปไดของกฎ เชน รายการ LR(0) ทสรางจากกฎ L → X Y Z คอ L → X Y Z, L → X Y Z, L → X Y Z และ L → X Y Z สวนรายการ LR(0) ทสรางจากกฎ L → e คอ L → เพราะสตรงวางมความยาว 0 จงมตำแหนงแยกไดตำแหนงเดยว
SD
) ( eD
( ) (
S
eD
S
S
eD
) eD
S
5
SD
) ( eD
( ) (
S
eD
S
S
eD
) eD
S
6 S
SD
) ( eD
( ) (
S
eD
S
S
eD
) eD
S
7
S
S
หลกการและการประมวลภาษาโปรแกรม
59
ตวอยาง 3.31 ไวยากรณทมกฎ S → ( S ) S, S → e มรายการ LR(0) ตอไปน
S → ( S ) S, S → ( S ) S, S → ( S ) S, S → ( S ) S, S → ( S ) S และ S →
ไวยากรณทมกฎ E → E + n, E → E * n, E → n มรายการ LR(0) ตอไปน
E → E + n, E → E + n, E → E + n, E → E + n , E → E * n, E → E * n, E → E * n, E → E * n , E → n และ E → n
รายการ LR(0) ทมตำแหนงแยกอยหนาสญลกษณแรกในกฎ เรยกวา รายการเรม (initial item) เปนรายการทแสดงวาจะเรมพจารณาสรางตนไมยอยของสญลกษณทางซายของกฎไดหรอไม
รายการ LR(0) ทมตำแหนงแยกอยหลงสญลกษณสดทายในกฎ เรยกวา รายการสมบรณ (complete item) เปนรายการทแสดงวาในสแตคเกบสตรงทางขวาของกฎนนไดสมบรณแลว ดงนนอาจเลอกใชกฎนนในการลด
ตวอยาง 3.32 จากตวอยาง 3.31 ไวยากรณทมกฎ S → ( S ) S, S → e มรายการเรมตน
S → ( S ) S และ S →
มรายการสมบรณ S → ( S ) S และ S →
ไวยากรณทมกฎ E → E + n, E → E * n, E → n มรายการเรมตน E → E + n, E → E * n และ E → n
มรายการสมบรณ E → E + n , E → E * n และ E → n
ออโตมาตาจำกดของรายการ LR(0)
เราสรางออโตมาตาจำกดเพอจำวาตวแจงสวนสรางตนไมยอยใดไดแลวบาง ดงนนแตละสถานะของออโตมาตาจำกดจำรายการ LR(0) แตละรายการ ออโตมาตาจะเปลยนสถานะจากสถานะของ L → X Y Z ไปยงสถานะของ L → X Y Z เมอไดสญลกษณ Y ซงอาจเปนสญลกษณปลาย (คอโทเคน) หรอสญลกษณไมปลาย
- ถา Y เปนโทเคน การเปลยนจากสถานะของ L → X Y Z ไปยงสถานะของ L → X Y Z เกดเมอตวแจงสวนเลอนโทเคน Y ลงในสแตค
- ถา Y เปนสญลกษณไมปลาย การเปลยนจากสถานะของ L → X Y Z ไปยงสถานะของ L → X Y Z เกดเมอตวแจงสวนใส Y ลงในสแตคโดยการลดสตรงบนสแตคเปน Y
นอกจากนน เมอ Y เปนสญลกษณไมปลาย ออโตมาตาอาจเปลยนจากสถานะ L → X Y Z ไปยงสถานะของ Y → P Q ดวยสตรงวาง การเปลยนสถานะนเปนการเปลยนสถานะเชงไมกำหนด คอ เลอก
Programming Language Principles and Processing
60
เปลยนสถานะเมอรลวงหนา (ดวยความสามารถเชงไมกำหนด) วาตองสรางสญลกษณ Y ดวยการลดในอนาคตเพอรายการทม Y หลงตำแหนงแยก เชน L → X Y Z
ตวอยางตอไปนแสดงการสรางออโตมาตาจำกดของรายการ LR(0)
ตวอยาง 3.33 ไวยากรณทมกฎ S → ( S ) S, S → e มรายการ LR(0) ตอไปน
S → ( S ) S, S → ( S ) S, S → ( S ) S, S → ( S ) S, S → ( S ) S และ S →
และมการเปลยนสถานะในออโตมาตาจำกดดงแสดงในรปขางลางน
จากตวอยาง 3.33 ออโตมาตาทสรางมานยงไมมสถานะเรมตน สถานะเรมตนควรมรายการท ใชในการแปลงครงแรกทอยทรากของตนไมแจงสวน ดงนนจงอาจเปนรายการเรมตนทสรางจากกฎทมสญลกษณเรมตนอยทางซายซงอาจมไดมากกวาหนงกฎ ดงนนเราจะเพมสญลกษณ S' เปนสญลกษณเรมตนใหมและกฎ S' → S เมอ S เปนสญลกษณเรมตนเกา การเพมกฎนในไวยากรณไมทำใหภาษาเปลยนไป แตการแปลงดวยไวยากรณนเรมตนดวยการใชกฎ S' → S เสมอเพราะมเพยงกฎเดยวทใช S' ไวยากรณทเพมกฎนไปเรยกวาไวยากรณเสรม (augmented grammar)
กฎทเสรมมาทำใหมรายการ S' → S และ S' → S เพมมา เราสรางออโตมาตาจากไวยากรณเสรมตามทอธบายกอนนและใหสถานะของ S' → S เปนสถานะเรมตนไดดงแสดงในรปขางลางน สถานะทเพมขนมาแสดงดวยการแรเงา
ออโตมาตานเปนออโตมาตาจำกดเชงไมกำหนดซงทำใหการสรางโปรแกรมจากออโตมาตานซบซอน ดงนนเราจะแปลงออโตมาตาน เปนออโตมาตาจำกดเชงกำหนดโดยหาสวนปดคลม (closure) ของแตละสถานะ (ดจากตำราเกยวกบออโตมาตาจำกดทวไป) และใหสถานะของออโตมาตาจำกดเชงกำหนดแทนสวนปดคลมของสถานะของออโตมาตาจำกดเชงไมกำหนดดงแสดงในตวอยางตอไปน
S → ( S ) S S → ( S ) S S → ( S ) S
S → S → ( S ) S S → ( S ) S S
( e
S
e e
e )
S → ( S ) S S → ( S ) S S → ( S ) S
S → S → ( S ) S S → ( S ) S S
( e
S
e e
e )
S' → S
S' → S
e
e
S
หลกการและการประมวลภาษาโปรแกรม
61
ตวอยาง 3.34 จากออโตมาตาจำกดเชงไมกำหนดในตวอยาง 3.33 เราหาสวนปดคลมของแตละสถานะไดดงแสดงในตารางขางลางน
สถานะในออโตมาตาจำกดเชงไมกำหนด
สวนปดคลม สถานะในออโตมาตา
จำกดเชงกำหนด S' → S S' → S, S → ( S ) S, S → 0 S' → S S' → S 5 S → ( S ) S S → ( S ) S ไมเกดในการทำงาน S → ( S ) S S → ( S ) S, S → ( S ) S, S → 1 S → ( S ) S S → ( S ) S 2 S → ( S ) S S → ( S ) S, S → ( S ) S, S → 3 S → ( S ) S S → ( S ) S 4 S → S → ไมเกดในการทำงาน
เราสรางออโตมาตาจำกดเชงกำหนดโดยใหแตละสถานะแทนสวนปดคลมของสถานะของออโตมาตาจำกดเชงไมกำหนดจากตารางขางบน การเปลยนสถานะของออโตมาตาจำกดเชงกำหนดแสดงในรปขางลาง
จากออโตมาตาขางบน สถานะ 6 และ 7 ไมอยในออโตมาตาจำกดเชงกำหนดนเนองจากรายการ S → ( S ) S และ S → ไมเกดแยกกบรายการอน จงไมแสดงไวในรป
รายการในสวนปดคลมทมาจากออโตมาตาจำกดเชงไมกำหนดเรยกวา รายการแกน (kernel item) ซงแสดงดวยตวเอยงในรปขางบน สงเกตวาถาสถานะ 2 สถานะมรายการแกนเหมอนกนแลวจะตองมสวนปดคลมเหมอนกนและเปนสถานะเดยวกน
3.5.3 การสรางตารางการแจงสวนแบบ SLR(1)
ตวแจงสวนสามารถใชออโตมาตาของรายการเพอจำวาสวนของแบบประโยคทสรางไวในสแตคตรงกบสวนหนาของสตรงทางขวาในกฎใด ดงนนตวแจงสวนจะดวาออโตมาตาอยในสถานะใดโดยไมตองเขาไปในสแตค ตวแจงสวนสามารถตดสนใจวาจะทำการเลอนหรอลดโดยดจากรายการในสถานะของออโตมาตาดงน
S → ( S ) S S → ( S ) S S →
S → ( S ) S
S → ( S ) S S → ( S ) S S →
S → ( S ) S
S
( S
)
S' → S
S' → S S → ( S ) S S →
S
(
( 0 1
2
3 4 5
0
5
1
2
3
4
Programming Language Principles and Processing
62
- สถานะทมรายการสมบรณ X → y แสดงวา สแตคมสตรงท y อย ดงนนตวแจงสวนสามารถใชกฎของรายการดงกลาวทำการลดเมออยในสถานะนนได หากพจารณาโทเคนถดไปประกอบดวย จะเหนวาการลดนนทำใหสรางตนไมแจงสวนตอไปไดหากโทเคนถดไปอยใน follow(X)
- เมอตวแจงสวนอยในสถานะทมรายการ X → w Y z แสดงวามสตรง w ในสแตคแลว ถา Y เปนสญลกษณปลายทตรงกบโทเคนถดไป ตวแจงสวนอาจเลอนโทเคน Y ใสลงในสแตค เพอใหม w Y ในสแตค หากโทเคนถดไปไมใช Y ตวแจงสวนไมสามารถเลอนโทเคนนนลงในสแตคไดเพราะจะไมสามารถทำใหสแตคตรงกบขวามอของกฎนนได
- เมอตวแจงสวนอยในสถานะทมรายการ X → w Y z แสดงวามสตรง w ในสแตคแลว ถา Y เปนสญลกษณไมปลายและไดสญลกษณนนใสเพมมาในสแตคจากการลด ตวแจงสวนเปลยนสถานะหลงการลดททำใหไดสญลกษณไมปลายนนไปยงสถานะทมรายการ X → w Y z
ตวแจงสวนแบบ simple LR(1) หรอ SLR(1) ใชการแจงสวนแบบ LR อยางงายทดโทเคนลวงหนา 1 ตวรวมกบออโตมาตาของรายการดงทกวามา จากออโตมาตาของรายการ เราสรางตารางการแจงสวนแบบ SLR(1) ทระบการทำงาน (การเลอนหรอการลด) ของตวแจงสวนเมอไดสญลกษณหนงและออโตมาตาอยในแตละสถานะดงแสดงในตวอยางตอไปน
ตวอยาง 3.35 จากออโตมาตาจำกดเชงกำหนดในตวอยาง 3.34 เราสรางตารางการแจงสวนแบบ SLR(1) ไดดงแสดงในตารางขางลางน
Symbol State
( ) $ S
0 shift & goto 1 reduce: S → reduce: S → goto 5 1 shift & goto 1 reduce: S → reduce: S → goto 2 2 shift & goto 3 3 shift & goto 1 reduce: S → reduce: S → goto 4 4 reduce: S → ( S ) S reduce: S → ( S ) S 5 accept
จากออโตมาตาจำกดเชงกำหนดในตวอยาง 3.34 ตารางการแจงสวนแบบ SLR(1) สรางไดดงน
ทสถานะ 0 - จากรายการ S → ( S ) S ถาโทเคนถดไปเปนสญลกษณ ( แลวออโตมาตาจะเปลยนไปยงสถานะ 1 และ
ตวแจงสวนจะเลอน ( พรอมกบสถานะ 1 ของออโตมาตาลงในสแตค (shift & goto 1) - จากรายการ S' → S เมอตวแจงสวนไดสญลกษณ S จากการลด ออโตมาตาจะเปลยนไปยงสถานะ 5
และตวแจงสวนจะเลอน S พรอมกบสถานะ 5 ของออโตมาตาลงในสแตค (goto 5) - จากรายการ S → ถาโทเคนถดไปเปนสญลกษณ ) หรอ $ ทอยใน follow(S) ตวแจงสวนจะทำการลด
ดวยกฎ S → โดย pop สตรงวางออกจากสแตค (reduce: S → ) นนคอไมเปล ยนสแตค ดงนน
หลกการและการประมวลภาษาโปรแกรม
63
สถานะของออโตมาตาจะถอยไปตามท pop สตรงออกจากสแตค แลวจงเปลยนสถานะตามสญลกษณ S ทลงในสแตค
ทสถานะ 1 - จากรายการ S → ( S ) S เมอตวแจงสวนไดสญลกษณ S จากการลด ออโตมาตาจะเปลยนไปยงสถานะ
2 และตวแจงสวนจะเลอน S พรอมกบสถานะ 2 ของออโตมาตาลงในสแตค (goto 2) - จากรายการ S → ( S ) S ถาโทเคนถดไปเปนสญลกษณ ( แลวออโตมาตาจะเปลยนไปยงสถานะ 1 และ
ตวแจงสวนจะเลอน ( พรอมกบสถานะ 1 ของออโตมาตาลงในสแตค (shift & goto 1) ทำนองเดยวกบทสถานะ 0
- จากรายการ S → ถาโทเคนถดไปเปนสญลกษณ ) หรอ $ ทอยใน follow(S) ตวแจงสวนจะทำการลดดวยกฎ S → (reduce: S → ) ทำนองเดยวกบทสถานะ 0
ทสถานะ 2 - จากรายการ S → ( S ) S ถาโทเคนถดไปเปนสญลกษณ ) แลวออโตมาตาจะเปลยนไปยงสถานะ 3 และ
ตวแจงสวนจะเลอน ) พรอมกบสถานะ 3 ของออโตมาตาลงในสแตค (shift & goto 3) ทสถานะ 3 - จากรายการ S → ( S ) S เมอตวแจงสวนไดสญลกษณ S จากการลด ออโตมาตาจะเปลยนไปยงสถานะ
4 และตวแจงสวนจะเลอน S พรอมกบสถานะ 4 ของออโตมาตาลงในสแตค (goto 4) - จากรายการ S → ( S ) S ถาโทเคนถดไปเปนสญลกษณ ( แลวออโตมาตาจะเปลยนไปยงสถานะ 1 และ
ตวแจงสวนจะเลอน ( พรอมกบสถานะ 1 ของออโตมาตาลงในสแตค (shift & goto 1) ทำนองเดยวกบทสถานะ 0
- จากรายการ S → ถาโทเคนถดไปเปนสญลกษณ ) หรอ $ ทอยใน follow(S) ตวแจงสวนจะทำการลดดวยกฎ S → (reduce: S → ) ทำนองเดยวกบทสถานะ 0
ทสถานะ 4 - จากรายการ S → ( S ) S ถาโทเคนถดไปเปนสญลกษณ ) หรอ $ ทอยใน follow(S) ตวแจงสวนจะทำ
การลดดวยกฎ S → ( S ) S โดย pop สตรง ( S ) S ออกจากสแตค (reduce: S → ( S ) S ) ดงนนสถานะของออโตมาตาจะถอยไปตามท pop สตรงออกจากสแตค แลวจงเปลยนสถานะตามสญลกษณ S ทลงในสแตค
ทสถานะ 5 - จากรายการ S' → S เมอตวแจงสวนไดสญลกษณ $ ทบอกวาอานสายของโทเคนหมดแลว ตวแจงสวน
จะยอมรบสายของโทเคนทอานมา และ สงตนไมแจงสวนกลบไป
ตวอยางตอไปนแสดงการแจงสวนแบบ SLR(1) โดยใชตารางการแจงสวนในตวอยาง 3.35 สแตคเกบสญลกษณซงเปนโหนดในตนไมแจงสวนคกบสถานะ เชน S 2 หมายถง โหนดทเกบสญลกษณ S กบสถานะ 2
ตวอยาง 3.36 จากตารางการแจงสวนในตวอยาง 3.35 หากใหสายของโทเคนทนำไปสรางตนไมแจงสวนเปน ( ( ) ) ( ) จะมการทำงานดงแสดงตอไปน
Programming Language Principles and Processing
64
สแตค (ลาง -> บน) สายของโทเคน การกระทำ การแปลง $ 0 ( ( ) ) ( ) $ เลอน $ 0 ( 1 ( ) ) ( ) $ เลอน $ 0 ( 1 ( 1 ) ) ( ) $ ( ( ) ) ( ) ลด S → $ 0 ( 1 ( 1 S 2 ) ) ( ) $ เลอน $ 0 ( 1 ( 1 S 2 ) 3 ) ( ) $ ( ( S ) ) ( ) ลด S → $ 0 ( 1 ( 1 S 2 ) 3 S 4 ) ( ) $ ( ( S ) S ) ( ) ลด S → ( S ) S $ 0 ( 1 S 2 ) ( ) $ เลอน $ 0 ( 1 S 2 ) 3 ( ) $ เลอน $ 0 ( 1 S 2 ) 3 ( 1 ) $ ( S ) ( ) ลด S → $ 0 ( 1 S 2 ) 3 ( 1 S 2 ) $ เลอน $ 0 ( 1 S 2 ) 3 ( 1 S 2 ) 3 $ ( S ) ( S ) ลด S → $ 0 ( 1 S 2 ) 3 ( 1 S 2 ) 3 S 4 $ ( S ) ( S ) S ลด S → ( S ) S $ 0 ( 1 S 2 ) 3 S 4 $ ( S ) S ลด S → ( S ) S $ 0 S 5
$ ยอมรบ
S
สงเกตการลด S → ครงแรก สแตคเปลยนจาก $ 0 ( 1 ( 1 เปน $ 0 ( 1 ( 1 S 2 เพราะ pop ออกจากสแตคคอไมมการเปลยนสแตค ดงนนออโตมาตาอยทสถานะ 1 และเมอได S จงเปลยนไปอยในสถานะ 2 ตามทระบในตารางการแจงสวน
สงเกตการลด S → ( S ) S คร งแรก สแตคเปล ยนจาก $ 0 ( 1 ( 1 S 2 ) 3 S 4 เปน $ 0 ( 1 S 2 เพราะ pop ( S ) S ออกจากสแตคพรอมทงสถานะทอยคกน เหลอ $ 0 ( 1 ในสแตค จากตารางการแจงสวน เมออยทสถานะ 1 และได S จงเปลยนไปอยในสถานะ 2 ดงนนจงใส S 2 ลงในสแตค
ตารางการแจงสวนแบบ SLR(1) ระบวาตวแจงสวนจะเลอกทำการเลอนหรดลดดวยกฎใด ชองทไมระบวาตวแจงสวนสามารถเลอกทำงานอยางไร หมายถง สถานการณทมขอผดพลาดทางไวยากรณ (syntax error) ในสายของโทเคนดงแสดงในตวอยางตอไปน
1
2
3
4
5
6
7
หลกการและการประมวลภาษาโปรแกรม
65
ตวอยาง 3.37 จากตารางการแจงสวนในตวอยาง 3.35 หากใหสายของโทเคนทนำไปสรางตนไมแจงสวนเปน ( ) ) ทไมถกตองตามไวยากรณทกำหนด การแจงสวนจะเปนดงน
สแตค (ลาง -> บน) สายของโทเคน การกระทำ การแปลง $ 0 ( ) ) $ เลอน $ 0 ( 1 ) ) $ ลด S → $ 0 ( 1 S 2 ) ) $ ( ( ) ) ( ) เลอน $ 0 ( 1 S 2 ) 3 ) $ ลด S → $ 0 ( 1 S 2 ) 3 S 4 ) $ ( ( S ) ) ( ) ลด S → ( S ) S $ 0 S 5 ) $ ( ( S ) S ) ( ) ผดไวยากรณ
เมออยทสถานะ 5 และไดโทเคน ) ตารางแจงสวนไมมการทำงานทใชได นนคอมขอผดพลาดทางไวยากรณ
การแจงสวนแบบ SLR(1) มความสามารถมากกวาการแจงสวนแบบ LL(1) เพราะสามารถใชกบไวยากรณทมตวรวมทางซายไดดงแสดงในตวอยางตอไปน
ตวอยาง 3.38 กำหนดไวยากรณทมตวรวมทางซายดงน
E → E + n, E → E * n, E → n
และมรายการ LR(0) ตอไปน
E → E + n, E → E + n, E → E + n, E → E + n , E → E * n, E → E * n, E → E * n, E → E * n , E → n และ E → n
เราสามารถสรางออโตมาตาจำกดเชงไมกำหนดของรายการ LR(0) ไดดงแสดงในรปขางลางน
Programming Language Principles and Processing
66
ออโตมาตาจำกดเชงไมกำหนดนแปลงเปนออโตมาตาจำกดเชงกำหนดดงแสดงขางลาง
เราสรางตารางการแจงสวนแบบ SLR(1) จากออโตมาตาจำกดเชงกำหนดนและการหา follow(E) = {+, *, $} ไดดงน
Symbol State n + * $ E
0 shift & goto 6 goto 1 1 shift & goto 2 shift & goto 3 accept 2 shift & goto 4 3 shift & goto 5 4 reduce:E → E + n reduce: E → E + n reduce: E → E + n 5 reduce:E → E * n reduce: E → E * n reduce: E → E * n 6 reduce:E → n reduce: E → n reduce: E → n
3.5.4 ไวยากรณแบบ non-SLR(1)
การแจงสวนแบบ SLR(1) อาจมสถานการณทมการทำงานทเปนไปไดมากกวาหนงแบบ เราเรยกวาเกดขอขดแยง (conflict) นนคอในตารางการแจงสวนแบบ SLR(1) มการลดและการเลอนในชองเดยวกนทเรยกวาขอขดแยงแบบเลอน-ลด (shift-reduce conflict) หรอ มการลดดวยกฎหลายกฎในชองเดยวกนทเรยกวาขอขดแยงแบบลด-ลด (reduce-reduce conflict) ไวยากรณททำใหเกดขอขดแยงในตารางการแจงสวนแบบ SLR(1) เรยกวา ไวยากรณแบบ non-SLR(1) ตวอยางตอไปนแสดงในไวยากรณแบบ non-SLR(1)
E → E + n E → E + n E → E + n
E → n
E → E + n E
e
e
n
+
e
e
n
E → E * n
E → E * n E → E * n E → E * n E
e
* n
E → n
e
e
e
E' → E
E' → E
E
e
E → E + n E → E + n
n
+ n
E → E * n E → E * n
E' → E E → E + n E → E * n *
n
E → n
E' → E E → E + n E → E * n E → n
E 0
1
6
2
3
4
5
หลกการและการประมวลภาษาโปรแกรม
67
ตวอยาง 3.39 กำหนดไวยากรณตอไปน
S' → S, S → L = R, S → R, L → id, L → * R, R → L
และมรายการ LR(0) ตอไปน
S' → S , S' → S , S → L = R , S → L = R , S → L = R , S → L = R , S → R , S → R , L → id , L → id , L → * R , L → * R, L → * R , R → L , และ R → L
เราสามารถสรางออโตมาตาจำกดเชงกำหนดของรายการ LR(0) ไดดงแสดงในรปขางลางน
เราสรางตารางการแจงสวนแบบ SLR(1) จากออโตมาตาจำกดเชงกำหนดนและการหา follow(S) = {$}, follow(L) = {=, $} follow(R) = {=, $} ไดดงน
Symbol State = * id $ S L R
0 shift & goto 4 shift & goto 7 goto 9 goto 1 goto 8
1 reduce: R → L shift & goto 2 reduce: R → L
2 goto 5 goto 3 3 reduce: S → L = R 4 goto 5 goto 6 5 reduce: R → L reduce: R → L 6 reduce: L → * R reduce: L → * R
7 reduce: L → id reduce: L → id
8 reduce: S → R 9 accept
S → L = R S → L = R R → L
* L
=
R
R S' → S S → L = R S → R L → id
L → * R R R → L
L
0
1 2 3
S' → S
S → L = R
R → L
S → R
9
8 L → id 7
L → * R R → L
4
id
S R
L → * R 6
R → L 5
L
Programming Language Principles and Processing
68
จากตารางแจงสวนขางบนน เมออยในสถานะ 1 และโทเคนถดไปเปน = แลวตวแจงสวนอาจเลอกลดดวยกฎ R → L หรอเลอนและเปลยนสถานะไปยงสถานะ 2 ซงเปนขอขดแยงแบบเลอนลด ดงนน ไวยากรณนเปนแบบ non-SLR(1)
การแกขอขดแยงในไวยกรณแบบ non-SLR(1)
เมอมขอขดแยงในตารางการแจงสวนแบบ SLR(1) ผออกแบบภาษาอาจเลอกการทำงานหนงแบบจากการทำงานทงหมดทเปนไปได ในไวยากรณของภาษาโปรแกรมสวนใหญ เมอมขอขดแยงแบบเลอน -ลด จะเลอกการเลอนแทนการลด ซงเปนการเลอกสรางโครงสรางใหญแทนทจะสรางโครงสรางเลก จากตวอยาง 3.39 เมอตวแจงสวนอยในสถานะ 1 และโทเคนถดไปเปน = หากเลอกทำการเลอนหมายความวาตวแจงสวนจะสรางโครงสรางประโยคกำหนดคา (assignment statement) จากกฎ S → L = R หากเลอกทำการลดหมายความวาตวแจงสวนจะสรางโครงสรางสำหรบนพจนทางขวาของประโยคกำหนดคาจากกฎ R → L
ไวยากรณของประโยคเงอนไข (if statement) มความกำกวมและทำใหเกดขอขดแยงไดดงแสดงในตวอยางตอไปน
ตวอยาง 3.41 กำหนดไวยากรณของประโยคเงอนไขตอไปนซงเปนไวยากรณกำกวม
S' → S, S → F, S → return, F → if id S, F → if id S else S
เราสามารถสรางออโตมาตาจำกดเชงกำหนดของรายการ LR(0) ไดดงแสดงในรปขางลางน
else
S
S' → S
S → F S' → S S → F S → return F → if id S F → if id S else S
S
0
8
5
S
F
S → return 4
F → if id S
F → if id S else S
1 F → if id S
F → if id S else S S → F S → return F → if id S F → if id S else S
2
F → if id S F → if id S else S
3
F → if id S else S
S → F
S → return F → if id S
F → if id S else S
6
F → if id S else S 7
F
F
if if
id
หลกการและการประมวลภาษาโปรแกรม
69
เราสรางตารางการแจงสวนแบบ SLR(1) จากออโตมาตาจำกดเชงกำหนดนและการหา follow(S) = follow(F) = {$, else} ไดดงน
Symbol State
id if else return $ S F
0 shift & goto 1 shift & goto 4 goto 5
1 shift & goto 2
2 shift & goto 1 shift & goto 4 goto 3 goto 5
3 shift & goto 6
reduce: F → if id S reduce: F → if id S
4 reduce: S → F reduce: S → F 5 reduce: S → return reduce: S → return 6 shift & goto 1 shift & goto 4 goto 7 goto 5
7 reduce:
F → if id S else S
8 accept
เมอตวแจงสวนอยในสถานะ 3 และโทเคนถดไปเปน else ตวแจงสวนอาจเลอกทำการเลอนเพอใหไดโครงสราง if id S else S เพอใหใชกฎ F → if id S else S ไดในเวลาตอมา ดงนนจะทำใหสรางประโยคเงอนไขแบบไมม else กอน วธนทำใหจบค else กบ if ใกลสดกอนหนาทยงไมมคกอน หากตวแจงสวนเลอกทำการลดโดยใชกฎ F → if id S ทำใหเลอกสรางประโยคเง อนไขแบบไมม else กอน ในกรณนจะไมจบค else กบ if ใดเลย ดงนนสำหรบภาษาโปรแกรมทมคำสงเงอนไขเชนน เราอาจสรางตวแจงสวนแบบ SLR(1) และแกขอขดแยงนโดยเลอกการเลอนแทนการลด
ตวอยางตอไปนเปนการสรางตารางการแจงสวนแบบ SLR(1) ของไวยากรณทอธบายนพจนทใชตวกระทำ + * และ ^
ตวอยาง 3.41 กำหนดไวยากรณตอไปน
E → E + E, E → E * E, E → E ^ E, E → n
ไวยากรณนเปนไวยากรณกำกวมทไมระบวาตวกระทำใดในนพจนจะถกทำกอน ดงนนเราอาจใชลำดบความสำคญและสมบตการเชอมโยงของตวกระทำมาใชแกขอขดแยง ในทน ใหตวกระทำ ^ * + มลำดบความสำคญเรยงจากมากไปนอย ตวกระทำ + และ * มสมบตการเชอมโยงทางซาย และตวกระทำ ^ มสมบตการเชอมโยงทางขวา
เราสามารถสรางออโตมาตาจำกดเชงกำหนดของรายการ LR(0) ไดดงแสดงในรปขางลางน
Programming Language Principles and Processing
70
เราสรางตารางการแจงสวนแบบ SLR(1) จากออโตมาตาจำกดเชงกำหนดนและการหา follow(E) = {+, *, ^, $} ไดดงน
Symbol State
n + * ^ $ E
0 shift & goto 6 goto 1 1 shift & goto 2 shift & goto 4 shift & goto 6 accept 2 shift & goto 8 goto 3
3 shift & goto 2
reduce: E → E+E shift & goto 4
reduce: E → E+E shift & goto 6
reduce: E → E+E reduce: E → E+E
4 shift & goto 8 goto 5
5 shift & goto 2
reduce: E → E*E shift & goto 4
reduce: E → E*E shift & goto 6
reduce: E → E*E reduce: E → E*E
6 shift & goto 8 goto 7
7 shift & goto 2
reduce: E → E^E shift & goto 4
reduce: E → E^E shift & goto 6
reduce: E → E^E reduce: E → E^E
8 reduce: E → n reduce: E → n reduce: E → n reduce: E → n
E → E + E E → E + E E → E * E E → E ^ E
E → E + E E → E + E E → E * E E → E ^ E E → n
n
+
E
E' → E E → E + E E → E * E E → E ^ E
E → n
E' → E E → E + E E → E * E E → E ^ E E → n
E
0
1
8
2
3
+
E → E * E E → E + E
E → E * E
E → E ^ E
E → E * E
E → E + E
E → E * E
E → E ^ E E → n
*
E
4
5
*
E → E ^ E E → E + E
E → E * E
E → E ^ E
E → E ^ E
E → E + E
E → E * E
E → E ^ E E → n
E
6
7
^
*
*
^
n
n
n
+
E
^
+
^
หลกการและการประมวลภาษาโปรแกรม
71
ในทนเราจะแกขอขดแยงโดยใชลำดบความสำคญและสมบตการเชอมโยงของตวกระทำ สำหรบขอขดแยง (การลดดวยกฎ E → E + E และการเลอน) เมอไดโทเคน + * หรอ ^ และตวแจงสวนอยทสถานะ 3 ซงม E + E อยในสแตค เราสามารถแกขอขดแยงไดดงน
- เมอไดโทเคน + ตวแจงสวนจะเลอกทำการลดดวยกฎ E → E + E เพอใหสรางนพจนจากตวกระทำ + ตวทางซายกอนตามสมบตการเชอมโยงทางซายของตวกระทำ +
- เมอไดโทเคน * หรอ ^ ตวแจงสวนจะไมเลอกทำการลด แตจะเลอนโทเคน * หรอ ^ ลงในสแตคเพอใหสรางนพจนจากตวกระทำ * หรอ ^ กอนเนองจากตวกระทำ + มลำดบความสำคญตำกวาตวกระทำ * และ ^
สำหรบขอขดแยง (การลดดวยกฎ E → E * E และการเลอน) เมอไดโทเคน + * หรอ ^ และตวแจงสวนอยทสถานะ 5 ซงม E * E อยในสแตค เราสามารถแกขอขดแยงไดดงน
- เมอไดโทเคน + ตวแจงสวนจะเลอกการลดดวยกฎ E → E * E เพอใหสรางนพจนจากตวกระทำ * ทางซายกอนเนองจากตวกระทำ + มลำดบความสำคญตำกวาตวกระทำ *
- เมอไดโทเคน * ตวแจงสวนจะลดดวยกฎ E → E * E เพอใหสรางนพจนจากตวกระทำ * ตวทางซายกอนตามสมบตการเชอมโยงทางซายของตวกระทำ *
- เมอไดโทเคน ^ ตวแจงสวนจะไมเลอกทำการลด แตจะเลอนโทเคน ^ ลงในสแตคเพอใหสรางนพจนจากตวกระทำ ^ กอนเนองจากตวกระทำ ^ มลำดบความสำคญสงกวาตวกระทำ *
สำหรบขอขดแยง (การลดดวยกฎ E → E ^ E และการเลอน) เมอไดโทเคน + * หรอ ^ และตวแจงสวนอยทสถานะ 7 ซงม E ^ E อยในสแตค เราสามารถแกขอขดแยงไดดงน
- เมอไดโทเคน + หรอ * ตวแจงสวนจะเลอกการลดดวยกฎ E → E ^ E เพอใหสรางนพจนจากตวกระทำ ^ กอนเนองจากตวกระทำ + และ * มลำดบความสำคญตำกวาตวกระทำ ^
- เมอไดโทเคน ^ ตวแจงสวนจะไมเลอกทำการลด แตจะเลอนโทเคน ^ ลงในสแตคเพอใหสรางนพจนจากตวกระทำ ^ ทางขวากอนตามสมบตการเชอมโยงทางขวาของตวกระทำ ^
Programming Language Principles and Processing
72
หลกการและการประมวลภาษาโปรแกรม
73
4. ตววเคราะหความหมาย
ในภาษาโปรแกรมเราสนใจความหมายขององคประกอบยอยในโปรแกรมซ งรวมเปนตวกำหนดความหมายของโปรแกรมโดยรวม ตวแปลภาษาทใชในปจจบนตรวจสอบเพยงแคความหมายระดบพนฐานของโครงสราง (construct) ในโปรแกรม ไดแก ชนดและขอบเขต (scope) ของตวแปร ความหมายเหลานไมสามารถตรวจสอบจากไวยากรณได ตววเคราะหความหมาย (semantic analyzer) ทำงานกบตนไมแจงสวนทสรางโดยตวแจงสวน การทำงานรวมกนระหวางตวแจงสวนและตววเคราะหความหมายเปนไดสองแบบ สำหรบแบบทหนง ตววเคราะหความหมายทำงานไปพรอมกบตวแจงสวนในขณะทกำลงสรางตนไมแจงสวน สำหรบแบบทสอง ตวแจงสวนสรางตนไมแจงสวนใหเสรจกอนแลวตววเคราะหความหมายจงตรวจสอบความหมายจากตนไมทครบสมบรณแลว
หวขอ 4.1 กลาวถงความหมายทสนใจในภาษาโปรแกรมโดยเนนในสวนทเกยวของกบตววเคราะหความหมาย หวขอ 4.2 อธบายการกำหนดความสมพนธของความหมายในภาษาโปรแกรมดวยไวยากรณของลกษณะประจำ (attribute grammar) หวขอ 4.3 อธบายการเขยนโปรแกรมเพอตรวจสอบความหมายตามไวยากรณของลกษณะประจำสำหรบภาษาทกำหนด
4.1 แนวคดเกยวกบความหมายในภาษาโปรแกรมทเกยวกบตววเคราะหความหมาย
ตวระบ (identifier) ใชอางถงสงท โปรแกรมเมอรตองการสรางเพ อใชในโปรแกรม เชน ตวแปร ฟงกชน คลาส (class) ชนดขอมลทผใชกำหนด (user-defined data type) ตารางสญลกษณเกบตวระบและขอมลทเกยวของ สวนตาง ๆ ของตวแปลภาษาดงขอมลเหลานจากโปรแกรมมาเกบในตารางสญลกษณ
- สแกนเนอรหาชอของตวระบในโปรแกรม - ตววเคราะหความหมายวเคราะหหาประเภทและชนดของตวระบ เชน เปนตวแปรชนดจำนวนเตม
เปนฟงกชนทคนคาชนดจำนวนจรง - ตวสรางรหสกำหนดทเกบของตวระบในหนวยความจำ
ขอมลทเกยวกบตวระบทไดมานจะถกนำมาเกบในตารางสญลกษณ ขอมลทเกยวกบความหมายของตวแปรในแตละภาษาอาจตางกนไป ในทนเราจะพจารณาชนดและขอบเขตของตวแปรทเปนขอมลเกยวกบความหมายทตรวจสอบดวยตววเคราะหความหมาย
4.1.1 ชนดของตวแปร
ชนดของตวแปรในภาษาโปรแกรมแตละภาษาอาจตางกน ชนดขอมลพนฐาน (primitive data type) ทมในภาษาโปรแกรมโดยทวไป ไดแก จำนวนเตม จำนวนจรง ตวอกขระ สายอกขระ เปนตน นอกจากนนยงมชนดขอมลทสรางจากชนดขอมลพนฐาน เรยกวา ชนดขอมลกลม (aggregate data type) ขอมลกล มทประกอบดวยขอมลชนดเดยวกนทงหมด เรยกวา แถวลำดบ (array) ขอมลกลมทประกอบดวยขอมลชนดตางกน ไดแก struct ในภาษาซ tuple ในภาษาไพธอน
Programming Language Principles and Processing
74
ภาษาโปรแกรมบางภาษา เชน ภาษาซ ภาษาจาวา ไมใหตวแปรเปลยนชนดระหวางการทำงาน ตวแปรแบบนเปนตวแปรแบบ static type ในภาษาทใชตวแปรแบบน ตวแปรมชนดตามทประกาศไวในคำสงประกาศตวแปร (declaration statement) และไมอาจเปลยนจากชนดหนงไปเปนอกชนดหนงในระหวางการทำงานได ภาษาโปรแกรมบางภาษา เชน ภาษาไพธอน ยอมใหตวแปรเปลยนชนดระหวางการทำงาน ตวแปรแบบนเปนตวแปรแบบ dynamic type
ในโปรแกรมภาษาไพธอนขางลางน เมอทำงานในบรรทดท 1 x เปนตวแปรชนดจำนวนเตม จากนนเมอรบขอมลเขาในบรรทดท 2 และขอมลเขาเปน 'f' แลวคาทนำไปใสในตวแปร x ในบรรทดท 3 มชนดเปนจำนวนจรง ดงนนตวแปร x เปลยนชนดเปนจำนวนจรง หากขอมลเขาไมเปน 'f' คาทนำไปใสในตวแปร x ในบรรทดท 6 มชนดสายอกขระ ดงนนตวแปร x เปลยนชนดสายอกขระ
1: x = 0
2: t = input('choose type :')
3: if t=='f': x=3.14159
4: else: x='error'
การยอมใหตวแปรเปลยนชนดไดระหวางทโปรแกรมทำงานทำใหเขยนโปรแกรมงายขน แตการจดการตวแปรในภาษาประเภทนมขนตอนมากกวาภาษาทไมใหเปลยนชนดของตวแปร สำหรบภาษาไมใหเปลยนชนดของตวแปร ตวสรางรหส จะเกบตำแหนงในหนวยความจำ (memory address) ของตวแปรไวในตารางสญลกษณและตำแหนงนไมเปลยนตลอดอายของตวแปร ตวสรางรหสสรางโปรแกรมในภาษาระดบทใกลเคยงกบภาษาเครองโดยใชตารางสญลกษณดงแสดงในรปขางลาง (ภาษาทใชในตวอยางนมความหมายเหมอนภาษาซ)
name type … address คำสง: x = 3
Intermediate code: t = 0318 //addr of x, stored in the symbol table
*t = 3
…
x
…
…
int
…
…
…
…
…
0318
…
หากยอมใหตวแปรเปลยนชนดได ตำแหนงในหนวยความจำท เกบคาของตวแปรหนงอาจมการเปลยนแปลงเมอตวแปรเปลยนชนดและตองใชหนวยความจำมากขน (เชน เมอตวแปรเปลยนจากชนดตวอกขระทใชหนวยความจำ 2 ไบท เปนชนดจำนวนเตมทใชหนวยความจำ 4 ไบท) เนองจากหนวยความจำทตำแหนงเดมอาจไมมทวางพอจงตองหาหนวยความจำทตำแหนงอน อยางไรกตามการเปลยนชนดของตวแปรและยายตำแหนงทเกบคาจะเกดขนในระหวางทโปรแกรมทำงาน แตตวสรางรหสจะตองกำหนดตำแหนงในหนวยความจำทใชในการเขาถงตวแปรในขนตอนของการแปลภาษาแลว ดงนนจงให ตารางสญลกษณเกบตำแหนงในหนวยความจำทใชเกบตำแหนงทเกบคาจรงดงแสดงในรปขางลาง
name type … address Memory
address คา คำสง: x = 3
Intermediate code: t = 0318 //from symbol table
a = *t //a = 0577
*a= 3 //store 3 at mem# 0577
…
x
…
…
int
…
…
…
…
…
0318
…
…
0318
…
0577
…
0577
…
3
หลกการและการประมวลภาษาโปรแกรม
75
เมอมการเปลยนชนดของตวแปรและตองการเพมขนาดของตวแปรในหนวยความจำ ระบบจะหาทในหนวยความจำใหและนำตำแหนงใหมนมาเกบแทนและสามารถใชงานรหสกลางเดมดงแสดงในรปขางลาง
name type … address Memory
address คา คำสง: x = 3.5
Intermediate code: t = 0318 //from symbol table
a = *t //a = 0610
*a= 3.5 //store 3.5 at mem# 0610
…
x
…
…
int
…
…
…
…
…
0318
…
…
0318
…
0577
…
0610
…
0610
…
3
…
3.5
วธการนทำใหสามารถเปลยนชนดของตวแปรขณะทโปรแกรมทำงานไดแตการเขาถงคาในตวแปรมขนตอนมากขนกวาภาษาทไมยอมใหเปลยนตวแปรขณะทำงาน
4.1.2 ขอบเขต (scope) ของตวแปร
ขอบเขตของตวแปรหมายถงตำแหนงในโปรแกรมทสามารถอางถงตวแปรนนได ในภาษาโปรแกรมทใชกนในปจจบนตวแปรมขอบเขตแบบสถต (static scope) นนคอขอบเขตของตวแปรระบโดยตำแหนงของการประกาศตวแปรโดยไมขนกบลำดบการทำงานของคำสงในโปรแกรม ภาษาซและภาษาจาวาใชขอบเขตแบบสถต นนคอตวแปรตวหนงจะมองเหนไดภายในบลอคทประกาศตวแปรไว ในตวอยางโปรแกรมภาษาซขางลางน ในบลอคของฟงกชน blk0 จะมองเหนตวแปร x ทประกาศในบลอกของตวเองและมองไมเหนตวแปร x ทประกาศในบลอก blk1 ทำนองเดยวกนในบลอคของฟงกชน blk1 มองเหนตวแปร x ในบลอคของฟงกชน blk1 และ ไมเหนตวแปร x ในบลอคของฟงกชน ฟงกชน blk0 ขอบเขตของตวแปรกำหนดดวยขอบเขตของบลอคท ประกาศตวแปรน นไว ขอบเขตนข นกบการกำหนดบลอกในโปรแกรมซ งไมมการเปลยนแปลงในขณะทำงานดงนนจงเรยกขอบเขตแบบนวาขอบเขตแบบสถต
void blk0(void) {
int x = 1;
printf("x=%d", x) // x=1 here.
y = blk1();
printf("x=%d", x) // x=1 still.
}
void blk1(void) {
int x = 0;
printf("%d", x) // x=0 here.
}
สำหรบภาษาทใชขอบเขตแบบพลวต (dynamic scope) ขอบเขตของตวแปรขนกบลำดบการเรยกฟงกชน ในตวอยางโปรแกรมขางลางน ฟงกชน blk0 เรยกฟงกชน blk1 ดงนนตวแปรในฟงกชน blk0 จะมองเหนจากฟงกชน blk1 ดวย ดงนนตวแปร x ในฟงกชน blk1 เปนตวแปรเดยวกนกบในฟงกชน blk0 void blk0(void) {
int x = 1;
printf("x=%d", x) // x is 1 here.
y = blk1();
printf("x=%d", x) // x is 0 here.
}
void blk1(void) {
x = 0; // x is changed here.
printf("%d", x) // x is 0 here.
}
Programming Language Principles and Processing
76
เนองจากตวแปรทอางถงในฟงกชนมขอบเขตเปลยนไปตามการเรยกใชฟงกชนทำใหอานโปรแกรมเขาใจไดยาก ภาษาโปรแกรมทใชในปจจบนจงใชขอบเขตแบบสถต ตววเคราะหความหมายมหนาทตรวจสอบ เกยวกบขอบเขตของตวแปรดวย นนคอเมอมการอางถงตวแปรแตละครงในโปรแกรม ตววเคราะหความหมายตองตรวจสอบวาอยในขอบเขตของตวแปรนนหรอไมหากมการอางถงตวแปรนอกขอบเขตของตวแปรนน ตววเคราะหความหมายตองรายงานขอผดพลาดดวย
4.2 การกำหนดความสมพนธของความหมายดวยไวยากรณของลกษณะประจำ
ในการออกแบบภาษาโปรแกรมผออกแบบตองกำหนดความหมายในภาษาทตองการตรวจสอบ ในภาษาโปรแกรมทวไปความหมายทตรวจสอบเกยวกบชนดขอมลของสวนประกอบในโปรแกรม ผออกแบบภาษาตองกำหนดชนดขอมลท ตองใชในโครงสรางตางๆของโปรแกรมและชนดขอมลท เปนผลลพธของโครงสรางใหมโปรแกรม เคร องมอท ใชอธบายขอกำหนดเหลาน ใหชดเจนเพ อนำไปสรางตววเคราะหความหมายไดถกตองคอไวยากรณลกษณะประจำ
4.2.1 ไวยากรณของลกษณะประจำ
ไวยากรณของลกษณะประจำใชอธบายความหมายขององคประกอบยอยในโปรแกรม ไวยากรณของลกษณะประจำประกอบดวย (1) ไวยากรณแบบไมพงบรบท (2) ลกษณะประจำ (attribute) และ (3) กฎของความหมาย (semantic rule)
- ไวยากรณแบบไมพงบรบทเปนชดของกฎทอธบายโครงสรางของภาษาดงกลาวไปแลวในบทท 3 - ลกษณะประจำของโครงสรางทางไวยากรณเปนสงท เราใชเกบความหมายทตองการตรวจสอบใน
ขนตอนน ลกษณะประจำทใชในตววเคราะหความหมายอาจเปนชนดหรอขอบเขตของตวแปร - กฎของความหมายระบความสมพนธระหวางลกษณะประจำของโครงสรางยอยในโครงสรางใหญ
ตวอยางขางลางน เป นการกำหนดชนดของตวแปรในประโยคประกาศตวแปร (declaration statement) ดวยไวยากรณของลกษณะประจำ ลกษณะประจำ type แทนชนดขอมลซงเปนความหมายทตองการ varlist.type แทนชนดขอมลของโครงสราง varlist ไวยากรณลกษณะประจำนหาชนดขอมลในประโยคประกาศตวแปรแลวเกบชนดของตวแปรในตารางสญลกษณ
Grammar rule Semantic rule 1 dec → int varlist varlist.type = integer
2 dec → float varlist varlist.type = real
3 varlist → id id.type = varlist.type
addType(id, id.type)
4 varlist1 → id , varlist2
id.type = varlist1.type
addType(id, id.type)
varlist2.type = varlist1.type
กฎของความหมายสองกฎแรกในไวยากรณลกษณะประจำนกำหนดวา ในประโยคประกาศตวแปรทแทนดวยสญลกษณ dec รายการของตวแปรทตามมา (varlist) มชนดขอมลเปน integer เมอประโยค
หลกการและการประมวลภาษาโปรแกรม
77
ประกาศตวแปรขนตนดวยโทเคน int แตรายการของตวแปรทตามมามชนดขอมลเปน real เมอประโยคประกาศตวแปรข นตนดวยโทเคน float กฎท 3 กำหนดวา เม อรายการของตวแปร (varlist) ประกอบดวยตวแปร (id) เดยว ชนดของตวแปรนน (id.type) เปนชนดเดยวกบชนดขอมลของรายการของตวแปร (varlist.type) และใหเพมชนดของตวแปรนนในตารางสญลกษณดวยฟงกชน addType กฎท 4 กำหนดวา เมอรายการของตวแปร (varlist1) ประกอบดวยตวแปร(id) ตวหนงกบรายการของตวแปรอกช ด (เช น x, y, z ) ชน ดของต วแปรน น (id.type) และชน ดข อม ลของรายการต วแปรท เหลอ (varlist2.type) เปนชนดเดยวกบชนดขอมลของรายการของตวแปร (varlist1.type) ทงหมดและใหเพมชนดของตวแปรในตารางสญลกษณ หลงจากนตวแปลภาษาสามารถดงชนดของตวแปรทเกบไวในตารางสญลกษณมาใชในการตรวจสอบชนดขอมล
จากไวยากรณลกษณะประจำทกำหนดน ตนไมแจงสวนของโปรแกรมทมประโยคประกาศตวแปร int x, y แสดงดวยรปขางลางโดยแสดงลกษณะประจำ type กำกบทโหนด varlist และ id กฎของความหมายกฎแรกทำใหไดลกษณะประจำ type ของโหนด varlist ทความสงเปน 1 มคาเปน integer จากคานและกฎขอท 4 ทำใหไดลกษณะประจำ type ของโหนด id และโหนด varlist ทความสงเปน 2 มคาเปน integer จากกฎขอท 3 และคาทโหนด varlist ทไดนทำใหไดลกษณะประจำ type ของโหนด id ทความสงเปน 3 มคาเปน integer ตนไมแจงสวนรวมกบลกษณะประจำของแตละโหนดทแสดงขางบนน เรยกวา ตนไมแจงสวนประกอบความหมาย (annotated parse tree)
4.2.2 การสงคาของลกษณะประจำในตนไมแจงสวนประกอบความหมาย
การสงคาของลกษณะประจำในตนไมแจงสวนประกอบความหมายเปนปจจยทตองพจารณาในการเขยนโปรแกรมเพอคำนวณคาของลกษณะประจำ เมอพจารณากฎของความหมาย L → R1 R2 … Rn ในไวยากรณลกษณะประจำท มลกษณะประจำ a,a1,a2,…,an การสงคาของลกษณะประจำในตนไมแจงสวนประกอบความหมายมได 4 แบบดงน
- การสงคาจากบนลงลางโดยสงคาจากโหนด L ลงไปยงโหนด R1, R2 … หรอ Rn ดวยกฎของความหมาย R1.a=f(L.a1), R2=g(L.a2),…, Rn=h(L.an) เมอ f, g,…, h เปนฟงกชน
- การสงคาจากลางข นบนโดยสงคาจากโหนด R1, R2 … หรอ Rn ข นไปยงโหนด L ดวยกฎของความหมาย L.a=f(R1.a1, R2.a2,…, Rn.an) เมอ f เปนฟงกชน
dec
int varlist
varlist id
id
, type=integer
type=integer
type=integer
type=integer
Programming Language Principles and Processing
78
- การสงคาจากซายไปขวาโดยสงคาจากโหนดลก Ri ไปยงโหนดลกทอยทางขวา Rj (เชน จากโหนด
R2 ไปยงโหนด R4) ดวยกฎของความหมาย Rj.a=f(Ri.ai) เมอ f เปนฟงกชน - การสงคาจากขวาไปซายโดยสงคาจากโหนดลก Ri ไปยงโหนดลกทอยทางซาย Rj (เชน จากโหนด
R4 ไปยงโหนด R2) ดวยกฎของความหมาย Rj.a=f(Ri.ai) เมอ f เปนฟงกชน
ตวอยางตอไปนแสดงไวยากรณลกษณะประจำทสงคาของลกษณะประจำจากบนลงลาง เมอพจารณากฎไวยากรณ varlist → id ทมกฎของความหมาย id.type=varlist.type จะเหนวา type ของโหนด id ไดคามาจาก type ของโหนด varlist ซงเปนโหนดแมและเพมชนดขอมลของตวแปร id ลงในตารางสญลกษณ ทำนองเดยวกน สำหรบกฎไวยากรณ varlist1 → id , varlist2 ท มกฎของความหมาย id.type = varlist1.type และ varlist2.type = varlist1.type จะเหนวา type ของโหนด id และ varlist2 ไดคามาจาก type ของโหนด varlist1 ซงเปนโหนดแม
Grammar rule Semantic rule 1 dec → int varlist varlist.type = integer
2 dec → float varlist varlist.type = real
3 varlist → id id.type = varlist.type
addType(id, id.type)
4 varlist1 → id , varlist2
id.type = varlist1.type
addType(id, id.type)
varlist2.type = varlist1.type
ตวอยางตอไปนแสดงไวยากรณลกษณะประจำทสงคาของลกษณะประจำจากลางขนบน ไวยากรณลกษณะประจำนใชลกษณะประจำ type แทนชนดขอมลทไดจากนพจนซงสรางจากตวแปร นพจนยอย และตวกระทำ ฟงกชน getType(id) ใชหาชนดของตวแปร id จากตารางสญลกษณ ในทนสมมตวาลกษณะประจำ type มคาเปน integer หรอ real เทานน
Grammar rule Semantic rule 1 E1 → E2 + F E1.type = (E2.type==F.type)?F.type:real
2 E → F E.type = F.type
3 F1 → F2 * id F1.type = (F2.type==getType(id))?F2.type:real
4 F → id F.type = getType(id)
5 F → ( E ) F.type = E.type
กฎของความหมายในแถวแรกใชเมอนพจนสรางจากนพจนยอย 2 นพจนและตวกระทำ + กฎนระบวา ถานพจนยอยมชนดเดยวกน (integer ทงค หรอ real ทงค) ชนดของนพจนใหญจะเปนชนดเดยวกบนพจนยอย ถานพจนยอยมชนดตางกน (integer กบ real) นพจนใหญเปนชนด real ดงนนคาของ E1.type สงขนมาจากคาของ E2.type และ F.type ในโหนดลก ในทำนองเดยวกน กฎของความหมายในแถว 3 ใชเมอนพจนสรางจากตวกระทำ * นพจนยอย และตวแปร กฎนระบวา ถานพจนยอยและตวแปรมชนดเดยวกน ชนดของนพจนใหญจะเปนชนดเดยวกบนพจนยอย ถานพจนยอยมชนดตางกบตวแปร นพจนใหญเปนชนด real ดงนนคาของ F1.type สงขนมาจากคาของ F2.type และ getType(id) ในโหนดลก
หลกการและการประมวลภาษาโปรแกรม
79
กฎของความหมายในแถว 2 และ 5 ใชเมอนพจนสรางจากนพจนยอยนพจนเดยว กฎนระบวานพจนใหญมชนดเดยวกนนพจนยอย ดงนน จากกฎของความหมายในแถว 2 คาของ E.type สงขนมาจากคาของ F.type ในโหนดลก และจากกฎของความหมายในแถว 5 คาของ F.type สงขนมาจากคาของ E.type ในโหนดลก
กฎของความหมายในแถว 4 ใชเมอนพจนสรางจากตวแปรตวเดยว กฎนระบวานพจนมชนดเดยวกบตวแปร และ ชนดของตวแปรหาไดจากตารางสญลกษณดวยฟงกชน getType
ตนไมแจงสวนประกอบความหมายของนพจน (x+y)*z ทสรางจากไวยากรณทกำหนดนแสดงในรปขางลางเมอ x และ z เปนตวแปรชนด integer สวน y เปนตวแปรชนด real คาของลกษณะประจำ type ในตนไมนสงจากลางขนบน กฎของความหมายในไวยากรณนกฎของความหมายทเกยวของกบ id ใชฟงกชน getType(id) ดงชนดขอมลของตวแปร id เพอสงใหโหนดแม ดงนนนพจน x+y ทแทนดวยโหนด E ในตนไมม type เปน real และนพจน (x+y)*z ทแทนดวยโหนด F ในตนไมม type เปน real ดวย
ตวอยางตอไปนแสดงไวยากรณลกษณะประจำทสงคาของลกษณะประจำจากซายไปขวา ไวยากรณลกษณะประจำนใชลกษณะประจำ type แทนชนดขอมลของตวแปรทไดจากประโยคประกาศตวแปร กฎของความหมายในแถวแรกระบวาคาของลกษณะประจำ type ของรายการของตวแปร varlist ไดมาจากคาของ type ของ typeD ซงเปนคำสงวน int หรอ float ดงนนคาของลกษณะประจำ type สงจากซายไปขวา กฎของความหมายในแถวท 4 และ 5 สงคาของลกษณะประจำ type จากบนลงลาง
Grammar rule Semantic rule 1 dec → typeD varlist varlist.type = typeD.type
2 typeD → int typeD.type = int
3 typeD → float typeD.type = real
4 varlist → id id.type = varlist.type
addType(id, id.type)
5 varlist1 → id , varlist2
id.type = varlist1.type
addType(id, id.type)
varlist2.type = varlist1.type
F
F id (z)
F E
id (y)
+
type=integer
type=integer
type=real
type=real
E
*
) ( E
type=integer
F
id (x)
type=integer
type=real
type=real
type=real
type=real
Programming Language Principles and Processing
80
การสงคาของลกษณะประจำจากขวาไปซายคลายกบการสงคาจากซายไปขวา การสงคาแบบนใชไมบอยในภาษาโปรแกรมเนองจากทำใหไมสามารถหาคาของลกษณะประจำพรอมกบการสรางตนไมแจงสวน
4.2.3 การอธบายชนดขอมลในโปรแกรมดวยไวยากรณของลกษณะประจำ
การสรางตววเคราะหความหมายเพ อตรวจสอบชนดขอมลในโปรแกรมทำไดโดยเขยนกฎของความหมายทระบวาโครงสรางยอยในโปรแกรมเชนตวแปรนพจนคำสงใหคาเปนขอมลชนดใด และกำหนดวาโครงสรางแตละชนดตองใชขอมลชนดใด หวขอนแสดงตวอยางกฎของความหมายทระบชนดขอมลของตวแปรและคาทไดจากนพจนรวมทงตรวจสอบชนดขอมลทใชในโครงสรางยอย
Grammar rule Semantic rule 1 dec → typeD varlist varlist.type = typeD.type
2 typeD → int typeD.type = int
3 typeD → float typeD.type = real
4 varlist → id id.type = varlist.type
addType(id, id.type)
5 varlist1 → id ,
varlist2
id.type = varlist1.type
addType(id, id.type)
varlist2.type = varlist1.type
6 E1 → E2 + id
t1= E2.type, t2= getType(id)
E1.type = (t1==bool or t2==bool)? error:
(t1==int and t2==int)? int:real
7 E → id E.type = getType(id)
8 F → E1 < E2
t1= E1.type, t2= E2.type
F.type = ((t1==int or t1==real)and
(t2==int or t2==real))?
bool:error
9 B → F1 or F2 t1= F1.type, t2= F2.type
B.type = (t1==bool and t2 ==bool)?bool:error
10 B → F B.type = F.type
11 st1 → if B st2 else st3
t1=st2.type, t2=st3.type
st1.type = (B.type==bool and
t1==t2)?t1:error
12 st → id = E st.type = (E.type==getType(id))?E.type:error
กฎของความหมายในแถวท 1-5 กำหนดชนดขอมลของตวแปรจากการประกาศตวแปรเชน จากคำสงประกาศตวแปร int x,y ตวแปร x และ y เปนชนด int กฎของความหมายในแถวท 6 และ 7 กำหนดชนดขอมลของนพจนทสรางจากตวกระทำ + เชน นพจน x+y ใหผลลพธเปนขอมลชนด int เมอ x และ y เปนตวแปรชนด int กฎของความหมายในแถวท 8 กำหนดชนดขอมลของนพจนทสรางจากตวกระทำ < เชน นพจน x<y ใหผลลพธเปนขอมลชนด bool ถา x และ y เปนตวแปรชนด int หรอ real แตถา x หรอ y มชนด bool แลว x<y ใหผลลพธเปน error กฎของความหมายในแถวท 9 และ 10 กำหนดชนดขอมลของนพจนทางตรรกศาสตรทอาจสรางจากตวกระทำ or เชน a or b โดยกำหนดวาถานพจนยอยทงหมดเปนชนด bool นพจนใหญจะมชนดเปน bool ดวย มฉะนนนพจนใหญมชนดเปน error คอเกดขอผดพลาด
ไวยากรณลกษณะประจำหนงอาจมลกษณะประจำมากกวาหน งตวทใชประกอบกนเพอกำหนดความหมายทตองการ ผออกแบบภาษาสามารถสรางลกษณะประจำตามทตองการใช
หลกการและการประมวลภาษาโปรแกรม
81
4.3 โปรแกรมตววเคราะหความหมาย
การเขยนโปรแกรมตววเคราะหความหมายทำไดโดยเพมการคำนวณคาของลกษณะประจำใหกบโหนดในตนไมแจงสวน เนองจากกฎของความหมายสรางไวคกบกฎของไวยากรณคาของลกษณะประจำของโหนดในตนไมแจงสวนขนกบคาในโหนดแม โหนดลก หรอ โหนดพนองเทานน ดงนนการคำนวณคาของลกษณะประจำทำไดโดยทอง (traverse) ตนไมแจงสวนในลำดบทเหมาะสมกบการสงคา เชนการทองตนไมแบบกอนลำดบ (preorder traversal) ใชกบการสงคาจากบนลงลาง เปนตน อยางไรกตามคาของลกษณะประจำอาจสงจากบนลงลาง สงจากลางขนบน หรอสงจากซายไปขวากได หวขอนอธบายการเขยนโปรแกรมสำหรบการสงคาแบบตางๆ โดยใชไวยากรณลกษณะประจำในหวขอ 4.2
สำหรบโปรแกรมในหวขอนใชฟงกชน nodeType ทบอกวาโหนดนนเปนโหนดของสญลกษณไมปลายตวใด ฟงกชน leftChild และ rightChild ทใหลกสายสดและรปขวาสดของโหนดนน ฟงกชน child2 และ child3 ทใหลกโหนดท 2 และ 3 ของโหนดนน ฟงกชนทเก ยวกบตารางสญลกษณ ไดแก ฟงกชน addType ทเกบชนดของตวแปรลงในตารางสญลกษณ และ ฟงกชน getType ทอานชนดของตวแปรจากตารางสญลกษณ
4.3.1 โปรแกรมสำหรบลกษณะประจำทสงคาจากบนลงลาง
การเขยนโปรแกรมสำหรบสงคาของสญลกษณประจำจากบนลงลางใชการทองตนไมแบบกอนลำดบ (preorder traversal) ซงจะหาคาของลกษณะประจำทโหนดนนกอนแลวจงลงไปทำงานกบโหนดลกดงแสดงขางลาง
procedure Eval (T:node)
{ compute all attributes of T
for each child C of T
Eval(C);
}
พจารณาไวยากรณลกษณะประจำทสงคาจากบนลงลางจากหวขอ4. 2.2 ทแสดงขางลางน
Grammar rule Semantic rule 1 dec → int varlist varlist.type = integer
2 dec → float varlist varlist.type = real
3 varlist → id id.type = varlist.type
addType(id, id.type)
4 varlist1 → id , varlist2
id.type = varlist1.type
addType(id, id.type)
varlist2.type = varlist1.type
โปรแกรมขางลางนเปนฟงกชน Eval ททำงานแบบเรยกซำ (recursive call) ฟงกชนนคำนวณคาของลกษณะประจำ type ในโหนดนนกอนทจะเรยกฟงกชน Eval ซำสำหรบโหนดลกของมน การทำงานแตละขนในโปรแกรมแปลงมาจากไวยากรณลกษณะประจำดงแสดงดวยคำอธบาย (comment ) ในแตละบรรทดของโปรแกรม
Programming Language Principles and Processing
82
procedure Eval (T:node)
{ switch nodeType(T):
{ case dec: // dec -> int varlist | float varlist
NodeVarlist=rightChild(T)
if (nodeType(leftChild(T))==int) // dec -> int varlist
varlist.type=integer // varlist.type = integer
if (nodeType(leftChild(T))==float) // dec -> float varlist
varlist.type=real // varlist.type = real
Eval(NodeVarlist) // sending the attribute down
break
case varlist: // varlist1 -> id | id , varlist2
Node_id=leftChild(T)
NodeVarlist=rightChild(T) // id.type = varlist1.type
addType(Node_id, T.type) // addType(id, id.type)
if (NodeVarlist!=NULL) // varlist1 -> id , varlist2
{ NodeVarlist.type=T.type // varlist2.type = varlist1.type
Eval(NodeVarlist) // sending the attribute down
}
break
}
}
4.3.2 โปรแกรมสำหรบลกษณะประจำทสงคาจากลางขนบน
การเขยนโปรแกรมสำหรบสงคาของสญลกษณประจำจากลางขนบนใชการทองตนไมแบบหลงลำดบ (postorder traversal) ซงจะเรยกฟงกชน Eval ซำ เพอหาคาของลกษณะประจำท โหนดลกกอนแลวจงคำนวณคาของลกษณะประจำในโหนดนนดงแสดงขางลาง procedure Eval (T:node)
{ for each child C of T
Eval(C);
compute all attributes of T
}
พจารณาไวยากรณลกษณะประจำทสงคาจากลางขนบนจากหวขอ 4.2.2 ทแสดงขางลางน
Grammar rule Semantic rule 1 E1 → E2 + F E1.type = (E2.type==F.type)?F.type:real
2 E → F E.type = F.type
3 F1 → F2 * id F1.type = (F2.type==getType(id))?F2.type:real
4 F → id F.type = getType(id)
5 F → ( E ) F.type = E.type
โปรแกรมขางลางนเปนฟงกชน Eval ททำงานแบบเรยกซำ (recursive call) ฟงกชนนเรยกตวเองซำเพอหาคำนวณคาของลกษณะประจำ type ในโหนดลกกอนทจะคำนวณคาในโหนดนน การทำงานแตละขนในโปรแกรมแปลงมาจากไวยากรณลกษณะประจำดงแสดงดวยคำอธบายในแตละบรรทดของโปรแกรม
หลกการและการประมวลภาษาโปรแกรม
83
procedure Eval (T:node)
{ switch nodeType(T):
{ case E: // E1 -> F | E2 + F
LNode=leftChild(T)
RNode=rightChild(T)
Eval(LNode) // sending the attribute up
if (RNode!=NULL) // E1 -> E2 + F { Eval(RNode) // sending the attribute up
if (LNode.type==RNode.type) // (E2.type==F.type)?
T.type=LNode.type // E1.type=F.type
else
T.type=real // E1.type=real
}
else // E1 -> F
T.type=LNode.type
break
case F: // F1 -> id | F2 * id | ( E ) LNode=leftChild(T)
MNode=Child2(T)
RNode=rightChild(T)
if RNode==NULL // F1 -> id T.type=getType(LNode) // F.type = getType(id) else if (nodeType(MNode)==*) // F1 -> F2 * id { Eval(Lnode) // sending the attribute up
if (LNode.type==getType(RNode))// F2.type==getType(id))?
T.type=LNode.type // F1.type = F2.type
else
T.type=real // F1.type = real
}
else // F1 -> ( E ) { Eval(MNode) // sending the attribute up
T.type=MNode.type // F.type = E.type }
break
}
}
4.3.3 โปรแกรมสำหรบลกษณะประจำทสงคาจากซายไปขวา
การเขยนโปรแกรมสำหรบสงคาของสญลกษณประจำจากซายไปขวาตองทำงานกบโหนดลกเรยงลำดบจากซายไปขวาดวย พจารณาไวยากรณลกษณะประจำทสงคาจากลางขนบนจากหวขอ 4.2.2 ทแสดงขางลางน
Grammar rule Semantic rule 1 dec → typeD varlist varlist.type = typeD.type
2 typeD → int typeD.type = int
3 typeD → float typeD.type = real
4 varlist → id id.type = varlist.type
addType(id) id.type)
5 varlist1 → id , varlist2
id.type = varlist1.type
addType(id) id.type)
varlist2.type = varlist1.type
Programming Language Principles and Processing
84
โปรแกรมขางลางนเปนฟงกชน Eval ททำงานแบบเรยกซำ (recursive call) ฟงกชนนเรยกตวเองซำเพอหาคำนวณคาของลกษณะประจำ type โดยทำงานกบโหนดลกเรยงจากซายไปขวา การทำงานแตละขนในโปรแกรมแปลงมาจากไวยากรณลกษณะประจำดงแสดงดวยคำอธบายในแตละบรรทดของโปรแกรม
procedure Eval (T:node)
{ switch nodeType(T):
{ case dec: // dec -> typeD varlist NodeTypeD=leftChild(T)
NodeVarlist=rightChild(T)
Eval(NodeTypeD) // send the attribute up
NodeVarlist.type=NodeTypeD.type // varlist.type=typeD.type // send the attribute L to R
Eval(NodeVarlist) // send the attribute down
break
case typeD: // typeD -> int | float
child=leftchild(T)
if (nodeType(child)==int) T.type=integer // typeD.type=int
if (nodeType(child)==float) T.type=real // typeD.type=real
break
case varlist: // varlist1 -> id | id , varlist2
Node_id=leftChild(T) NodeVarlist=rightChild(T)
Node_id.type=T.type // id.type = varlist.type
addType(Node_id, Node_id.type) //addType(id,id.type)
if (NodeVarlist!=NULL) // varlist1 -> id , varlist2
{ NodeVarlist.type= T.type // varlist2.type = varlist1.type
Eval(NodeVarlist) // send the attribute down
}
break
}
}
4.3.4 โปรแกรมสำหรบลกษณะประจำทสงคาแบบผสม
ไวยากรณลกษณะประจำทใชในภาษาโปรแกรมทวไปมการสงคาทงแบบบนลงลาง แบบลางขนบนและแบบซายไปขวาอยดวยกนดงทแสดงในหวขอ 4.2.3 ในหวขอน เราจะแสดงโปรแกรมสำหรบไวยากรณลกษณะประจำทสงคาหลายแบบโดยใชไวยากรณลกษณะประจำในหวขอ 4.2.3 ทแสดงขางลางน
Grammar rule Semantic rule 1 dec → typeD varlist varlist.type = typeD.type
2 typeD → int typeD.type = int
3 typeD → float typeD.type = real
4 varlist → id id.type = varlist.type
addType(id, id.type)
5 varlist1 → id , varlist2
id.type = varlist1.type
addType(id, id.type)
varlist2.type = varlist1.type
6 E1 → E2 + id
t1= E2.type, t2= getType(id)
E1.type = (t1==bool or t2==bool)? error:
(t1==int and t2==int)? int:real
7 E → id E.type = getType(id)
หลกการและการประมวลภาษาโปรแกรม
85
8 F → E1 < E2
t1= E1.type, t2= E2.type
F.type = ((t1==int or t1==real)and
(t2==int or t2==real))?
bool:error
9 B → F1 or F2
t1= F1.type, t2= F2.type
B.type = (t1==bool and t2
==bool)?bool:error
10 B → F B.type = F.type
11 st1 → if B st2 else st3
t1=st2.type, t2=st3.type
st1.type = (B.type==bool and
t1==t2)?t1:error
12 st → id = E st.type =
(E.type==getType(id))?E.type:error
โปรแกรมขางลางนเปนฟงกชน Eval ททำงานแบบเรยกซำ (recursive call) ฟงกชนนเรยกตวเองซำเพอหาคำนวณคาของลกษณะประจำ type ตามไวยากรณลกษณะประจำขางบบน การทำงานแตละขนในโปรแกรมแปลงมาจากไวยากรณลกษณะประจำดงแสดงดวยคำอธบายในแตละบรรทดของโปรแกรม procedure Eval (T:node)
{ switch nodeType(T):
{ case dec: // dec -> typeD varlist NodeTypeD=leftChild(T)
NodeVarlist=rightChild(T)
Eval(NodeTypeD) // send the attribute up
NodeVarlist.type=NodeTypeD.type //varlist.type=typeD.type
// send the attribute L to R
Eval(NodeVarlist) // send the attribute down
break
case typeD: // typeD -> int | float
child=leftchild(T)
if (nodeType(child)==int) T.type=integer // typeD.type=int
if (nodeType(child)==float) T.type=real // typeD.type=real
break
case varlist: // varlist1 -> id | id , varlist2
Node_id=leftChild(T) NodeVarlist=rightChild(T)
Node_id.type=T.type // id.type = varlist.type
addType(Node_id,Node_id.type) //addType(id, id.type)
if (NodeVarlist!=NULL) // varlist1 -> id , varlist2
{ NodeVarlist.type= T.type // varlist2.type = varlist1.type
Eval(NodeVarlist) // send the attribute down
}
break
case E: // E1 -> id | E2 + id
LNode=leftChild(T)
RNode=rightChild(T)
if RNode!=NULL // E1 -> E2 + id
{ Eval(LNode) // sending the attribute up
t1=LNode.type // t1=E2.type
t2=getType(RNode) // t2=getType(id)
if (t1==bool or t2==bool) // (t1==bool or t2==bool)?
T.type=error // E1.type = error
else if (t1==int and t2==int) // (t1==int and t2==int)?
Programming Language Principles and Processing
86
T.type=int // E1.type = int
else T.type=real // E1.type = real
}
else // E1 -> id
{ Eval(LNode) // sending the attribute up
T.type=LNode.type // E1.type = getType(id)
}
break
case F: // F -> E1 < E2 LNode=leftChild(T) RNode=rightChild(T)
Eval(LNode) // sending the attribute up
Eval(Rnode) // sending the attribute up
t1=LNode.type // t1=E1.type
t2=RNode.type // t2=E2.type
if ((t1==int or t1==real) and // ((t1==int or t1==real)and
(t2==int or t2==real)) // (t2==int or t2==real))?
T.type=bool // F.type=bool
else
T.type=real // F.type=error
break
case B: // B -> F | F1 or F2 LNode=leftChild(T)
RNode=rightChild(T)
if RNode!=NULL // B -> F1 or F2 { Eval(LNode) // sending the attribute up
Eval(Rnode) // sending the attribute up
t1=LNode.type // t1=F1.type
t2=RNode.type // t2=F2.type
if (t1==bool and t2==bool) // (t1==bool and t2 ==bool)?
T.type=bool // B.type = bool
else
T.type=error // B.type = error
}
else // B -> F { Eval(LNode) // sending the attribute up
T.type=LNode.type // B.type = F.type
}
break
case st: //st1 -> if B st2 else st3|id = E
LNode=leftChild(T)
if (nodetype(LNode)==if) // st1 -> if B st2 else st3
{ NodeCond=child2(T)
NodeThen=child3(T)
NodeElse=right(T)
Eval(NodeCond) // sending attribute up
Eval(NodeThen) // sending attribute up
Eval(NodeElse) // sending attribute up t1=NodeThen.type // t1=st2.type
t2=NodeElse.type // t2=st3.type
if (NodeCond.type==bool and t1==t2)//(B.type==bool and t1==t2)?
T.type=t1 // st1.type = t1
else
T.type=error // st1.type = error
}
else if (nodetype(LNode)==id) // st1 -> id = E
หลกการและการประมวลภาษาโปรแกรม
87
{ RNode=rightChild(T)
Eval(RNode) // sending attribute up
if (RNode.type==gettype(LNode)) // E.type==getType(id))?
T.type=RNode.type // st.type = E.type
else
T.type=error // st.type = error
}
}
Programming Language Principles and Processing
88
หลกการและการประมวลภาษาโปรแกรม
89
5. ตวกอกำเนดรหส
ตวกอกำเนดรหสเปนขนตอนหนงในการแปลภาษา ขนตอนนรบโครงสรางทไดจากรหสตนฉบบ (source code) เชนตนไมการแจงสวน แลวแปลงเปนรหสทตองการ ในการทำงานของตวแปลภาษารหสทตองการอาจเปนรหสเครอง (machine code) หรอรหสกลาง (intermediate code)
ในการสรางตวกอกำเนดรหส เราใชไวยากรณลกษณะประจำอธบายวธการสรางรหสโดยมลกษณะประจำแทนรหสทสรางและกฎของความหมายกำหนดวธสรางรหส หลงจากนนจงสรางโปรแกรมใหทำงานตามทกำหนดในไวยากรณลกษณะประจำดงทอธบายไปในบทท 4 ดงนนผทสรางตวกอกำเนดรหสตองระบวา โครงสรางตาง ๆ ในภาษาระดบสงมการทำงานตามรหสเครองหรอรหสกลางอยางไร ในทนเราจะอธบายโดยใชรหสกลางเปนตวอยาง
หวขอ 5.1 แสดงตวอยางรหสกลางสองแบบคอ P-code ทใชกบเครองจำลองททำงานกบสแตคและ 3-address code ทมรปแบบคำสงอยางงาย เชน x = y + z ซงหมายความวาใหเอาคาในตวแปร y และ z ไปกระทำดวยตวกระทำ + แลวนำผลลพธทไดไปเกบไวในตวแปร x หวขอ 5.2 แสดงการใชไวยากรณลกษณะประจำกำหนดการทำงานของตวกอกำเนดรหสสำหรบโครงสรางลำดบการทำงานในภาษาโปรแกรม หวขอ 5.3 อธบายชนดของขอมลทนยมใชในภาษาโปรแกรมและการสรางรหสกลางเพอเขาถงขอมลชนดตาง ๆ น
5.1 รหสกลาง
ในการสรางตวแปลภาษา เราอาจแปลรหสเรมตนเปนภาษากลางกอนแลวจงแปลเปนรหสเครองอกครง วธนทำใหสามารถแปลรหสเรมตนหนงไปเปนรหสเครองหลายภาษาไดโดยแปลรหสเรมตนเปนรหสกลางแลวแปลรหสกลางเปนรหสเครองสำหรบหลายเครองดงแสดงในรปขางลาง จาวาไบทโคด (Java byte code) เปนรหสกลางแบบหนงททำใหโปรแกรมภาษาจาวาสามารถใชงานในเครองใด ๆ ได จาวาไบทโคดเปนภาษาทใชสำหรบเครองเสมอนจาวา (Java virtual machine) ทเรยกยอวา JVM โปรแกรมภาษา Java จะถกแปลเปนจาวาไบทโคด ซงทำงานบน JVM JVM ถกสรางตามภาษาเครองของคอมพวเตอรทใชทำงาน (เชน JVM สำหรบหนวยประมวลผล ARM, JVM สำหรบหนวยประมวลผล Xeon) เพอจำลองการทำงานของโปรแกรมบนเครองนน
ในทำนองเดยวกนเราสามารถใชรหสกลางอำนวยความสะดวกในการแปลรหสเร มตนจากภาษาระดบสงหลายภาษาไปเปนภาษาเครองภาษาหนงได โดยแปลรหสเรมตนแตละภาษาเปนรหสกลาง แลวแปลรหสกลางนนเปนภาษาเครองทตองการดงแสดงในรปขางลาง ภาษาระดบสงหลายภาษา เชน JScala, Jython
source code Intermediate code
machine code 1 code
machine code 2 code
machine code n
…
Programming Language Principles and Processing
90
มตวประมวลภาษาทแปลจากภาษาเหลานนเปนจาวาไบทโคดเพอทำงานบน JVM
5.1.1 P-code
P-code เปนภาษาทใชกบเครองเสมอน (virtual machine) ททำงานกบสแตคเปนหลก เครองเสมอนนใชอางถงตวแปรไดเหมอนภาษาระดบสง แตเมอตองการทำงาน (เชน การกระทำทางคณตศาสตร การเปรยบเทยบ) กบตวแปรจะตองนำคาในตวแปรมาเกบลงสแตคกอนเนองจากคำสงของ P-code ใชคาบนสดของสแตคและเกบผลลพธทไดในสแตคดวย คำสงของ P-code ทจะกลาวถงในสวนนแบงเปนคำสงทนำคาเขาหรอออกจากสแตค การกระทำทางคณตศาสตร เปรยบเทยบและตรรกศาสตร คำสงกระโดดใหไปทำงานทคำสงอน และคำสงเกยวกบเลขทอย (address)
คำสงนำคาเขาหรอออกจากสแตค
loadc k นำคาคงท k ใสไวบนแสตค loadv x นำคาของตวแปร x ใสไวบนแสตค loada x นำตำแหนง (address) ของตวแปร x ใสบนแสตค store อานคาบนสด (*top) และคาถดลงไป (*(top-1)) ในสแตค แลวนำคาบนสดของสแตคไปเกบ
ทหนวยความจำทตำแหนง (address) ทระบดวยคาถดลงไปในสแตค nstore อานคาบนสด (*top) และคาถดลงไป (*(top-1)) ในสแตค แลวนำคาบนสดของสแตคไปเกบ
ทหนวยความจำทตำแหนง (address) ทระบดวยคาถดลงไปในสแตค แลวนำคาบนสดของสแตคทอานมากลบไปเกบในสแตค
การกระทำทางคณตศาสตร เปรยบเทยบและตรรกศาสตร
add, sub, lessthan, grtthan, equal, and, or นำคาบนสดสองคา ออกจากสแตคมาทำงานตามแตตวกระทำ ( เชน บวก ลบ เทยบวานอยกวา มากกวา) แลวนำผลลพธทไดเกบบนแสตค
not นำคาบนสดออกจากสแตคมาทำนเสธแลวเกบผลลพธทไดเกบบนแสตค
machine code Intermediate code
source code 1 code
source code 2 code
source code n
…
หลกการและการประมวลภาษาโปรแกรม
91
คำสงกระโดดไปทำงานทอน
label A กำหนดตำแหนงนนในโปรแกรมใหชอ A เพอใหใชอางถงในการกระโดดมาทำงาน jump A กระโดดไปทำงานทคำสงหลง label A jumpF A ดงคาบนสดจากสแตคออกมาตรวจสอบ ถาคานนเปนจรงใหกระโดดไปทำงานทคำสงหลง
label A มฉะนนจะทำงานคำสง ตอไป
คำสงเกยวกบเลขทอย
ind k นำคาบนสดของสแตค คอ a ออกมาและดงขอมลจากหนวยความจำทเลขทอย a+k มาเกบในสแตค แทนดงแสดงในรปขางลางทางซาย
ixa s นำคาบนสดของ stack คอ i และคาถดลงไปคอ a ออกจากสแตค และคำนวณคา a+s*i เกบในสแตคดงแสดงในรปขางลางทางขวา
การคำนวณนพจนดวย P-code
การหาคาของนพจนดวย P-code เปนการทำงานแบบ postfix นนคอถามนพจนยอย R กบ S แลวตองการหาคาของ R+S กตองเขยน P-code สำหรบคำนวณคาของ R ซงทำใหไดคาของนพจน R อยบนสดของสแตคดงแสดงในรปดานลาง รปแรก แลวจงตอดวย P-code ทคำนวณคาของ S ซงทำใหไดคาของนพจน S บนแสตคดงแสดงในรปดานลางรปทสอง จากนนจงตอดวยคำสง add ซงทำใหไดผลลพธของนพจน R+S อยในสแตคดงแสดงในรปขางลางรปซาย
stack
a
...
stack
*(a+k)
...
stack
a
...
stack
a+s*i
...
i
stack
value of R
...
stack
value of R
...
value of S
stack
value of R+S
...
Programming Language Principles and Processing
92
สวนของ P-code ตอไปนแสดงตวอยางการคำนวณนพจนในรปแบบตางๆ
P-code ทคำนวณนพจน x+y loadv x
loadv y
add
P-code ทคำนวณนพจน x+1 loadv x
loadc 1
add
P-code ทคำนวณนพจน x-(y-2) loadv x
loadv y
loadc 2
sub // get y-2
sub // get x-(y-2)
P-code ทคำนวณนพจน x+y<2-y loadv x
loadv y
add // get x-y
loadc 2
loadv y
sub // get 2-y
lessthan
P-code ทคำนวณนพจน x<2 and y==5 loadv x
loadc 2
lessthan // get x<2
loadv y
loadc 5
equal // get y==5
and
การกำหนดคาตวแปรดวย P-code
การกำหนดคาตวแปรใน P-code ทำไดดวยคำสง store ซงนำคาบนสดของสแตคมาเกบในตวแปรท กำหนด ดงน นจงตองคำนวณหาคา ตามท ระบทางดานขวาของเคร องหมาย = ในคำส งกำหนดคา (assignment statement) แลวใสไวบนแสตค จากนนจงใชคำสง store เพอเกบคาลงในตวแปร คาทนำมาเกบอาจเปนคาคงท (เชน x=0) คาของตวแปรอน (เชน x=y) หรอคาของนพจน (เชน x=x+y) ตวอยางตอไปนแสดงการกำหนดคาตวแปรดวยคาคงท คาของตวแปร และคาของนพจน
สวนของ P-code ตอไปนแสดงตวอยางการกำหนดคาตวแปรในรปแบบตางๆ
P-code สำหรบ x=0 loada x
loadc 0
store
P-code สำหรบ x=y loada x
loadv y
store
P-code สำหรบ x=x+y loada x
loadv x
loadv y
add
store
การทำงานแบบทางเลอกดวย P-code
การทำงานแบบทางเลอกในโปรแกรมโดยทวไปมสองแบบ คอ if-then และ if-then-else การทำงานทงสองแบบเรมตนดวยการตรวจสอบเงอนไข ดงนนตองม P-code ทคำนวณคาของเงอนไขกอน และใชคำสง jumpF เพอเลอกสวนของโปรแกรมทจะทำงานถดไป ในกรณของ if-then หากเงอนไขเปนจรงจะไปทำงานในสวนของ then หากเงอนไขไมเปนจรงจะขามสวนของ then และไปทำงานในคำสงถดไปเลย การทำงานใน
หลกการและการประมวลภาษาโปรแกรม
93
สวนนจะใชคำสง jumpF Q ซงตรวจสอบวาหากคาบนสดของสแตคเปนเทจจะกระโดดไปทำงานทตำแหนง Q ดงแสดงตอไปน
โปรแกรมในภาษาระดบสง
if (cond)
{ then-part
}
โปรแกรม P-code <code for cond>
jumpF Q
<code for then-part>
label Q
สวนของ P-code ตอไปนแสดงตวอยางการทำงานแบบ if-then
โปรแกรมในภาษาระดบสง
if (x==0)
{ y=0
x=x+2
}
โปรแกรม P-code loadv x
loadc 0
equal // x==0
jumpF OUT
loada y
loadc 0
store // y=0
loada x
loadv x
loadc 2
add // get x+2
store // x=x+2
label OUT
ในกรณของ if-then-else หากเงอนไขเปนจรงจะไปทำงานในสวนของ then แลวจงไปทำงานตามคำสงถดไป ในสวนนจะคลายกบการทำงานแบบ if-then แตตองใสคำสง jump เพอใหกระโดดขามโปรแกรมสวนของ else ไปทำงานทคำสงถดจากโครงสราง if-then-else หากเงอนไขไมเปนจรงจะขามสวนของ then ไปทำงานในสวนของ else แลวจงไปทำงานตามคำสงถดไปดงแสดงดงแสดงตอไปน
โปรแกรมในภาษาระดบสง
if (cond)
{ then-part
}
else
{ else-part
}
โปรแกรม P-code <code for cond>
jumpF ELSE
<code for then-part>
jump OUT
label ELSE
<code for else-part>
label OUT
Programming Language Principles and Processing
94
สวนของ P-code ตอไปนแสดงตวอยางการทำงานแบบ if-then-else
โปรแกรมในภาษาระดบสง
if (x==0)
{ y=0
x=x+2
}
else
{ y=1
x=x-1
}
โปรแกรม P-code loadv x
loadc 0
equal // x==0
jumpF ELSE
loada y
loadc 0
store // y=0
loada x
loadv x
loadc 2
add // get x+2
store // x=x+2
jump OUT
label ELSE
loada x
loadc 1
store y // y=1
loadv x
loadc 1
sub // get x-1
store // x=x-1
label OUT
การทำงานวนซำแบบ while
การทำงานวนซำแบบ while เรมตนดวยการตรวจสอบเงอนไข ดงนนตองม P-code ทคำนวณคาของเงอนไขกอน และใชคำสง jumpF เพอกระโดดออกจากโปรแกรมสวนทำซำ สวนของโปรแกรมทตองทำซำตามดวยคำสง jump เพอกระโดดกลบไปตรวจสอบเงอนไขดงแสดงตอไปน
โปรแกรมในภาษาระดบสง
while (cond)
{ body
}
โปรแกรม P-code label START
<code for cond>
jumpF OUT
<code for body>
jump START
label OUT
หลกการและการประมวลภาษาโปรแกรม
95
สวนของ P-code ตอไปนแสดงตวอยางการทำงานวนซำแบบ while
โปรแกรมในภาษาระดบสง
while (x>0)
{ n=n+x
x=x-1
}
โปรแกรม P-code label WHSTART
loadv x
loadc 0
grtthan // x>0
jumpF OUT
loada n
loadv n
loadv x
add
store // n=n+x
loada x
loadv x
loadc 1
sub // get x-1
store // x=x-1
jump WHSTART
label OUT
การทำงานวนซำแบบ for
การทำงานวนซำแบบ for เรมตนดวยการทำงานเรมตน init แลวตรวจสอบเงอนไข cond สวนการวนซำจะคลายกบการวนซำแบบ while แตเพมการทำงาน incr หลงสวนทำซำซงตามดวยคำสง jump เพอกระโดดกลบไปตรวจสอบเงอนไขดงแสดงตอไปน
โปรแกรมในภาษาระดบสง
for (init; cond ; incr)
{ body
}
โปรแกรม P-code <code for init>
label START
<code for cond>
jumpF OUT
<code for body>
<code for incr>
jump START
label OUT
Programming Language Principles and Processing
96
สวนของ P-code ตอไปนแสดงตวอยางการทำงานวนซำแบบ for
โปรแกรมในภาษาระดบสง
for (i=0; i<10; i=i+1)
{ n=n+i
}
โปรแกรม P-code loada i
loadc 0
store // i=0
label WHSTART
loadv i
loadc 10
lessthan // i<10
jumpF OUT
loada n
loadv n
loadv i
add
store // n=n+i
loada i
loadv i
loadc 1
add
store // i=i+1
jump WHSTART
label OUT
5.1.2 3-address Code
3-address code เปนภาษาทมคำสงระดบพนฐานทไมซบซอน แตละคำสงใน 3-address code มคาทเกยวของกบตวแปรไดไมเกน 3 คา 3-address code ประกอบดวยคำสงคำนวณและคำสงกระโดดไปทำงานทอน
คำสงคำนวณ
คำสงคำนวณใน 3-address code อยในรปของ x = y op z โดย x, y และ z เปนตวแปรทไมซำกน สวน op เปนตวกระทำทางคณตศาสตร การเปรยบเทยบ และทางตรรกศาสตรดงน
ตวกระทำทางคณตศาสตร: +, -, * ตวกระทำการเปรยบเทยบ: >, >=, <, <=, == ตวกระทำทางตรรกศาสตร: not (ซงใช 2-address เทานน), and, or ตวกระทำเกยวกบตำแหนงของตวแปร: *, &
คำสงเหลานนำคาในตวแปร y และ z มากระทำตามทกำหนดแลวเกบผลลพธในตวแปร x ตวกระทำเกยวกบตำแหนงของตวแปร *x หมายถง คาทเกบในหนวยความจำทมตำแหนง (address) เปนคาในตวแปร x
ถาใหตวแปร x เกบคา 3200 *x=y เปนคำสงทเกบคาของตวแปร y ในหนวยความจำทตำแหนง 3200 และ z=*x เปนคำสงทเกบคาทอยในหนวยความจำทตำแหนง 3200 ในตวแปร z
หลกการและการประมวลภาษาโปรแกรม
97
ตวกระทำ &x หมายถงตำแหนง (address) ของหนวยความจำทเกบตวแปร x ถาตวแปร x เกบทตำแหนง 4600 ในหนวยความจำ y=&x เปนคำสงทนำคาของตำแหนงของตวแปร x (คอ 4600) ไปเกบในตวแปร y
สงเกตวา &x=y เปนคำสงทไมสามารถทำไดเพราะ &x อางถงคาตำแหนงในหนวยความจำ ซงไมอนญาตใหโปรแกรมเมอรเปลยนเองได
คำสงกระโดดไปทำงานทอน
label A กำหนดตำแหนงนนในโปรแกรมใหชอ A เพอใชอางถงในการกระโดดมาทำงาน goto A กระโดดไปทำงานทคำสงหลง label A ifFalse x goto A ตรวจสอบคาของตวแปร x ถามคาเปนจรงจะทำงานทคำสงถดไป หากมคาเปนเทจ
จะกระโดดไปทำงานทคำสงหลง label A
การคำนวณนพจนดวย 3-address code
การหาคาของนพจนดวย 3-address code ทำงานโดยหาคาของนพจนยอยเกบไวในตวแปรชวคราว จากนนจงนำคาในตวแปรชวคราวนมาคำนวณตอเพอหาคาของนพจนใหญ นนคอถามนพจนยอย R กบ S แลวตองการหาคาของ R+S จะตองเขยน 3-address code สำหรบคำนวณคาของนพจน R แลวเกบไวในตวแปรชวคราว t1 ทำนองเดยวกนตองม 3-address code สำหรบคำนวณคาของนพจน S เกบไวในตวแปรชวคราว t2 จากนนจงใชคำสง t=t1+t2
สวนของ 3-address code ตอไปนแสดงตวอยางการคำนวณนพจนในรปแบบตาง ๆ
3-address code ทคำนวณนพจน x+y t=x+y
3-address code ทคำนวณนพจน x-(y-2) t = y-2
tt = x-t
3-address code สำหรบ x=x+1 t=x+1
x=t
3-address code สำหรบ z=x-(y-2) t1 = y-2
z = x-t1
3-address code ทคำนวณนพจน x+y<2-y t1=x+y
t2=2-y
t3=t1<t2
3-address code ทคำนวณนพจน x<2 and y==5 t1 = x<2
t2 = y==5
t3 = t1 and t2
การทำงานแบบทางเลอกดวย 3-address code
การทำงานแบบทางเลอกในโปรแกรมโดยทวไปมสองแบบ คอ if-then และ if-then-else การทำงานทงสองแบบเรมตนดวยการตรวจสอบเงอนไข ดงนนตองม 3-address code ทคำนวณคาของเงอนไขกอน และใชคำสง ifFalse … goto … เพอเลอกสวนของโปรแกรมทจะทำงานถดไป ในกรณของ if-then หากเงอนไขเปนจรงจะไปทำงานในสวนของ then หากเงอนไขไมเปนจรงจะขามสวนของ then และไปทำงาน
Programming Language Principles and Processing
98
ในคำสงถดไปเลย การทำงานในสวนนจะใชคำสง ifFalse … goto Q ซงตรวจสอบวาหากคาของนพจนเปนเทจจะกระโดดไปทำงานทตำแหนง Q ดงแสดงตอไปน
โปรแกรมในภาษาระดบสง
if (cond)
{ then-part
}
โปรแกรม 3-address code <code for cond, the result’s in c>
ifFalse c goto Q
<code for then-part>
label Q
สวนของ 3-address code ตอไปนแสดงตวอยางการทำงานแบบ if-then
โปรแกรมในภาษาระดบสง
if (x==0)
{ y=0
x=x+2
}
โปรแกรม 3-address code c = x==0
ifFalse c goto OUT
y = 0
t = x+2
x = t
label OUT
ในกรณของ if-then-else หากเงอนไขเปนจรงจะไปทำงานในสวนของ then แลวจงไปทำงานตามคำสงถดไป ในสวนนจะคลายกบการทำงานแบบ if-then แตตองใสคำสง goto เพอใหกระโดดขามโปรแกรมสวนของ else ไปทำงานทคำสงถดจากโครงสราง if-then-else หากเงอนไขไมเปนจรงจะขามสวนของ then ไปทำงานในสวนของ else แลวจงไปทำงานตามคำสงถดไปดงแสดงดงแสดงตอไปน
โปรแกรมในภาษาระดบสง
if (cond)
{ then-part
}
else
{ else-part
}
โปรแกรม 3-address code <code for cond,the result’s in c >
ifFalse c goto ELSE
<code for then-part>
goto OUT
label ELSE
<code for else-part>
label OUT
สวนของ 3-address code ตอไปนแสดงตวอยางการทำงานแบบ if-then-else
โปรแกรมในภาษาระดบสง
if (x==0)
{ y=0
x=x+2
}
else
{ y=1
x=x-1
}
โปรแกรม 3-address code c = x==0
ifFalse c goto ELSE
y = 0
t = x+2
x = t
goto OUT
label ELSE
y = 1
t = x-1
x = t
label OUT
หลกการและการประมวลภาษาโปรแกรม
99
การทำงานวนซำแบบ while
การทำงานวนซำแบบ while เรมตนดวยการตรวจสอบเงอนไข ดงนนตองม 3-address code ทคำนวณคาของเงอนไขกอน และใชคำสง ifFalse … goto … เพอกระโดดออกจากโปรแกรมสวนทำซำ สวนของโปรแกรมทตองทำซำตามดวยคำสง jump เพอกระโดดกลบไปตรวจสอบเงอนไขดงแสดงตอไปน
โปรแกรมในภาษาระดบสง
while (cond)
{ body
}
โปรแกรม 3-address code label START
<code for cond,the result is in c>
ifFalse c goto OUT
<code for body>
goto START
label OUT
สวนของ 3-address code ตอไปนแสดงตวอยางการทำงานวนซำแบบ while
โปรแกรมในภาษาระดบสง
while (x>0)
{ n=n+x
x=x-1
}
โปรแกรม 3-address code label WHSTART
c = x>0
ifFalse c goto OUT
t = n+x
n = t
s = x-1
x = s
jump WHSTART
label OUT
การทำงานวนซำแบบ for
การทำงานวนซำแบบ for เรมตนดวยการทำงานเรมตน init แลวตรวจสอบเงอนไข cond สวนการวนซำจะคลายกบการวนซำแบบ while แตเพมการทำงาน incr หลงสวนทำซำซงตามดวยคำสง goto เพอกระโดดกลบไปตรวจสอบเงอนไขดงแสดงตอไปน
โปรแกรมในภาษาระดบสง
for (init; cond ; incr)
{ body
}
โปรแกรม 3-address code <code for init>
label START
<code for cond,the result is in c>
ifFalse c goto OUT
<code for body>
<code for incr>
goto START
label OUT
Programming Language Principles and Processing
100
สวนของ 3-address code ตอไปนแสดงตวอยางการทำงานวนซำแบบ for
โปรแกรมในภาษาระดบสง
for (i=0; i<10; i=i+1)
{ n=n+i
}
โปรแกรม 3-address code i = 0
label WHSTART
c = i<10
ifFalse c goto OUT
t = n+i
n = t
t = i+1
i = t
goto WHSTART
label OUT
5.2 ไวยากรณลกษณะประจำกำหนดการลำดบการทำงาน
ไวยากรณลกษณะประจำทใชสรางรหสกลางหรอรหสเครองจะใชลกษณะประจำเพอเกบรหสทสรางสำหรบโครงสรางยอยและนำมาสรางรหสสำหรบโครงสรางใหญ นอกจากนนยงอาจมลกษณะประจำอนทใชสงคาทจำเปน เชน ตวแปรทเกบคาชวคราว หวขอนอธบายการสรางรหสสำหรบโครงสรางกำหนดลำดบการทำงานในโปรแกรม คอ การคำนวณนพจนและกำหนดคาใหตวแปร การทำงานแบบทางเลอก การทำงานวนซำแบบ while และ for โดยแบงเปนการสราง p-code ในหวขอ 5.2.1 และการสราง 3-address code ในหวขอ 5.2.2 การสราง P-code ใชลกษณะประจำตวเดยวเพอเกบ P-code แตการสราง 3-address code ตองใชลกษณะประจำเพมอกตวหนงสำหรบตวแปรทใชเกบคาชวคราวสำหรบนพจนยอย แตการสราง p-code ไมจำเปนตองใชตวแปรนเนองจากสามารถเกบคาชวคราวของนพจนยอยในสแตค
เน องจากรหสกลางหรอรหสเคร องท สรางข นเปนสตรง ในหวขอน เราใชฟงกช นเช อมสตรง (concatenation) ซ งแทนดวยส ญลกษณ + , ฟงก ช นด งช อต วแปรจากโหนดในตนไมแจงส วนคอ getName(node), ฟงกชนสรางตวแปรใหมคอ newVar() ซงสงชอตวแปรทสรางขนใหใหมโดยชอนไมซำกบตวแปรอนในโปรแกรม และ ฟงกชน newLabel() ทสงชอของตำแหนงในโปรแกรมทสรางขนใหใหมโดยชอนไมซำกบตำแหนงทใชไปแลว
5.2.1 ไวยากรณลกษณะประจำทสราง P-code
ในหวขอนเราใชลกษณะประจำ code สำหรบเกบ p-code ทสรางสำหรบโครงสรางตาง ๆ ในภาษา เชน ifSt.code เกบ P-code สำหรบโครงสรางทแทนดวยสญลกษณ ifSt ในไวยากรณของภาษา และลกษณะประจานแสดงในตนไมแจงสวนดวยตวอกษรสฟา
ไวยากรณลกษณะประจำทสราง P-code สำหรบนพจน
กำหนดไวยากรณสำหรบนพจนอยางงายในตารางไวยากรณลกษณะประจำขางลางน กฎของความหมายทแสดงนสราง p-code ทคำนวณนพจนโดยสราง p-code ของนพจนยอยแลวนำมาประกอบกนเปน p-code สำหรบนพจนรวมดงน
หลกการและการประมวลภาษาโปรแกรม
101
Grammar rule Semantic rule 1 B1 → B2 opB R B1.code = B2.code+R.code+opB.code
2 B1 → ( B2 ) B1.code = B2.code
3 B → R B.code = R.code
4 opB → and opB.code = "and"
5 opB → or opB.code = "or"
6 R → M1 opR M2 R.code = M1.code+M2.code+opR.code
7 R1 → ( R2 ) R1.code = R2.code
8 opR → < opR.code = "lessthan"
9 opR → == opR.code = "equal"
10 M1 → M2 opM T M1.code = M2.code+T.code+opM.code
11 M → T M.code = T.code
12 opM → + opM.code = "add"
13 opM → - opM.code = "sub"
14 T → ( M ) T.code = M.code
15 T → id T.code = "loadv "+getName(id)
16 T → num T.code = "loadc "+getNum(num)
ไวยากรณลกษณะประจำนใชสราง p-code โดยคำนวณลกษณะประจำ code สำหรบโหนดในตนไมแจงสวน รปขางลางน เปนตนไมแจงสวนของนพจน x+5 < y and y==0 การคำนวณลกษณะประจำ code เปนไปตามกฎของความหมาย เชน ตนไมยอยทม R เปนโหนดรากสรางจากกฎขอ 6 R → M opR M
ลกษณะประจำ code ของโหนดนกำหนดดวยกฎของความหมายทคกน คอ R.code = M1.code + M2.code + opR.code
B
B opB R
M opR M
M opR M
and R
M opM T
T + num
< T
id
id
T
id
== T
num
loadv x
loadc 5
add
loadv y
lessthan
loadv y loadc 0 equal and
loadv y loadc 0 equal
loadv x loadc 5 add loadv y lessthan
loadv x loadc 5 add loadv y lessthan
loadv x loadc 5 add
loadc 5 loadv x add
loadv x
loadv y
loadv y
lessthan
and
loadv y loadc 0 equal
loadc 0 loadv y
Programming Language Principles and Processing
102
ไวยากรณลกษณะประจำทสราง P-code สำหรบคำสงกำหนดคาใหตวแปร
กำหนดไวยากรณสำหรบคำสงกำหนดคาใหตวแปรในตารางไวยากรณลกษณะประจำขางลางน กฎของความหมาย 2 ขอนระบวา p-code ของคำสงนประกอบดวยคำสง loada v เมอ v เปนตวแปรทางซายของเครองหมาย = ตามดวย p-code ทคำนวณนพจนทางขวาของเครองหมาย = (คอ M.code หรอ B.code) ซงทำใหไดคาของนพจนอยบนแสตค ดงนนเมอ p-code ทำงานสวนนจบ คาทคำนวณจากนพจนจะอยบนสดของสแตคและเลขทอยของตวแปร v อยถดลงไป จากนนจงใชคำสง store เพอเกบคานนในตวแปร v
Grammar rule Semantic rule 17 A → id = M A.code = "loada "+getName(id)+M.code+"store"
18 A → id = B A.code = "loada "+getName(id)+B.code+"store"
รปขางลางนแสดงตนไมแจงสวนของคำสง x=x+1 ลกษณะประจำ code ทแสดงในตนไมนสรางจากไวยากรณลกษณะประจำขางบน
ไวยากรณลกษณะประจำทสราง P-code สำหรบคำสง if
กำหนดไวยากรณสำหรบคำสง if ในตารางไวยากรณลกษณะประจำขางลางน กฎของความหมายในขอ 24-26 ระบวา p-code สำหรบคำสง if สรางจาก p-code ทคำนวณเงอนไขซงทำใหไดคาของเงอนไขอยบนสดของสแตค จากนนใชคำสง jumpF เพอกระโดดไปทำงานในสวน else เมอเงอนไขเปนเทจ ตำแหนงทจะกระโดดไปทำงานนสรางดวยฟงกชน newLabel() p-code ของสวน then จะอยตอจากคำสง jumpF และตองตามดวยคำสง jump ทจะทำใหกระโดดขามสวน else ไป
รปขางลางน แสดงตนไมแจงสวนของคำส ง IF x<10 y=0 ELSE IF x==20 y=10 ลกษณะประจำ code ทแสดงในตนไมนสรางจากไวยากรณลกษณะประจำขางบน ในการสรางลกษณะประจำ code ของโหนด ifSTU ในตนไมยอยดานขวาลาง เราตองสรางชอทระบตำแหนงในโปรแกรมกอนดวยฟงกชน newLabel() ในตวอยางนสมมตวา OT เปนตำแหนงทระบดวย "L0" จากนน code ของโหนดนสรางจาก code ของโหนดลก B ทเปนเงอนไขของคำสง if ตอดวยคำสง jumpF ไปยงตำแหนง L0 ในโปรแกรม หลงคำสงนเปน code ของโหนดลก STM ทเปนสวน then คำสงทายสดเปนการระบตำแหนง L0 ดวยคำสง label
A
id = M
M opM T
T
id
+ num
loada x loadv x loadc 1 add
store
loadv x loadc 1 add
loadv x loadc 1 add
loadv x
หลกการและการประมวลภาษาโปรแกรม
103
Grammar rule Semantic rule 19 STM → ifSTM STM.code = ifSTM.code
20 STM → A STM.code = A.code
21 STU → ifSTU STU.code = ifSTU.code
22 ifST → ifSTM ifST.code = ifSTM.code
23 ifST → ifSTU ifST.code = ifSTU.code
24 ifSTM → IF B STM1 ELSE STM2
EL=newLabel()
OT=newLabel()
ifSTM.code =
B.code+"jumpF "+EL+STM1.code+"jump "+OT+
"label "+EL+STM2.code+"label "+OT
25 ifSTU → IF B STM
OT=newLabel()
ifSTM.code =
B.code+"jumpF "+OT+STM.code+"label "+OT
26 ifSTU → IF B STM1 ELSE STU2
EL=newLabel()
OT=newLabel()
ifSTM.code =
B.code+"jumpF "+EL+STM1.code+"jump "+OT+
"label "+EL+STU2.code+"label "+OT
ifSTU
B STM STU
IF B STM M opR M
A R
T
id
< T
num M
T
R
loadv x
loadc 10
lessthan
jumpF L1
loada y loadc 0 store
jump L2
loada y loadc 10 store
loadv x loadc 10 lessthan
loadv x loadc 10
loadc 10
lessthan
loadc 20 equal
ifST
IF ELSE
loadv x
id = M
T
num
loada y loadc 0 store
loadv x
loadc 0
loadc 0
ifSTU
M
T
opR
==
A
id = M
T
num
loadc 10
loadc 10
loada y loadc 10 store
loadv x loadc 20 equal
loadv x loadc 20 equal
loadv x loadc 20 equal
jumpF L0
loada y loadc 10 store label L0
label L1 loadv x loadc 20 equal jumpF L0 loada y loadc 10 store label L0
label L2
loada y loadc 0 store
loadv x loadc 10 lessthan
id num
loadc 20 loadv x
Programming Language Principles and Processing
104
ไวยากรณลกษณะประจำทสราง P-code สำหรบคำสง while
กำหนดไวยากรณสำหรบคำสง while ในตารางไวยากรณลกษณะประจำขางลางน p-code สำหรบคำสง while ตองระบตำแหนงของคำสงแรกทตรวจสอบเงอนไข (ST ในกฎของความหมาย) เพอใหวนกลบมาทำงานซำ และตำแหนงของคำสงแรกทอยตอจาก while loop (OT ในกฎของความหมาย) เพอใหกระโดดออกจากการวน กฎของความหมายนระบวา p-code สำหรบคำสง while สรางจาก p-code ทคำนวณเงอนไขตามดวยคำสง jumpF OT เพอกระโดดออกจากการวนซำหากเงอนไขเปนเทจ แลวตามดวย p-code ของสวนททำซำ ทายสดเปนคำสง jump ทจะทำใหกระโดดวนไปทำซำท ST อก
Grammar rule Semantic rule
27 Wloop → WHILE B STM
ST=newLabel()
OT=newLabel()
Wloop.code =
"label "+ST+B.code+"jumpF "+OT
+STM.code+"jump "+ST+"label "+OT
รปขางลางนแสดงตนไมแจงสวนของคำสง WHILE x>0 x=x-1 ลกษณะประจำ code ทแสดงในตนไมนสรางจากไวยากรณลกษณะประจำขางบน ในการสรางลกษณะประจำ code ของโหนด Wloop เราตองสรางช อท ระบตำแหนงในโปรแกรมกอนดวยฟงกชน newLabel() ในตวอยางน สมมตวา ST เปนตำแหนงทระบดวย ."L1" และ OT เปนตำแหนงทระบดวย ."L2" จากนน code ของโหนดนเรมตนดวยคำสง label L1 ทระบตำแหนงเรมตนการวนซำ จากนนจงตอดวย code ของโหนดลก B ทเปนเงอนไขของคำสง while ทตอดวยคำสง jumpF ไปยงตำแหนงในโปรแกรมสรางเกบไวในตวแปร L2 ตามดวย code ของโหนด STM คำสงทายสดเปนการระบตำแหนงคำสงแรกนอกโครงสราง while ทสรางไวแลวดวยคำสง label
Wloop
B STM
M opR M
A R
T
id
> T
num
loadv x loadc 0 grtthan
loadv x loadc 0
loadc 0
grtthan
WHILE
loadv x
id = M
T
num
loadc 1 loadv x
loada x loadv x
loadc 1
sub
store
loadv x loadc 0 grtthan
loada x loadv x loadc 1 sub store loadv x
loadc 1 sub
M
id
opM
- loadv x
T
loada x loadv x loadc 1 sub store
jump L1
label L2
label L1 loadv x loadc 0 grtthan jumpF L2
หลกการและการประมวลภาษาโปรแกรม
105
ไวยากรณลกษณะประจำทสราง P-code สำหรบคำสง for
กำหนดไวยากรณสำหรบคำสง for ในตารางไวยากรณลกษณะประจำขางลางน การสราง p-code สำหรบคำสง for คลายกบคำสง while แตมคำสงททำแรกสดและคำสงททำกอนวนกลบไปทำซำแตละรอบ
Grammar rule Semantic rule
28 Floop → FOR (STM1; B; STM2) STM3
L1=newLabel()
L2=newLabel()
Floop.code = STM1.code+"label "+L1+
B.code+"jumpF "+L2 +STM3.code
+STM2.code+"jump "+L1+"label "+L2
รปขางลางนแสดงตนไมแจงสวนของคำสง FOR (i=0; i<5; i=i+1) x=x+i
5.2.2 ไวยากรณลกษณะประจำทสราง 3-address code
ในหวขอนเราใชไวยากรณและลกษณะประจำ code จากหวขอ 5.2.1 ลกษณะประจำ code แสดงในตนไมแจงสวนดวยตวอกษรสฟา นอกจากนนยงมลกษณะประจำ var ทเกบชอตวแปรทเกบคาทคำนวณไดและตองนำไปใชในสวนอนของโปรแกรม ลกษณะประจำ var แสดงในตนไมแจงสวนดวยตวอกษรสแดง
Floop
B STM
M opR M
A R
T
id
< T
num
loadv i loadc 5 lessthan
loadv i
loadc 5
loadc 5
lessthan
FOR (
loadc 0
id = M
T
i
loadv i loadc 1
loada i loadv i
loadc 1
add
store
loadv i loadc 5 lessthan
loada i loadv i loadc 1 add store
loadv i loadc 1 add
M
id
opM
+ T
loada x loadv x loadv i add store
loada i loadc 0 store
label L1 loadv i loadc 5 lessthan jumpF L2
add
STM
A
id = M
T
num
d
loadv i
loada x loadv x loadv i add store
loada x loadv x loadv i add store
loadv x loadv i add
M
id
opM
+ loadv i
T
add
STM
A
id = M
loada i loadc 0 store
loadc 0
T
num
loada i loadc 0 store
loadv i
loada i loadv i loadc 1 add store jump L1 label L2
) ; ;
loadv x
loadv x
Programming Language Principles and Processing
106
ไวยากรณลกษณะประจำทสราง 3-address code สำหรบนพจน
ในตารางไวยากรณลกษณะประจำขางลางน กฎของความหมายสราง 3-address code ทคำนวณนพจนและเกบในลกษณะประจำ code โดยสราง 3-address code ของนพจนยอยแลวนำมาประกอบกนเปน 3-address code สำหรบนพจนรวม ลกษณะประจำ var เปนชอของตวแปรชวคราวทใชเกบคาทคำนวณไดจากนพจนนน
Grammar rule Semantic rule
1 B1 → B2 opB R
B1.var = newVar()
B1.code = B2.code+R.code+B1.var+"="+B2.var+
opB.code+R.var
2 B1 → ( B2 ) B1.var = B2.var
B1.code = B2.code
3 B → R B.var = R.var
B.code = R.code
4 opB → and opB.code = " and "
5 opB → or opB.code = " or "
6 R → M1 opR M2 R.var = newVar()
R.code = M1.code+M2.code+
R.var+"="+M1.var+opR.code+ M2.var
7 R1 → ( R2 ) R1.var = R2.var
R1.code = R2.code
8 opR → < opR.code = " < "
9 opR → == opR.code = " == "
10 M1 → M2 opM T
M1.var = newVar()
M1.code = M2.code+T.code+
M1.var+"="+M2.var+opM.code+T.var
11 M → T M.var = T.var
M.code = T.code
12 opM → + opM.code = " + "
13 opM → - opM.code = " - "
14 T → ( M ) T.var = M.var
T.code = M.code
15 T → id T.var = getName(id)
T.code = ""
16 T → num T.var = getNum(num)
T.code = ""
รปขางลางนเปนตนไมแจงสวนของนพจน x+5 < y and y==0 จากกฎขอ 15 และ 16 จะเหนวา ลกษณะประจำ code ของโหนด T ทมลกเปน id หรอ num มคาเปนสตรงวางเนองจากเราสามารถอางถงตวแปรหรอคาไดโดยตรง แตลกษณะประจำ var ของโหนดเหลานระบชอของตวแปรนน (จาก id) หรอสตรงทใชอางถงคา num ลกษณะประจำ var นใชสราง 3-address code ของโหนดทสงขนไป
จากกฎขอ 6 โหนด R ในดานขวาของตนไมมลกษณะประจำ var เปนตวแปร T3 ทใชเกบคาทไดจากนพจนในตนไมยอยน ตวแปรนสรางจากฟงกชน newVar() สวนลกษณะประจำ code ของโหนดนสรางจาก M1.code และ M2.code ตอดวยคำสง T3 = y==0 ซง y และ 0 ในคำสงนไดมาจากลกษณะประจำ var ของโหนดลก
หลกการและการประมวลภาษาโปรแกรม
107
ไวยากรณลกษณะประจำทสราง 3-address code สำหรบคำสงกำหนดคาตวแปร
ในตารางไวยากรณลกษณะประจำขางลางน กฎของความหมายทสราง 3-address code ระบวา 3-address code ของคำส งน ประกอบดวยคำส งทคำนวณคาของนพจนทางขวาของเคร องหมาย = (คอ M.code หรอ B.code) เกบในตวแปรชวคราว ตามดวยคำสงกำหนดคาตวแปรชวคราวนใหตวแปรทางซายของเครองหมาย = ลกษณะประจำ var เกบชอตวแปรชวคราวทเกบคาทคำนวณไดน
Grammar rule Semantic rule 17 A → id = M
A.var = getName(id)
A.code = M.code+ A.var +"="+M.var
18 A → id = B A.var = getName(id)
A.code = B.code+ A.var +"="+B.var
รปขางลางนแสดงตนไมแจงสวนของคำสง x=x+1 ลกษณะประจำ code ทแสดงในตนไมนสรางจากไวยากรณลกษณะประจำขางบน ตวแปรชวคราว T1 เกบคาของนพจน x+1 และคำสง x=T1 เกบคาของ x+1 ในตวแปร T1 ในตวแปร x
B
B opB R
M opR M
M opR M
and R
M opM T
T + num
< T
id
id
T
id
== T
num
T3
T3=y==0
T2
T1=x+5
T2=T1<y
T1
T1=x+5
5 x +
x
y
<
and
==
0
y y
y 0
T2 T1=x+5 T2=T1<y
T4 T1=x+5 T2=T1<y
T3=y==0 T4=T2 and T3
A
id = M
M opM T
T
id
+ num
x
T1=x+1
x=T1
T1
T1=x+1
x 1
+
x
Programming Language Principles and Processing
108
ไวยากรณลกษณะประจำทสราง 3-address code สำหรบคำสง if
จากตารางไวยากรณลกษณะประจำขางลางน กฎของความหมายในขอ 24-26 ระบวา 3-address code สำหรบคำสง if สรางจาก 3-address code ทคำนวณเงอนไขตามไวยากรณของนพจนทกลาวไปแลว คาของเง อนไขนเกบในตวแปรทเกบชอไวในลกษณะประจำ var จากนนใชคำสง ifFalse … goto … ตรวจสอบคาในตวแปรน ถาเปนเทจจะกระโดดไปทำงานในสวน else โดยตำแหนงทจะกระโดดไปทำงานนสรางดวยฟงกชน newLabel() 3-address code ของสวน then จะอยตอจากคำสง ifFalse และตองตามดวยคำสง goto ทจะทำใหกระโดดขามสวน else ไป ในกฎขอ 24 และ 26 ตำแหนง L1 เปนสวนของ else และ ตำแหนง L2 เปนคำสงหลงคำสง if-then-else ในกฎขอ 25 ตำแหนง L เปนตำแหนงของคำสงหลงคำสง if-then
Grammar rule Semantic rule 19 STM → ifSTM STM.code = ifSTM.code
20 STM → A STM.code = A.code
21 STU → ifSTU STU.code = ifSTU.code
22 ifST → ifSTM ifST.code = ifSTM.code
23 ifST → ifSTU ifST.code = ifSTU.code
24 ifSTM → IF B STM1 ELSE STM2
EL=newLabel()
OT=newLabel()
ifSTM.code =
B.code+"ifFalse "+B.var+" goto "+EL+
STM1.code+"goto "+OT+ "label "+EL+
STM2.code+"label "+OT
25 ifSTU → IF B STM
OT=newLabel()
ifSTM.code =
B.code+"ifFalse "+B.var+" goto "+OT+
STM.code+"label "+OT
26 ifSTU → IF B STM1 ELSE STU2
EL=newLabel()
OT=newLabel()
ifSTM.code =
B.code+"ifFalse "+B.var+" goto "+EL+
STM1.code+"goto "+OT+ "label "+EL+
STU2.code+"label "+OT
รปขางลางน แสดงตนไมแจงสวนของคำส ง IF x<10 y=0 ELSE IF x==20 y=10 ลกษณะประจำ code ทแสดงในตนไมนสรางจากไวยากรณลกษณะประจำขางบน ในการสรางลกษณะประจำ code ของโหนด ifSTU ในตนไมยอยดานขวาลาง เราตองสรางชอทระบตำแหนงในโปรแกรมกอนดวยฟงกชน newLabel() เกบในตวแปร EL ละ OT ในตวอยางน สมมตให OT เกบสตรง "L0" จากนน code ของโหนดนสรางจาก code ของโหนดลก B ทเปนเงอนไขของคำสง if ตอดวยคำสง ifFalse … goto … ทกระโดดไปยงตำแหนงในโปรแกรมทตงชอไวดวยฟงกชน newLabel() หลงคำสงนเปน code ของโหนดลก STM ทเปนสวน then จากนนตามดวยคำสงทายสดเปนการระบตำแหนง
หลกการและการประมวลภาษาโปรแกรม
109
ไวยากรณลกษณะประจำทสราง 3-address code สำหรบคำสง while
3-address code สำหรบคำสง while ตองระบตำแหนงของคำสงแรกทตรวจสอบเงอนไข (L1 ในกฎของความหมาย) เพอใหวนกลบไปทำงานซำ และตำแหนงของคำสงแรกทอยตอจาก while loop (L2 ในกฎของความหมาย) เพอใหกระโดดออกจากการวน กฎของความหมายทสราง 3-address code คลายกบการสราง p-code แตตองรบคาของเงอนไขของการวนซำจากตวแปรทเกบใน B.var เพอใชในคำสง ifFalse …
Grammar rule Semantic rule
27 Wloop → WHILE B STM
ST=newLabel()
OT=newLabel()
Wloop.code =
"label "+ST+B.code+"ifFalse "+B.var+"goto "+OT
+STM.code+"goto "+ST+"label "+OT
รปขางลางนแสดงตนไมแจงสวนของคำสง WHILE x>0 x=x-1 ในการสรางลกษณะประจำ code ของโหนด Wloop ใช ตำแหนง L1 และ L2 ท สร างดวยฟงกช น newLabel() ดงน น ST="L1" และ OT="L2" นอกจากนน T1 เปนตวแปรทเกบคาของเงอนไขการวนซำทรบมาจาก จาก B.var ดงนน code ของโหนด Wloop เรมตนดวยคำสง label L1 ทระบตำแหนงเรมตนการวนซำ จากนนจงตอดวย code ของโหนดลก B ทเปนเงอนไขของคำสง while ทตอดวยคำสง ifFalse T1 goto L2 ททำใหกระโดดออกจาก
ifSTU
B STM STU
IF B STM M opR M
A R
T
id
< T
num M
T
R
T1=x<10
ifFalse T1 goto L1
y=0
goto L2
label L1
T2=x==20 ifFalse T2 goto L0 y=10 label L0
label L2
y
y=10
T1
T1=x<10
0
<
20 ==
ifST
IF ELSE
x
id = M
T
num
y
y=0
x
0
0
ifSTU
M
T
opR
==
A
id = M
T
num
10
10
T2
T2=x==20
T2=x==20
ifFalse T2 goto L0
y=10
label L0
x
10
10
T1 T1=x<10
0 y=0
T2 T2=x==20 y=10
T2=x==20 ifFalse T2 goto L0 y=10 label L0
id num
x 20
Programming Language Principles and Processing
110
การวนซำ ตอจาก code ของโหนด STM เปนคำสง goto L1 ททำใหวนไปตรวจสอบเงอนไขการวนซำ สดทายเปนการระบตำแหนงคำสงแรกนอกโครงสราง while ทสรางไวแลวดวยคำสง label L2
ไวยากรณลกษณะประจำทสราง 3-address code สำหรบคำสง for
กำหนดไวยากรณสำหรบคำสง for ในตารางไวยากรณลกษณะประจำขางลางน การสราง 3-address code สำหรบคำสง for คลายกบคำสง while แตมคำสงททำแรกสดและคำสงททำกอนวนกลบไปทำซำแตละรอบ
Grammar rule Semantic rule
28 Floop → FOR (STM1; B; STM2) STM3
ST=newLabel()
OT=newLabel()
Floop.code =
STM1.code+"label "+ST+ B.code+
"ifFalse "+B.var+"goto "+OT+
STM3.code +STM2.code+"goto "+ST+
"label "+OT
รปขางลางน แสดงตนไมแจงสวนของคำส ง FOR (i=0; i<5; i=i+1) x=x+i โดยเพ ม 3-address code ของคำสง i=0 ไวกอนการตรวจสอบเงอนไข และ 3-address code ของคำสง i=i+1 ไวกอนคำสง goto L1
Wloop
B STM
M opR M
A R
T
id
< T
num
T1
T1=x>0
x 0
0
>
WHILE
x
id = M
T
num
1
x
T2=x-1
x=T2
T2
T2=x-1
M
id
opM
- T
label L1 T1=x>0
ifFalse T1 goto L2
T2=x-1
x=T2
goto L1
label L2
T1 T1=x>0
x
x
x T2=x-1 x=T2
หลกการและการประมวลภาษาโปรแกรม
111
5.3 ชนดขอมลและไวยากรณลกษณะประจำสำหรบเขาถงขอมลชนดตางๆ
ภาษาระดบสง (high-level language) มชนดขอมลพนฐาน (primitive data type) เชน จำนวนเตม (integer) จำนวนจรง (floating-point number) ตวอกขระ (character) เมอใชรหสเครอง เราสามารถอางถงขอมลพนฐานเหลานดวยเลขทอยของขอมลในหนวยความจำซงเกบไวในตารางสญลกษณ เมอใชรหสกลาง เราสามารถใชตวแปรอางถงขอมลพนฐานเหลานโดยตรง
อยางไรกตาม ภาษาระดบสงยงมขอมลทมโครงสรางขอมลทซบซอนมากขน เชน ขอมลแถวลำดบ (array) ขอมลแบบระเบยน (record) ขอมลเหลานเกบในหนวยความจำทตอเนองกนทงชดและเกบเลขทอยของตำแหนงแรกในหนวยความจำทใชเกบขอมลนน เมอใชรหสเครองหรอรหสกลาง เราตองการอางถงขอมลพนฐานแตละตวในโครงสรางนดวย ดงนนตวสรางรหสตองคำนวณเลขทอยขอ งขอมลพนฐานแตละตวในโครงสรางได ทงนตวแปลภาษาตองเกบรายละเอยดของโครงสรางทจำเปนสำหรบการคำนวณ เลขทอยของขอมลแตละตวในตารางสญลกษณ รายละเอยดทจำเปนสำหรบขอมลแถวลำดบ คอ ชนดของคาในแถวลำดบ เลขทอยของหนวยความจำทเกบขอมลแถวลำดบ จำนวนมต (dimension) ของขอมลแถวลำดบ และ ขนาดของขอมลแถวลำดบในแตละมต ดงแสดงในรปขางลางรปซาย รายละเอยดทจำเปนสำหรบขอมลแบบระเบยน คอ เลขทอยของหนวยความจำทเกบขอมลแบบระเบยน จำนวนฟลด (field), ชนดของขอมลแตละฟลด และระยะหางของแตละฟลดจากเลขทอยแรกของตวแปร ดงแสดงในรปตอไปน
Floop
B STM
M opR M
A R
T
id
< T
num
T1
T1=i<5
i
<
FOR
0
id = M
T
num
1 1
x
T2=x+i
x=T2
T2
T2=x+i
M
id
opM
+ T
i=0
label L1 T1=i<5
ifFalse T1 goto L2
T2=x+i
x=T2
T3=i+1
i=T3
goto L1
label L2
+
STM
A
id = M
T
id
x
i
T3=i+1
i=T3
T3
T3=i+1
M
id
opM
+ x T
+
STM
A
id = M
i
i=0
T
num
i 0
i=0
5
5
T1 T1=i<5
T3=i+1 i=T3
i
i
T2=x+i x=T2
Programming Language Principles and Processing
112
หวขอนอธบายการสรางรหสกลางคำนวณเลขทอยของขอมลแตละตวในโครงสราง 2 แบบน หวขอ 5.3.1 แสดงการสรางรหสกลางคำนวณเลขทอยของขอมลในตวแปรแถวลำดบ หวขอ 5.3.2 แสดงการสรางรหสกลางคำนวณเลขทอยของขอมลในตวแปรแบบระเบยน
5.3.1 การสรางรหสกลางคำนวณเลขทอยของขอมลในตวแปรแถวลำดบ
ขอมลในตวแปรแถวลำดบถกจดเกบในหนวยความจำทตอกนโดยเรยงตามตำแหนง สมมตให x เปนตวแปรแถวลำดบ 1 มตขนาด 9 ตว แตละตวใชเนอท 4 ไบท ถาตวแปรนถกเกบทหนวยความจำเลขท 0310 เปนตนไป คาแตละตำแหนงในตวแปร x เกบในตำแหนงทแสดงในรปขางลางน ดงนนถา x เปนตวแปรแถวลำดบ 1 มตขนาด n ตว เลขทอยของ x[i] เปน &x+is เมอ &x เปนเลขทอยของหนวยความจำทเกบ x และ s เปนขนาดของหนวยความจำทใชเกบคาหนงตว
สำหรบตวแปรแถวลำดบหลายมต เมอนำมาเกบเรยงในหนวยความจำทจดเรยงตามเลขทอยแบบหนงมต เราตองเลอกวาจดลำดบตามมตใดกอน ในการจดแบบแถวเปนหลก (row-major order) จะเรยงคาทละแถวเรยงจากแถวแรกไปยงแถวสดทาย สวนการจดแบบคอลมนเปนหลก (column-major order) จะเรยงคาทละคอลมนเรยงจากคอลมนแรกไปยงคอลมนสดทาย
ในการจดเรยงแบบแถวเปนหลก ถา x เปนตวแปรแถวลำดบ 2 มตขนาด 6 แถว 3 คอลมน แตละตวใชเนอท 4 ไบท ถาตวแปรนถกเกบทหนวยความจำเลขท 0310 เปนตนไป คาแตละตำแหนงในตวแปร x เกบในตำแหนงทแสดงในรปขางลางน ดงนนถา x เปนตวแปรแถวลำดบ 2 มตขนาด m แถว n คอลมน เลขทอยของ x[i][j] เปน &x+(i*n+j)*s เมอ &x เปนเลขทอยของหนวยความจำทเกบ x และ s เปนขนาดของหนวยความจำทใชเกบคาหนงตว
Starting address
Number of fields
Type & offset of field 1
Type & offset of field 2
Type & offset of field n
…
รายละเอยดทจำเปนสำหรบขอมลแถวลำดบ รายละเอยดทจำเปนสำหรบขอมลแบบระเบยน
Starting address
Number of dimensions
Size in dimension 1
Size in dimension 2
Size in dimension n
…
Data type
0 1 2 7 8 …
เลขทอย: 0310 0314 0318 0338 0342
คาในตวแปร x ทตำแหนง :
หลกการและการประมวลภาษาโปรแกรม
113
ในการจดเรยงแบบคอลมนเปนหลก ถา x เปนตวแปรแถวลำดบ 2 มตขนาด 6 แถว 3 คอลมน แตละตวใชเนอท 4 ไบท ถาตวแปรนถกเกบทหนวยความจำเลขท 0310 เปนตนไป คาแตละตำแหนงในตวแปร &x เกบในตำแหนงทแสดงในรปขางลางน ดงนนถา x เปนตวแปรแถวลำดบ 2 มตขนาด m แถว n คอลมน เลขทอยของ x[i][j] เปน &x+(j*m+i)*s เมอ &x เปนเลขทอยของหนวยความจำทเกบ x และ s เปนขนาดของหนวยความจำทใชเกบคาหนงตว
การคำนวณเลขทอยของขอมลในตวแปรแถวลำดบดวย P-code
กำหนดให x เปนตวแปรแถวลำดบ 1 มต, i เปนตวแปรทเกบตำแหนงของคาในแถวลำดบ และ s เกบขนาดของคาหนงคาในตวแปร (เชน จำนวนจรงมขนาด 4 ไบท ตวอกขระมขนาด 1 ไบท) &x เปนเลขทอยของคาแรกในแถวลำดบ (ในลกษณะเดยวกบทใชในภาษาซ) สวนของ P-code ตอไปนคำนวณเลขทอยของ x[i] ดวยคำสง ixa
loada x // stack content : &x
loadv i // stack content : &x | i
ixa s // stack content : &x+is
นอกจากนนยงใชคำสง ind k ทคำนวณเลขทอยในหนวยความจำจากคาบนสดของสแตคบวก k และเกบในสแตค ตวอยางขางลางนแสดงการกำหนดคาตวหนงในตวแปรแถวลำดบดวยคำสง x[i]=0 และนำคาตวหนงในตวแปรแถวลำดบมาเกบในอกตวแปรดวยคำสง y=x[i]
P-code สำหรบคำสง x[i]=0 loada x
loadv i
ixa s
loadc 0
store
P-code สำหรบคำสง y=x[i] loada y
loada x
loadv i
ixa s
ind 0
store
ในตวอยางนใหตวแปรแถวลำดบเกบแบบแถวเปนหลกและให x เปนตวแปรแถวลำดบ 2 มตทมขนาด m แถว n คอลมน โดย i และ j เปนตวแปรทเกบแถวและคอลมนของคาใน x และ s เกบขนาดของคาหนงคาในตวแปร &x เปนเลขทอยของคาแรกในแถวลำดบ สวนของ P-code ตอไปนคำนวณเลขทอยของ x[i][j]
คอ x+(i*n+j)*s ดวยคำสง ixa
0,0 0,1 0,2 1,0 1,1 1,2 2,0 2,1 4,2 5,0 5,1 5,2 … คาในตวแปร x ทตำแหนง : (แถว , หลก)
เลขทอย: 0310 0314 0318 0322 0326 0330 0334 0338 0366 0370 0374 0378
0,0 1,0 2,0 3,0 4,0 5,0 1,0 1,1 2,2 3,2 4,2 5,2 …
เลขทอย: 0310 0314 0318 0322 0326 0330 0334 0338 0366 0370 0374 0378
คาในตวแปร x ทตำแหนง : (แถว , หลก)
Programming Language Principles and Processing
114
loada x // stack content : x
loadv j // stack content : x | j
loadv i // stack content : x | j | i
ixa n // stack content : x | j+i*n
ixa s // stack content : x+(j+i*n)s
ตวอยางขางลางนแสดงการกำหนดคาตวหนงในตวแปรแถวลำดบดวยคำสง x[i][j]=0 และนำคาตวหนงในตวแปรแถวลำดบมาเกบในอกตวแปรดวยคำสง y=x[i][j]
P-code สำหรบคำสง x[i][j]=0 loada x
loadv j
loadv i
ixa n
ixa s
loadc 0
store
P-code สำหรบคำสง y=x[i][j] loada y
loada x
loadv j
loadv i
ixa n
ixa s
ind 0
store
การคำนวณเลขทอยของขอมลในตวแปรแถวลำดบดวย 3-address code
กำหนดให x เปนตวแปรแถวลำดบ 1 มต i เปนตวแปรทเกบตำแหนงของคาในแถวลำดบ และ s เกบขนาดของคาหนงคาในตวแปร (เชน จำนวนจรงมขนาด 4 ไบท ตวอกขระมขนาด 1 ไบท) &x เปนเลขทอยของคาแรกในแถวลำดบ สวนของ 3-address code ตอไปนคำนวณเลขทอยของ x[i] คอ &x+is
t1 = i*s
t2 = &x+t1
ตวอยางขางลางนแสดงการกำหนดคาตวหนงในตวแปรแถวลำดบดวยคำสง x[i]=0 และนำคาตวหนงในตวแปรแถวลำดบมาเกบในอกตวแปรดวยคำสง y=x[i]
3-address code สำหรบคำสง x[i]=0 t1 = i*s
t2 = &x+t1
*t2 = 0
3-address code สำหรบคำสง y=x[i] t1 = i*s
t2 = &x+t1
y = *t2
ในตวอยางนใหตวแปรแถวลำดบเกบแบบแถวเปนหลกและให x เปนตวแปรแถวลำดบ 2 มตทมขนาด m แถว n คอลมน โดย i และ j เปนตวแปรทเกบแถวและคอลมนของคาใน x และ s เกบขนาดของคาหนงคาในตวแปร &x เปนเลขทอยของคาแรกในแถวลำดบ สวนของ 3-address code ตอไปนคำนวณเลขทอยของ x[i][j] คอ x+(i*n+j)s
t1 = i*n
t2 = t1+j
t3 = t2*s
t4 = &x+t3
ตวอยางขางลางนแสดงการกำหนดคาตวหนงในตวแปรแถวลำดบดวยคำสง x[i][j]=0 และนำคาตวหนงในตวแปรแถวลำดบมาเกบในอกตวแปรดวยคำสง y=x[i][j]
หลกการและการประมวลภาษาโปรแกรม
115
3-address code สำหรบคำสง x[i][j]=0 t1 = i*n
t2 = t1+j
t3 = t2*s
t4 = &x+t3
*t4 = 0
3-address code สำหรบคำสง y=x[i][j] t1 = i*n
t2 = t1+j
t3 = t2*s
t4 = &x+t3
y = *t4
5.3.2 การสรางรหสกลางคำนวณเลขทอยของขอมลในตวแปรแบบระเบยน
ขอมลในตวแปรแบบระเบยนถกจดเกบในหนวยความจำทตอกนโดยเรยงตามลำดบในระเบยน สมมตให x เปนตวแปรแบบระเบยนทประกอบดวยฟลด id ทเปนจำนวนเตมขนาด 4 ไบท, price ทเปนจำนวนจรงขนาด 8 ไบท และ unit ทเปนจำนวนเตมขนาด 4 ไบท ถาตวแปรนถกเกบทหนวยความจำเลขท 0310 เปนตนไป คาของแตละฟลดเกบในตำแหนงทแสดงในรปขางลางน ดงนนถา x เปนตวแปรแถวลำดบ 1 มตขนาด n ตว เลขทอยของ x[i] เปน &x+is เมอ &x เปนเลขทอยของหนวยความจำทเกบ x และ s เปนขนาดของหนวยความจำทใชเกบคาหนงตว
การคำนวณเลขทอยของขอมลในตวแปรแถวลำดบดวย P- code
กำหนดให x เปนตวแปรแบบระเบยน, f เปนชอฟลด, &x เปนเลขทอยของคาแรกในตวแปร, k เปนระยะหางของฟลด f จากเลขทอยของคาแรกในตวแปร สวนของ P-code ตอไปนคำนวณเลขทอยของ x.f
loada x // stack content : &x
loadc k // stack content : &x | k
add // stack content : &x+k
ตวอยางขางลางนแสดงการกำหนดคาตวหนงในตวแปรแถวลำดบดวยคำสง x.f=0 และนำคาตวหนงในตวแปรแถวลำดบมาเกบในอกตวแปรดวยคำสง y=x.f
p-code สำหรบคำสง x.f=0 loada x
loadc k
add
loadc 0
store
P-code สำหรบคำสง y=x.f loada y
loada x
ind k
store
การคำนวณเลขทอยของขอมลในตวแปรแถวลำดบดวย 3-address code
กำหนดให x เปนตวแปรแบบระเบยนดงทกลาวไป สวนของ 3-address code ตอไปนคำนวณเลขทอยของ x.f
x.id
เลขทอย: 0310 0314 0322
คาในตวแปร x ทตำแหนง : x.unit x.price
Programming Language Principles and Processing
116
t1 = &x
t2 = t1+k
ตวอยางขางลางนแสดงการกำหนดคาตวหนงในตวแปรแถวลำดบดวยคำสง x.f=0 และนำคาตวหนงในตวแปรแถวลำดบมาเกบในอกตวแปรดวยคำสง y=x.f
3-address code สำหรบคำสง x.f=0 t1 = &x
t2 = t1+k
*t2 = 0
3-address code สำหรบคำสง y=x.f t1 = &x
t2 = t1+k
y = *t2
หลกการและการประมวลภาษาโปรแกรม
117
Programming Language Principles and Processing
118
6. สภาพแวดลอมเวลาดำเนนงาน
การทำงานของโปรแกรมมกเกยวของกบตวแปรซงมหลายชนด ตวแปรบางตวถกกำหนดใหใชไดตงแตเรมตนจนจบการทำงานของโปรแกรม ตวแปรบางตวใชในระหวางทฟงกชนหรอสวนยอยของโปรแกรมทำงานเทานน ตวแปลภาษาตองจดการเนอทในหนวยความจำใหตวแปรเหลานอยางเหมาะสม หวขอนอธบายการจดการหนวยความจำในโปรแกรมสำหรบตวแปรชนดตางๆ หวขอ 6.1 อธบายตวแปรแบบตาง ๆ ทใชในภาษาโปรแกรม หวขอ 6.2 อธบายการจดหนวยความจำสำหรบตวแปรชนดตาง ๆ หวขอ 6.3 อธบายคำสงทตวแปลภาษาตองเพมในรหสกลางหรอรหสเครองเพอจดการเกยวกบฟงกชน
6.1 ชนดของตวแปรในภาษาโปรแกรม
ตวแปรในภาษาโปรแกรมแบงตามการผก (binding) กบหนวยความจำและชวงชวต (lifetime) ของตวแปรไดเปน 4 ชนดคอ ตวแปรแบบสถต (static variable) ตวแปรในสแตคแบบพลวต (stack-dynamic variable) ตวแปรในฮปแบบกำหนดโดยปรยาย (implicit heap dynamic variable) และ ตวแปรในฮปแบบกำหนดชดแจง (explicit heap dynamic variable)
6.1.1 ตวแปรแบบสถต (static variable)
ตวแปรแบบสถตเปนตวแปรทมชวงชวตยาวตลอดการทำงานของโปรแกรม ตวแปรในภาษาซทประกาศโดยมคำวา static กำกบเปนตวแปรแบบสถต เชน static int x ตวแปลภาษาตองกำหนดทอยในหนวยความจำใหตวแปรชนดนตงแตโปรแกรมเรมทำงานและตวแปรนนจะผกกบเลขทอยในหนวยความจำทตำแหนงนนตลอดการทำงาน ดงนนจงสามารถอางถงตวแปรนในรหสเครองดวยเลขทอยนนตลอดการทำงานของโปรแกรม เช น ถาประกาศตวแปร x ดงทยกตวอยางไปแลว ตวแปลภาษากำหนดเลขทอย ในหนวยความจำทเกบตวแปร x ตงแตโปรแกรมเรมทำงาน ในทนสมมตใหเปนเลขทอย 0326 จากนนจะใชเลขทอย 0326 นอางถงตวแปร x ในโปรแกรมไดเสมอ
6.1.2 ตวแปรในสแตคแบบพลวต (stack-dynamic variable)
ในภาษาโปรแกรมมตวแปรทใชไดเฉพาะในฟงกชนและมชวงชวตอยในชวงทฟงกชนนนทำงานเทานน ตวอยางของตวแปรประเภทน ไดแก ตวแปรเฉพาะท (local variable) ซงประกาศไวในฟงกชนในภาษาซและภาษาจาวา เนองจากตวแปรประเภทนมชวตอยเมอฟงกชนนนทำงาน แตฟงกชนหนงอาจเรยกอกฟงกชนหนงทำงาน เชน ฟงกชน A เรยกฟงกชน B ใหทำงานซงทำใหฟงกชน A ตองหยดการทำงานไปเมอฟงกชน B เรมทำงาน ฟงกชน A จะกลบมาทำงานอกครงเมอฟงกชน B ทำงานเสรจ ดงนนตวแปรในฟงกชน A ตองถกเกบไว เมอฟงกชน B ทำงานเสรจ ฟงกชน A จะกลบมาทำงานตอโดยตองนำตวแปรในฟงกชน A กลบมาใชไดโดยไมมการเปลยนคาไปจากตอนทฟงกชน A หยดทำงาน
เนองจากการเรยก (call) ฟงกชนและการกลบ (return) จากฟงกชนมลกษณะเหมอนการทำงานของสแตค คอ ฟงกชนทถกเรยกหลงจะจบการทำงานกอนในลกษณะเขาหลง -ออกกอน (last-in, first-out) ตวแปลภาษาจงสามารถจดการทเกบตวแปรทใชในฟงกชนแบบสแตคไดเชนกน ตวแปลภาษาจดแบงทใน
หลกการและการประมวลภาษาโปรแกรม
119
หนวยความจำไวใชเปนสแตคทเกบตวแปรเหลาน จากรปขางลางน ตวแปลภาษาจะใชทวางบนสแตคเพอเกบตวแปรในฟงกชน A เมอฟงกชน A เรมทำงาน หากฟงกชน A มการเรยกใชฟงกชน B ตอไปกจะใชทถดไปบนสแตคเพอเกบตวแปรในฟงกชน B ดงนนหากฟงกชน A ยงทำงานไมเสรจตวแปรของฟงกชน A จะยงถกเกบไวในสแตค ในขณะทดานบนเปนทเกบตวแปรของฟงกชน B เมอฟงกชน B ทำงานเสรจแลว ตวแปรของฟงกชน B ทอยดานบนกจะถกนำออกไปจากสแตคซงทำใหตวแปรของฟงกชน A ปรากฏอยบนสดของสแตค แทนและถกนำกลบมาใชในฟงกชน A ไดโดยมคาเดยวกบตอนทฟงกชนหยดทำงาน ดงน นเลขท อยในหนวยความจำทผกกบตวแปรจะไมเปลยนไประหวางการทำงาน
6.1.3 ตวแปรในฮปแบบกำหนดชดแจง (explicit heap dynamic variable)
นอกจากตวแปรสองชนดทไดกลาวไปแลว ภาษาโปรแกรมยงมตวแปรทผเขยนโปรแกรมสามารถระบใหสรางขนมาหรอใหลบตวแปรนนทงในขณะทโปรแกรมทำงานได เชน ในภาษาจาวา ผเขยนโปรแกรมสามารถใชคำสง new เพอขอเนอทในหนวยความจำสำหรบตวแปรหนงได และใชคำสง free เพอเลกใชหนวยความจำสำหรบตวแปรนน ดงนนชวงชวตของตวแปรนนถกกำหนดโดยผเขยนโปรแกรมซงทำใหตวแปลภาษาไมสามารถกำหนดชวงชวตของตวแปรนนได ตวแปลภาษาจะแบงเนอทในหนวยความจำสำหรบตวแปรชนดนแยกไว เมอมคำสงขอใชทสำหรบตวแปรแบบนกจะขอเนอทในหนวยความจำสวนนมาใช พนทในหนวยความจำสวนน เรยกวา ฮป (heap)
6.1.4 ตวแปรในฮปแบบกำหนดโดยปรยาย (implicit heap dynamic variable)
ในภาษาโปรแกรมทอนญาตใหตวแปรเปลยนชนดในขณะทโปรแกรมทำงานได เมอชนดของตวแปรเปลยนไป ขนาดของหนวยความจำทตองใชในการเกบตวแปรนนอาจเปลยนไปดวย เชน เมอตวแปร x มชนดเปนจำนวนเตมดวยคำสง x=0 ตวแปร x ใชเนอท 4 ไบท ตอมาเมอใชคำสง x=[1,2,3,4] x เปนตวแปรแถวลำดบทเกบจำนวนเตม 4 คาและตองใชเนอท 16 ไบท ดงนนตวแปลภาษาตองจดหาเนอทในฮปใหใหมเพอเกบตวแปร x การขอทในฮปของตวแปรแบบนตางกบตวแปรในฮปแบบกำหนดชดแจง คอ ผเขยนโปรแกรมไมไดกำหนดการขอใชเนอทหนวยความจำ แตตวแปลภาษาขอใชเนอทใหโดยปรยายเมอมการเปลยนชนดของตวแปร
หวขอตอไปอธบายการจดการหนวยความจำสำหรบตวแปรทใชในขณะทโปรแกรมทำงาน
stack
Local variables in A
bottom of stack
stack
Local variables in A
bottom of stack
stack
Local variables in A
Local variables in B
bottom of stack
เมอ A เรมทำงาน A เรยก B เมอ B เรมทำงาน B กลบมา A เมอ A กลบมาทำงาน
Programming Language Principles and Processing
120
6.2 การจดหนวยความจำสำหรบตวแปร
เนอทในหนวยความจำทใชระหวางการทำงานของโปรแกรมแบงเปนสวนทเกบโปรแกรมและสวนทเกบตวแปร ตวแปลภาษาสามารถบอกไดวาเนอทสวนเกบโปรแกรมตองมขนาดเทาไรเพราะสวนนคอรหสเครองทสรางโดยตวแปลภาษาเอง แตตวแปลภาษาไมสามารถบอกไดวาหนวยความจำสวนทใชเกบตวแปรของโปรแกรมตองมขนาดเทาไรเพราะตวแปรภายในฟงกชนจะถกสรางขนเมอฟงกชนถกเรยกใชและตวแปลภาษาไมอาจบอกไดกอนโปรแกรมเรมทำงานวา ฟงกชนใดจะถกเรยกใชกครง แตตวแปลภาษาบอกไดวาตวแปรแบบสถตในโปรแกรมตองการเน อท ในหนวยความจำเทาไร ดงน นตวแปลภาษาจะจดเน อท ในหนวยความจำสำหรบโปรแกรมหนงดงแสดงในรปขางลางน
หนวยความจำสวนแรก คอ code area ใชเกบโปรแกรมทจะทำงาน สวนถดมา คอ static area ใชเกบตวแปรแบบสถต ขนาดของเนอทสำหรบสองสวนนไมเปลยนแปลงระหวางทโปรแกรมทำงาน สวนถดมาของหนวยความจำใชสำหรบตวแปรในฟงกชนทถกเกบในสแตคซงอาจมการเพมหรอลดขนาดของสแตคตามการเรยกใชฟงกชน สวนสดทายเปนฮปท ใชเกบตวแปรทสรางระหวางการทำงานแตไมไดอย ในสแตค เนองจากเนอทของฮปและสแตคมการเพมหรอลดระหวางทโปรแกรมทำงาน ตวแปลภาษาจงจดใหสแตคและฮปใชหนวยความจำทตอกน สแตคใชเนอทเรมจากเลขทอยตำและสามารถเพมขนาดไปยงเลขทอยสงขนได สวนฮปใชเนอทเรมจากเลขทอยสงและสามารถเพมขนาดไปยงเลขทอยตำลง ทงนทำใหโปรแกรมใชเนอทสำหรบสแตคและฮปรวมกน เชน สแตคอาจใชหนวยความจำสวนนทงหมดในชวงทโปรแกรมมก ารเรยกใชฟงกชนเวยนเกดหลายครง แตเมอฟงกชนทำงานจบไปแลวเนอทในสแตคทใชสำหรบตวแปรในฟงกชนจะถกคนกลบไป โปรแกรมอาจขอเนอทสำหรบตวแปรในฮปแบบกำหนดชดแจงทเปนตวแปรแถวลำดบขนาดใหญโดยขอหนวยความจำจากฮปซงอาจเปนสวนทเคยใชเกบตวแปรของฟงกชนมากอน นนคอหนวยความจำสวนหนงอาจถกใชสำหรบสแตคในเวลาหนงแตใชสำหรบฮปในอกเวลาหนงกได
6.2.1 การจดเกบตวแปรแบบสถต
เนองจากตวแปรแบบสถตมชวงชวตตลอดการทำงานของโปรแกรม ตวแปลภาษาจดหนวยความจำในเนอทแบบสถต (static area) และ กำหนดเลขทอยใหตวแปรแบบสถตแตละตวไดตงแตโปรแกรมเรมทำงาน
สวนเกบโปรแกรม (code area)
สวนเกบตวแปรแบบสถต (static area)
สแตค (stack)
ฮป (heap)
สวนเ
กบตว
แปร
หลกการและการประมวลภาษาโปรแกรม
121
จากนนตวแปลภาษาสามารถใชเลขทอยนอางถงตวแปรแบบสถตในรหสเครองตลอดการทำงานของโปรแกรม ดงนนตวแปลภาษาจะเกบเลขทอยนไวในตารางสญลกษณและใชในการสรางรหสเครอง
6.2.2 การจดเกบตวแปรในสแตคแบบพลวต
ตวแปรเฉพาะทในฟงกชนถกสรางขนเมอมการเรยกใชฟงกชนและถกเกบไวจนกระทงฟงกชนทำงานจบ ดงนนตวแปรเหลานถกเกบไวในสแตค สมมตใหมฟงกชน A และ B ซงฟงกชน A เรยกใชฟงกชน B เราเรยก A เปนตวเรยก (caller) และ B เปนตวถกเรยก (callee) เมอฟงกชน A ทำงาน ตวแปรเฉพาะทของฟงกชน A จะถกเกบไวในสแตค เมอฟงกชน A เรยกใชฟงกชน B ตวแปรเฉพาะทของฟงกชน A จะยงถกเกบไวและตวแปรของฟงกชน B จะถกสรางเกบไวดานบนของสแตคดงแสดงนรปขางลาง เมอฟงกชน B จบการทำงานและยอนกลบมาทำงานของฟงกชน A ตอ ตวแปรเฉพาะทของฟงกชน B ทอยบนสดในสแตคจะถกปอบ (pop) ทงและทำใหตวแปรเฉพาะทของฟงกชน A กลบมาอยบนสดในสแตคดงแสดงในรปขางลาง พารามเตอร (parameter) ของฟงกชนเปนเหมอนตวแปรเฉพาะทซงตองมคาสงเขามาหรอนำคาสงออกไป ดงนนจงตองเกบในสแตคในลกษณะเดยวกน
ในการเรยกฟงกชนแบบเวยนเกด (recursive function) ซำ ตวแปรเฉพาะทของฟงกชนนนตองถกสรางขนใหมทกครงดวย ตวอยาง เชน ฟงกชน factorial ขางลางนมตวแปรเฉพาะท f
int factorial(int n) {
int f;
if (n==0 or n==1) f=n;
else f=n*factorial(n-1);
return f;
}
หากโปรแกรมหลกเร ยกฟงกช น factorial(4 ) ตวแปร f และพารามเตอร n ของฟงกชน factorial ตองถกเกบไวสำหรบการเรยกแบบเวยนเกดทกครงดงแสดงในรปขางลางน
stack
Local variables in A
bottom of stack
stack
Local variables in A
bottom of stack
stack
Local variables in A
Local variables in B
bottom of stack
เมอ A เรมทำงาน A เรยก B เมอ B เรมทำงาน B กลบมา A เมอ A กลบมาทำงาน
Programming Language Principles and Processing
122
จากตวอยางทกลาวมานจะเหนวาเมอตวแปลภาษาอางถงตวแปรเฉพาะทในการเรยกฟงกชนแตละครง เลขทอยของตวแปรเฉพาะทนนจะตางกน เพราะอางถงเนอทในสแตคทสรางขนในการเรยกฟงกชนแตละครง
6.2.3 การจดเกบตวแปรในฮป
เมอโปรแกรมขอเนอทในฮปทงแบบชดแจงและโดยปรยาย ตวแปลภาษาตองตรวจสอบวามเนอทวางในฮปหรอไมและจดเนอทใหหากม ตวแปลภาษาจะหาหนวยความจำในสวนฮปทวางและใชเลขทอยนสำหรบตวแปรนน ดงนนตวแปรนจะมเลขทอยจรงเมอโปรแกรมทำงานไปแลว
6.3 คำสงทใชจดการสแตคการเรยกและเลขทอยของตวแปรเฉพาะท
ในการเรยกใชฟงกชน ตวแปลภาษาตองเตรยมเนอทสำหรบตวแปรเฉพาะทและพารามเตอร ของฟงกชนดงทกลาวไปแลว นอกจากนนตวแปลภาษายงตองจดใหเกบเลขทอยหลงคำสงเรยกใชฟงกชนทเรยกวา
stack
n: 4
f:
bottom of stack
stack
n: 4 f:
n: 3 f:
bottom of stack
stack
n: 4 f:
n: 3 f:
n: 2 f:
bottom of stack
stack
n: 4 f:
n: 3 f:
n: 2 f:
n: 1 f: 1
bottom of stack
stack
n: 4 f:
n: 3 f:
n: 2 f: 2
bottom of stack
stack
n: 4 f:
n: 3 f: 6
bottom of stack
stack
n: 4 f:24
bottom of stack
call
factorial(3)
call factorial(4)
call factorial(2)
call factorial(1)
return from factorial(1)
return from factorial(2)
return from factorial(3)
หลกการและการประมวลภาษาโปรแกรม
123
เลขทอยกลบ (return address) เพอใหสามารถกระโดดกลบมาทำงานทคำสงนนเมอฟงกชนนนทำงานจบ ตวแปลภาษาจะเกบตวชทเรยกวา ลงคควบคม (control link) ทชไปยงระเบยนการทำงานของฟงกชนทเปนตวเรยก (caller) ดวย ขอมลเกยวกบฟงกชนทกลาวมานรวมเรยกวา ระเบยนการทำงาน (activation record) หรอ เฟรม (frame) ดงแสดงในรปขางลาง
6.3.1 คำสงจดการเรยกฟงกชนและกลบจากฟงกชน
เมอโปรแกรมเรยกใชฟงกชน จะตองมการเกบระเบยนการทำงานในสแตค เรยกวา สแตคการเรยก (call stack) ตวแปลภาษาสรางคำสงทเกบระเบยนการทำงานในสแตคการเรยกโดยใชตวชของเฟรม FP (frame pointer) เพอบอกตำแหนงของระเบยนการทำงานและตวชของสแตค SP (stack pointer) เพอบอกตำแหนงบนสดของสแตคการเรยก คำสงชดนเรยกวาลำดบการเรยก (calling sequence) ซงประกอบดวยการทำงานตอไปน
1. จองทในสแตคสำหรบพารามเตอรทสงคน (return parameter) และนำคาของพารามเตอรทสงเขามาเกบในสแตคการเรยก แลวเลอน SP
2. เกบลงคควบคมซงไดจาก FP ทชไปยงระเบยนการทำงานของฟงกชนเดมลงในสแตค แลวเลอน SP 3. เลอน FP มาชทเดยวกบ SP 4. เกบเลขทอยกลบลงในสแตคการเรยก แลวเลอน SP 5. จองทในสแตคสำหรบตวแปรเฉพาะท แลวเลอน SP 6. กระโดดไปทำงานทฟงกชนทถกเรยก
ตวแปลภาษาตองเพมคำสงททำงานตามลำดบการเรยกเมอมการเรยกฟงกชน ตวอยางตอไปนแสดงคำสงทจดการลำดบการเรยกใน 3-address code
ตวอยาง พจารณาลำดบการเรยกของ factorial(x)ทแสดงในโปรแกรมดวยตวหนาในโปรแกรมภาษาซตอไปน int factorial(int n){
int f;
if (n==0) f=1;
else f=factorial(n-1)*n;
return f;
}
int main(void) {
int x, y;
x=3;
…
y=factorial(x);
}
parameters
control link
return address
local variables
ระเบยนการทำงาน (activation record)
Programming Language Principles and Processing
124
ฟงกชน factorial ม n เปน input parameter และสงคน return parameter ทกำหนดเปน int ในหวฟงกชน ตวแปลภาษาเพมคำสงของ 3-address code เพอจดการเรยกฟงกชน factorial(x) ดงน
T = SP+4 // make space for return parameter
SP = T // update SP
*SP= x // push x as parameter n
T = SP+4 // size of integer is 4
SP = T // update SP
*SP= FP // push control link
T = SP+16 // size of address is 16
SP = T // update SP
FP = SP // update FP
*SP= RTA // push return address
T = SP+16 // size of address is 16
SP = T // update SP
T = SP+4 // make space for local variable f
SP = T // update SP
goto factorial // jump to function
label RTA // set return address
คำสงชดนทำใหไดระเบยนการทำงานขางลางนอยในสแตคการเรยก
return parameter 4 ไบท parameter n = x 4 ไบท
FP control link 16 ไบท return address 16 ไบท
SP local variable f 4 ไบท
เมอการทำงานของฟงกชนจบลงและมคำสง return เพอใหยอนกลบมาทำงานตอจากคำสงเรยกใชฟงกชนนน ตวแปลภาษาตองสรางคำสงททำใหยอนกลบมาทำงานตอจากคำสงเรยกฟงกชน พรอมทงสงพารามเตอรกลบ และคนคาตวแปรเฉพาะทของฟงกชนนนกลบมา คำสงชดนเรยกวาลำดบการกลบ (return sequence) ซงประกอบดวยการทำงานตอไปน
1. เกบเลขทอยกลบจากระเบยนการทำงานเพอกระโดดไปทำงานทฟงกชนทเรยกตาม 2. เลอน SP ไปชทเดยวกบ FP (ปอปตวแปรเฉพาะทและเลขทอยกลบทง) 3. เลอน FP ไปชทระเบยนการทำงานของฟงกชนเดม โดยนำลงคควบคมไปเกบใน FP 4. เลอน SP ไปชทพารามเตอรทสงคน 5. กระโดดไปทำงานคำสงทเลขทอยกลบ
เมอฟงกชนทำงานจบและกลบมาทำงานหลงคำสงเรยกฟงกชน ตวแปลภาษาตองเพมคำสงททำงานตามลำดบการกลบ ตวอยางตอไปนแสดงคำสงทจดการลำดบการกลบ
ตวอยาง พจารณาลำดบการกลบของ factorial(x)ทแสดงในโปรแกรมในตวอยางทแลว ตวแปลภาษาเพมคำสงของ 3-address code เพอจดการกลบจากฟงกชน factorial ดงน
หลกการและการประมวลภาษาโปรแกรม
125
RET= *FP // save return address
SP = FP // pop local variable f and return address
T = SP-16 // move SP down to control link
SP = T
FP = *SP // move FP down to the caller’s activation record
T = SP-4 // pop input parameter
SP = T
T = SP-4 // move SP down to return parameter
SP = T
goto RET // jump back
6.3.2 การคำนวณเลขทอยของตวแปรในฟงกชน
สำหรบตวแปรเฉพาะทแตละตว ตวแปลภาษาจะเกบตำแหนงของตวแปรในระเบยนการทำงานไวในตารางสญลกษณเพอใชหาเลขทอยของตวแปรนน เมอตองการอางถงตวแปรเฉพาะทในฟงกชนทกำลงทำงานอย ตวแปลภาษาคำนวณเลขทอยของตวแปรนนโดยนำคาของตวชของระเบยนการทำงาน FP บวกกบตำแหนงของตวแปรเฉพาะทจากตารางสญลกษณ ตวอยางตอไปนแสดงการคำนวณหาเลขทอยของตวแปรเฉพาะทในฟงกชน ตวอยางตอไปนแสดงการคำนวณเลขทอยของตวแปรในฟงกชน
ตวอยาง พจารณาฟงกชน factorial(x) และระเบยนการทำงานของฟงกชน factorial ขางลางนint factorial(int n){
int f;
if (n==0) f=1;
else f=factorial(n-1)*n;
return f;
}
return parameter 4 ไบท parameter n 4 ไบท
FP control link 16 ไบท
return address 16 ไบท
SP local variable f 4 ไบท
เมอฟงกชน factorial ทำงาน ระเบยนการทำงานของฟงกชน factorial จะอยบนสดของสแตค ดงนนเราสามารถคำนวณเลขทอยของคาในระเบยนการทำงานไดดงน
- เลขทอยของพารามเตอร n คอ FP-20 - เลขทอยของพารามเตอรทสงกลบ คอ FP-24 - เลขทอยของตวแปรเฉพาะท f คอ FP+16
ดงนน โปรแกรม 3-address code ของฟงกชน factorial เปนดงน
Programming Language Principles and Processing
126
label factorial
fAddr = FP+16 // find the address of local variable f
nAddr = FP-16 // find the address of parameter n
c = *nAddr==0
ifFalse c goto Flabel // if (n==0)
*fAddr = 1 // f=1
goto OUT
label Flabel // else
p = *nAddr -1 // calculate n-1
// ---- call sequence
T = SP+4
SP = T
*SP= p // set parameter as n-1
T = SP+4
SP = T
*SP= FP // save control link
T = SP+16
SP = T
FP = SP
*SP= RTA // save return address
T = SP+16
SP = T
T = SP+4
SP = T
// ---- call factorial
goto factorial
label RTA // set return address
par = *SP // get return parameter
N = *nAddr
*fAddr = par*N // f=factorial(n-1)*n
Label OUT
T = FP-20 // return f; store f as return parameter
*T =*fAddr
// ---- return sequence
RET= *FP // get return address
SP = FP // pop local variables and return address
T = SP-16
SP = T
FP = *SP // move FP to caller’s activation record
T = SP-4
SP = T // pop input parameter
T = SP-4
SP = T // move SP to return parameter
goto RET
จากตวอยางนจะเหนไดวาการอางถงตวแปรเฉพาะทในฟงกชนมขนตอนการคำนวนเลขทอยมากกวาการอางถงตวแปรแบบสถต
หลกการและการประมวลภาษาโปรแกรม
127
Programming Language Principles and Processing
128
7. สรป
การแปลภาษาโปรแกรมแบงเปนหลายขนตอน ในขนแรก สแกนเนอรแบงสายของตวอกขระเปนโทเคนซงเปนหนวยเลกสดทมความหมายในภาษาโปรแกรม จากนนตวแจงสวนนำสายของโทเคนมาตรวจสอบความสมพนธทางไวยากรณทกำหนดของภาษาและสรางตนไมแจงสวนทแสดงความสมพนธทางไวยากรณของโทเคนทงหมด ตอมาตววเคราะหความหมายจงตรวจสอบความถกตองทางความหมายซงมกเกยวของกบชนดของขอมล ขนตอนทง 3 นเรยกวาเปนสวนหนา (front-end) ของตวแปลภาษาและทำหนาทตรวจสอบความถกตองของโปรแกรมและสรางโครงสรางทแสดงความสมพนธของโทเคน
สวนหลง (back-end) ของตวแปลภาษาทำหนาทสรางโปรแกรมในภาษาทตองการจากโครงสรางทไดจากสวนหนา สวนหลงของตวแปลภาษาอาจเปนตวกอกำเนดรหสททำหนาทสรางโปรแกรมในภาษาทตองการจากโครงสรางทไดจากสวนหนา แตการทำงานของสวนหลงอาจสรางโปรแกรมทเปนรหสกลางกอนแลวจงแปลเปนภาษาเครองทตองการ
นอกจากนนตวแปลภาษาอาจมตวปรบประสทธภาพของรหส (code optimization) ทปรบโปรแกรมใหทำงานเรวขนซงไมไดกลาวถงในทน การปรบประสทธภาพนอาจทำบนตนไมแจงสวน รหสกลาง หรอ รหสเครอง กได
หลกการและการประมวลภาษาโปรแกรม
129
Programming Language Principles and Processing
130