ขั้นตอนของคอมไพเลอร์พร้อมตัวอย่าง: กระบวนการและขั้นตอนการคอมไพล์

การออกแบบคอมไพเลอร์มีขั้นตอนอะไรบ้าง?

ผู้รวบรวม ทำงานในเฟสต่างๆ โดยแต่ละเฟสจะแปลงโปรแกรมต้นฉบับจากการแสดงแบบหนึ่งไปยังอีกแบบหนึ่ง แต่ละเฟสจะรับอินพุตจากเฟสก่อนหน้าและป้อนเอาต์พุตไปยังเฟสถัดไปของคอมไพเลอร์
คอมไพเลอร์มี 6 ขั้นตอน แต่ละเฟสนี้จะช่วยในการแปลงค่าภาษาระดับสูงของรหัสเครื่อง ขั้นตอนของคอมไพเลอร์คือ:

  1. การวิเคราะห์คำศัพท์
  2. การวิเคราะห์ไวยากรณ์
  3. การวิเคราะห์เชิงความหมาย
  4. เครื่องสร้างโค้ดระดับกลาง
  5. Code เพิ่มประสิทธิภาพ
  6. Code เครื่องกำเนิดไฟฟ้า
เฟสของคอมไพเลอร์
เฟสของคอมไพเลอร์

ขั้นตอนทั้งหมดเหล่านี้จะแปลงซอร์สโค้ดโดยแบ่งออกเป็นโทเค็น การสร้างแผนผังการแยกวิเคราะห์ และเพิ่มประสิทธิภาพซอร์สโค้ดตามเฟสต่างๆ

ระยะที่ 1: การวิเคราะห์คำศัพท์

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

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

ตัวอย่าง:
x = y + 10

ราชสกุล

X ระบุ
= ตัวดำเนินการมอบหมาย
Y ระบุ
+ ตัวดำเนินการเพิ่มเติม
10 จำนวน

ขั้นตอนที่ 2: การวิเคราะห์ไวยากรณ์

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

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

ตัวอย่าง

ตัวระบุ/หมายเลขใดๆ ถือเป็นนิพจน์
ถ้า x เป็นตัวระบุ และ y+10 เป็นนิพจน์ ดังนั้น x= y+10 จะเป็นคำสั่ง
พิจารณาการแยกวิเคราะห์ต้นไม้สำหรับตัวอย่างต่อไปนี้

(a+b)*c

ตัวอย่างการวิเคราะห์ไวยากรณ์

ในต้นไม้พาร์ส

  • โหนดภายใน: บันทึกด้วยไฟล์ตัวดำเนินการและไฟล์สองไฟล์สำหรับเด็ก
  • Leaf: บันทึกที่มี 2 ช่องขึ้นไป หนึ่งอันสำหรับโทเค็นและข้อมูลอื่น ๆ เกี่ยวกับโทเค็น
  • ตรวจสอบให้แน่ใจว่าองค์ประกอบของโปรแกรมเข้ากันได้อย่างมีความหมาย
  • รวบรวมข้อมูลประเภทและตรวจสอบความเข้ากันได้ของประเภท
  • ตรวจสอบว่าตัวดำเนินการได้รับอนุญาตจากภาษาต้นฉบับหรือไม่

ระยะที่ 3: การวิเคราะห์เชิงความหมาย

การวิเคราะห์เชิงความหมายจะตรวจสอบความสอดคล้องเชิงความหมายของโค้ด ใช้แผนผังไวยากรณ์ของเฟสก่อนหน้าพร้อมกับตารางสัญลักษณ์เพื่อตรวจสอบว่าซอร์สโค้ดที่กำหนดมีความสอดคล้องทางความหมาย นอกจากนี้ยังตรวจสอบว่าโค้ดสื่อความหมายที่เหมาะสมหรือไม่
Semantic Analyzer จะตรวจสอบความไม่ตรงกันของประเภท ตัวดำเนินการที่เข้ากันไม่ได้ ฟังก์ชันที่เรียกด้วยอาร์กิวเมนต์ที่ไม่เหมาะสม ตัวแปรที่ไม่ได้ประกาศ ฯลฯ
หน้าที่ของขั้นตอนการวิเคราะห์ความหมายคือ:

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

ตัวอย่าง

float x = 20.2;
float y = x*30;

ในโค้ดข้างต้น ตัววิเคราะห์ความหมายจะพิมพ์จำนวนเต็ม 30 ให้ลอย 30.0 ก่อนการคูณ

ระยะที่ 4: ระดับกลาง Code รุ่น

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

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

ตัวอย่าง

ตัวอย่างเช่น

total = count + rate * 5

รหัสระดับกลางโดยใช้วิธีรหัสที่อยู่คือ:

 
t1 := int_to_float(5) 
t2 := rate * t1 
t3 := count + t2
total := t3

เฟส 5: Code การเพิ่มประสิทธิภาพ

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

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

ตัวอย่าง:
ลองพิจารณาโค้ดต่อไปนี้

a = intofloat(10)
b = c * a
d = e + b
f = d

สามารถกลายเป็น

b =c * 10.0
f = e+b

เฟส 6: Code รุ่น

Code การสร้างโค้ด (Generation) เป็นขั้นตอนสุดท้ายของกระบวนการคอมไพเลอร์ โดยจะรับข้อมูลจากขั้นตอนการปรับแต่งโค้ด และสร้างโค้ดเพจหรือโค้ดออบเจ็กต์ออกมาเป็นผลลัพธ์ วัตถุประสงค์ของขั้นตอนนี้คือการจัดสรรพื้นที่จัดเก็บและสร้างโค้ดเครื่องที่สามารถย้ายตำแหน่งได้
นอกจากนี้ยังจัดสรรตำแหน่งหน่วยความจำสำหรับตัวแปรด้วย คำแนะนำในโค้ดระดับกลางจะถูกแปลงเป็นคำสั่งเครื่อง ระยะนี้ครอบคลุมโค้ดเพิ่มประสิทธิภาพหรือโค้ดระดับกลางเป็นภาษาเป้าหมาย
ภาษาเป้าหมายคือรหัสเครื่อง ดังนั้น ตำแหน่งหน่วยความจำและรีจิสเตอร์ทั้งหมดจึงถูกเลือกและจัดสรรในระหว่างระยะนี้ด้วย รหัสที่สร้างโดยเฟสนี้จะถูกดำเนินการเพื่อรับอินพุตและสร้างเอาต์พุตที่คาดหวัง

ตัวอย่าง

ก = ข + 60.0
อาจจะแปลเป็นทะเบียนได้

MOVF a, R1
MULF #60.0, R2
ADDF R1, R2

การจัดการตารางสัญลักษณ์

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

เกิดข้อผิดพลาดในการจัดการกิจวัตร

ในขั้นตอนการออกแบบคอมไพลเลอร์อาจเกิดข้อผิดพลาดในทุกขั้นตอนด้านล่าง:

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

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

สรุป

  • คอมไพเลอร์ทำงานในเฟสต่างๆ โดยแต่ละเฟสจะแปลงโปรแกรมต้นฉบับจากการแสดงผลแบบหนึ่งไปยังอีกแบบหนึ่ง
  • หกขั้นตอนของ การออกแบบคอมไพเลอร์ ได้แก่ 1) การวิเคราะห์คำศัพท์ 2) การวิเคราะห์ไวยากรณ์ 3) การวิเคราะห์ความหมาย 4) ตัวสร้างรหัสขั้นกลาง 5) Code ตัวเพิ่มประสิทธิภาพ 6) Code Generator
  • การวิเคราะห์คำศัพท์เป็นระยะแรกที่คอมไพเลอร์สแกนซอร์สโค้ด
  • การวิเคราะห์ไวยากรณ์เป็นเรื่องเกี่ยวกับการค้นพบโครงสร้างในข้อความ
  • การวิเคราะห์เชิงความหมายจะตรวจสอบความสอดคล้องเชิงความหมายของโค้ด
  • เมื่อขั้นตอนการวิเคราะห์เชิงความหมายอยู่เหนือคอมไพลเลอร์แล้ว ให้สร้างโค้ดระดับกลางสำหรับเครื่องเป้าหมาย
  • Code ขั้นตอนการเพิ่มประสิทธิภาพจะลบโค้ดบรรทัดที่ไม่จำเป็นออกและจัดเรียงลำดับคำสั่งใหม่
  • Code ขั้นตอนการสร้างโค้ดจะได้รับข้อมูลจากขั้นตอนการปรับแต่งโค้ด และสร้างโค้ดหน้าเว็บหรือโค้ดออบเจ็กต์ออกมาเป็นผลลัพธ์
  • ตารางสัญลักษณ์ประกอบด้วยบันทึกสำหรับตัวระบุแต่ละตัวพร้อมช่องสำหรับแอตทริบิวต์ของตัวระบุ
  • การจัดการข้อผิดพลาดตามปกติจะจัดการกับข้อผิดพลาดและรายงานในระหว่างหลายขั้นตอน

สรุปโพสต์นี้ด้วย: