คอมไพเลอร์

จากวิกิพีเดีย สารานุกรมเสรี
ข้ามไปที่การนำทาง ข้ามไปที่การค้นหา

ใน การ คำนวณคอมไพเลอร์คือโปรแกรมคอมพิวเตอร์ที่แปลรหัสคอมพิวเตอร์ที่เขียนในภาษาโปรแกรม หนึ่ง ( ภาษา ต้นทาง ) เป็นอีกภาษาหนึ่ง (ภาษาเป้าหมาย ) ชื่อ "คอมไพเลอร์" ใช้เป็นหลักสำหรับโปรแกรมที่แปลซอร์สโค้ดจากภาษาโปรแกรมระดับสูงเป็นภาษาระดับล่าง (เช่นภาษาแอสเซมบลีโค้ดอ็อบเจ็กต์หรือโค้ดเครื่อง ) เพื่อสร้างโปรแกรมปฏิบัติการ [1] [2] : p1 

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

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

คอมไพเลอร์มีแนวโน้มที่จะดำเนินการบางส่วนหรือทั้งหมดต่อไปนี้ ซึ่งมักเรียกว่าเฟส: การ ประมวลผลล่วงหน้าการวิเคราะห์คำศัพท์ การแยก วิเคราะห์ การ วิเคราะห์ เชิงความหมาย ( การแปลที่เน้นไวยากรณ์ ) การแปลงโปรแกรมอินพุตเป็นการแสดงระดับกลางการ ปรับ โค้ดให้เหมาะสมและการสร้างโค้ด คอมไพเลอร์โดยทั่วไปใช้ขั้นตอนเหล่านี้เป็นส่วนประกอบแบบแยกส่วน ส่งเสริมการออกแบบที่มีประสิทธิภาพและความถูกต้องของการเปลี่ยนแปลงของอินพุตต้นทางไปยังเอาต์พุตเป้าหมาย ข้อบกพร่องของโปรแกรมที่เกิดจากพฤติกรรมคอมไพเลอร์ที่ไม่ถูกต้องอาจเป็นเรื่องยากมากที่จะติดตามและแก้ไข ดังนั้น ผู้ดำเนินการคอมไพเลอร์จึงทุ่มเทความพยายามอย่างมากเพื่อให้แน่ใจว่าคอมไพเลอร์ถูกต้อง [3]

คอมไพเลอร์ไม่ได้เป็นเพียงตัวประมวลผลภาษาเดียวที่ใช้ในการแปลงโปรแกรมต้นฉบับ ล่าม คือซอฟต์แวร์คอมพิวเตอร์ ที่แปลงและดำเนินการตามที่ระบุ [2] : p2 กระบวนการแปลมีอิทธิพลต่อการออกแบบภาษาคอมพิวเตอร์ ซึ่งนำไปสู่ความพึงพอใจในการรวบรวมหรือการตีความ ในทางทฤษฎี ภาษาโปรแกรมสามารถมีได้ทั้งคอมไพเลอร์และล่าม ในทางปฏิบัติ ภาษาโปรแกรมมักจะเชื่อมโยงกับภาษาเดียว (คอมไพเลอร์หรือล่าม)

ประวัติ

ไดอะแกรมของการทำงานของคอมไพเลอร์แบบหลายภาษา แบบหลายเป้าหมาย

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

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

  • ตัวอักษรชุดสัญลักษณ์ใด ๆ ก็ตาม
  • สตริงลำดับสัญลักษณ์ที่จำกัด
  • ภาษาชุดสตริงใดๆ บนตัวอักษร

ประโยคในภาษาอาจถูกกำหนดโดยชุดของกฎที่เรียกว่าไวยากรณ์ [4]

แบบฟอร์ม Backus–Naur (BNF) อธิบายไวยากรณ์ของ "ประโยค" ของภาษา และใช้สำหรับไวยากรณ์ของ Algol 60 โดยJohn Backus [5]แนวคิดนี้มาจาก แนวคิด ไวยากรณ์ที่ไม่มีบริบทโดยNoam Chomskyนักภาษาศาสตร์ [6] "BNF และส่วนขยายได้กลายเป็นเครื่องมือมาตรฐานสำหรับการอธิบายไวยากรณ์ของสัญกรณ์การเขียนโปรแกรม และในหลายกรณีของคอมไพเลอร์จะถูกสร้างขึ้นโดยอัตโนมัติจากคำอธิบาย BNF" [7]

ในทศวรรษที่ 1940 Konrad Zuseได้ออกแบบภาษาการเขียนโปรแกรมอัลกอริธึมที่เรียกว่าPlankalkül ("Plan Calculus") แม้ว่าจะไม่มีการใช้งานจริงเกิดขึ้นจนถึงปี 1970 แต่ได้นำเสนอแนวคิดในภายหลังในAPLซึ่งออกแบบโดย Ken Iverson ในปลายทศวรรษ 1950 [8] APL เป็นภาษาสำหรับการคำนวณทางคณิตศาสตร์

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

  • FORTRAN (การแปลสูตร) ​​สำหรับการใช้งานด้านวิศวกรรมและวิทยาศาสตร์ถือเป็นภาษาระดับสูงภาษาแรก [9]
  • COBOL (ภาษาเชิงธุรกิจทั่วไป) พัฒนาจากA-0และFLOW-MATICให้กลายเป็นภาษาระดับสูงที่โดดเด่นสำหรับการใช้งานทางธุรกิจ [10]
  • LISP (List Processor) สำหรับการคำนวณเชิงสัญลักษณ์ (11)

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

เหตุการณ์สำคัญบางประการในการพัฒนาเทคโนโลยีคอมไพเลอร์:

  • พ.ศ. 2495 : คอมไพเลอร์ Autocode ที่ พัฒนาโดยAlick Glennieสำหรับ คอมพิวเตอร์ Manchester Mark Iที่มหาวิทยาลัยแมนเชสเตอร์ ได้รับการพิจารณาว่าเป็นภาษาโปรแกรมคอมไพล์ภาษาแรก
  • 1952 : ทีมของ Grace Hopperที่Remington Randเขียนคอมไพเลอร์สำหรับ ภาษาโปรแกรม A-0 (และตั้งชื่อคำว่าคอมไพเลอร์เพื่ออธิบาย) [13] [14]แม้ว่าคอมไพเลอร์ A-0 จะทำหน้าที่เป็นตัวโหลดหรือตัวเชื่อมโยงมากกว่า มากกว่าแนวคิดสมัยใหม่ของคอมไพเลอร์เต็มรูปแบบ
  • 1954–1957 : ทีมงานที่นำโดยJohn Backusที่IBMได้พัฒนาFORTRANซึ่งปกติถือว่าเป็นภาษาระดับสูงภาษาแรก ในปีพ.ศ. 2500 พวกเขาสร้างคอมไพเลอร์ FORTRAN ซึ่งโดยทั่วไปแล้วให้เครดิตว่าได้แนะนำคอมไพเลอร์ที่สมบูรณ์ตัวแรกอย่างไม่น่าสงสัย
  • พ.ศ. 2502 : การประชุมว่าด้วยภาษาระบบข้อมูล (CODASYL) ได้ริเริ่มการพัฒนา ภาษา โคบอล การออกแบบโคบอลดึง A-0 และ FLOW-MATIC ในช่วงต้นทศวรรษ 1960 COBOL ถูกรวบรวมในหลายสถาปัตยกรรม
  • 1958–1962 : John McCarthy ที่MITออกแบบLISP [15]ความสามารถในการประมวลผลสัญลักษณ์มีคุณสมบัติที่เป็นประโยชน์สำหรับการวิจัยปัญญาประดิษฐ์ ในปีพ.ศ. 2505 LISP 1.5 ได้เผยแพร่เครื่องมือบางอย่าง: ล่ามที่เขียนโดย Stephen Russell และ Daniel J. Edwards ผู้เรียบเรียงและแอสเซมเบลอร์ที่เขียนโดย Tim Hart และ Mike Levin [16]

ระบบปฏิบัติการและซอฟต์แวร์ยุคแรกเขียนด้วยภาษาแอสเซมบลี ในทศวรรษที่ 1960 และต้นทศวรรษ 1970 การใช้ภาษาระดับสูงสำหรับการเขียนโปรแกรมระบบยังคงเป็นที่ถกเถียงกันอยู่เนื่องจากข้อจำกัดของทรัพยากร อย่างไรก็ตาม การวิจัยและความพยายามในอุตสาหกรรมหลายอย่างเริ่มเปลี่ยนไปสู่ภาษาโปรแกรมระบบระดับสูงเช่น BCPL , BLISS , BและC

BCPL (Basic Combined Programming Language) ออกแบบในปี 1966 โดยMartin Richardsแห่งมหาวิทยาลัยเคมบริดจ์ เดิมทีได้รับการพัฒนาให้เป็นเครื่องมือเขียนคอมไพเลอร์ [17]มีการใช้คอมไพเลอร์หลายตัว หนังสือของริชาร์ดส์ให้ข้อมูลเชิงลึกเกี่ยวกับภาษาและคอมไพเลอร์ [18] BCPL ไม่ได้เป็นเพียงภาษาโปรแกรมระบบที่มีอิทธิพลซึ่งยังคงใช้ในการวิจัย[19]แต่ยังเป็นพื้นฐานสำหรับการออกแบบภาษา B และ C

BLISS (ภาษาพื้นฐานสำหรับการนำซอฟต์แวร์ระบบไปใช้) ได้รับการพัฒนาสำหรับคอมพิวเตอร์ Digital Equipment Corporation (DEC) PDP-10 โดยทีมวิจัย Carnegie Mellon University (CMU) ของ WA Wulf ทีมงาน CMU ได้พัฒนาคอมไพเลอร์ BLISS-11 ต่อไปในปี 1970

Multics (Multiplexed Information and Computing Service) ซึ่งเป็นโครงการระบบปฏิบัติการแบ่งปันเวลา เกี่ยวข้องกับMIT , Bell Labs , General Electric (ต่อมาคือHoneywell ) และนำโดยFernando Corbatóจาก MIT [20] Multics เขียนด้วย ภาษา PL/Iที่พัฒนาโดย IBM และ IBM User Group [21]เป้าหมายของ IBM คือการตอบสนองความต้องการทางธุรกิจ วิทยาศาสตร์ และการเขียนโปรแกรมระบบ มีภาษาอื่นๆ ที่พิจารณาได้ แต่ PL/I เสนอโซลูชันที่สมบูรณ์ที่สุดแม้ว่าจะไม่ได้ใช้งานก็ตาม [22]ในช่วงสองสามปีแรกของโครงการ Multics เซตย่อยของภาษาสามารถคอมไพล์เป็นภาษาแอสเซมบลีด้วยคอมไพเลอร์ Early PL/I (EPL) โดย Doug McIlory และ Bob Morris จาก Bell Labs [23] EPL สนับสนุนโครงการจนกระทั่งสามารถพัฒนาคอมไพเลอร์สายรัดบูตสำหรับ PL/I แบบเต็มได้ [24]

Bell Labs ออกจากโครงการ Multics ในปี 1969 และพัฒนาภาษาโปรแกรมระบบBตามแนวคิด BCPL เขียนโดยDennis RitchieและKen Thompson Ritchie ได้สร้างคอมไพเลอร์รัดบูตสำหรับ B และเขียน ระบบปฏิบัติการ Unics (Uniplexed Information and Computing Service) สำหรับ PDP-7 ใน B Unics ในที่สุดก็กลายเป็น Unix

Bell Labs เริ่มการพัฒนาและขยายภาษา Cโดยอิงจาก B และ BCPL คอมไพเลอร์ BCPL ถูกส่งไปยัง Multics โดย Bell Labs และ BCPL เป็นภาษาที่ต้องการที่ Bell Labs [25]ในขั้นต้น โปรแกรมส่วนหน้าสำหรับคอมไพเลอร์ B ของ Bell Labs ถูกใช้ในขณะที่คอมไพเลอร์ C ได้รับการพัฒนา ในปี 1971 PDP-11 ใหม่ได้จัดเตรียมทรัพยากรเพื่อกำหนดส่วนขยายให้กับ B และเขียนคอมไพเลอร์ใหม่ ภายในปี 1973 การออกแบบภาษา C นั้นสมบูรณ์โดยพื้นฐานแล้ว และเคอร์เนล Unix สำหรับ PDP-11 ถูกเขียนใหม่ใน C. Steve Johnson เริ่มพัฒนา Portable C Compiler (PCC) เพื่อรองรับการกำหนดเป้าหมายใหม่ของคอมไพเลอร์ C ไปยังเครื่องใหม่ [26] [27]

การเขียนโปรแกรมเชิงวัตถุ (OOP) นำเสนอความเป็นไปได้ที่น่าสนใจสำหรับการพัฒนาและบำรุงรักษาแอปพลิเคชัน แนวคิด OOP ย้อนกลับไปได้อีก แต่เป็นส่วนหนึ่งของวิทยาศาสตร์ภาษาLISPและSimula [28]ที่ Bell Labs การพัฒนาC++เริ่มให้ความสนใจ OOP [29] C++ ถูกใช้ครั้งแรกในปี 1980 สำหรับการเขียนโปรแกรมระบบ การออกแบบเริ่มต้นใช้ประโยชน์จากความสามารถในการเขียนโปรแกรมระบบภาษา C ด้วยแนวคิด Simula สิ่งอำนวยความสะดวกเชิงวัตถุถูกเพิ่มเข้ามาในปี 1983 [30]โปรแกรม Cfront ใช้งานส่วนหน้า C++ สำหรับคอมไพเลอร์ภาษา C84 ในปีถัดมา คอมไพเลอร์ C++ หลายตัวได้รับการพัฒนาเมื่อความนิยมของ C++ เพิ่มขึ้น

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

DARPA (Defense Advanced Research Projects Agency) สนับสนุนโครงการคอมไพเลอร์ร่วมกับทีมวิจัย CMU ของ Wulf ในปี 1970 การ ออกแบบ PQCC คอมไพเลอร์คุณภาพการผลิต-คอมไพเลอร์ จะผลิต Production Quality Compiler (PQC) จากคำจำกัดความที่เป็นทางการของภาษาต้นทางและเป้าหมาย [31] PQCC พยายามที่จะขยายคำว่าคอมไพเลอร์-คอมไพเลอร์เกินกว่าความหมายดั้งเดิมในฐานะตัวสร้างพาร์เซอร์ (เช่นYacc ) โดยไม่ประสบความสำเร็จมากนัก PQCC อาจเรียกได้ว่าเป็นเครื่องกำเนิดคอมไพเลอร์อย่างถูกต้องกว่า

การวิจัย PQCC ในกระบวนการสร้างโค้ดพยายามสร้างระบบการเขียนคอมไพเลอร์แบบอัตโนมัติอย่างแท้จริง ความพยายามค้นพบและออกแบบโครงสร้างเฟสของ PQC คอมไพเลอร์ BLISS-11 มีโครงสร้างเริ่มต้น [32]ขั้นตอนรวมถึงการวิเคราะห์ (ส่วนหน้า) การแปลระดับกลางไปยังเครื่องเสมือน (ปลายตรงกลาง) และการแปลไปยังเป้าหมาย (ส่วนหลัง) TCOL ได้รับการพัฒนาสำหรับการวิจัย PQCC เพื่อจัดการกับโครงสร้างเฉพาะภาษาในการเป็นตัวแทนระดับกลาง [33]รูปแบบของ TCOL รองรับภาษาต่างๆ โครงการ PQCC ได้ตรวจสอบเทคนิคการสร้างคอมไพเลอร์แบบอัตโนมัติ แนวคิดการออกแบบได้รับการพิสูจน์แล้วว่ามีประโยชน์ในการเพิ่มประสิทธิภาพคอมไพเลอร์และคอมไพเลอร์สำหรับภาษาโปรแกรม Ada (ตั้งแต่ปี 1995 ที่เน้น เชิง วัตถุ)

เอกสารAda STONEMAN [ ต้องการอ้างอิง ]ได้ทำให้สภาพแวดล้อมสนับสนุนโปรแกรม (APSE) เป็นทางการ พร้อมด้วยเคอร์เนล (KAPSE) และค่าต่ำสุด (MAPSE) ล่าม Ada NYU/ED สนับสนุนความพยายามในการพัฒนาและกำหนดมาตรฐานกับ American National Standards Institute (ANSI) และ International Standards Organisation (ISO) การพัฒนาคอมไพเลอร์ Ada เบื้องต้นโดย US Military Services รวมถึงคอมไพเลอร์ในสภาพแวดล้อมการออกแบบแบบบูรณาการที่สมบูรณ์ตามแนวของSTONEMANเอกสาร. กองทัพบกและกองทัพเรือทำงานในโครงการ Ada Language System (ALS) ที่กำหนดเป้าหมายไปยังสถาปัตยกรรม DEC/VAX ในขณะที่กองทัพอากาศเริ่มต้นจาก Ada Integrated Environment (AIE) ซึ่งกำหนดเป้าหมายไปที่ IBM 370 series แม้ว่าโครงการไม่ได้ให้ผลลัพธ์ตามที่ต้องการ แต่ก็มีส่วนสนับสนุนความพยายามโดยรวมในการพัฒนา Ada [34]

ความพยายามในการคอมไพเลอร์ของ Ada อื่นๆ ได้เริ่มขึ้นในสหราชอาณาจักรที่มหาวิทยาลัยยอร์กและในเยอรมนีที่มหาวิทยาลัยคาร์ลสรูเฮอ ในสหรัฐอเมริกา Verdix (ได้มาโดย Rational ในภายหลัง) ได้ส่งมอบ Verdix Ada Development System (VADS) ให้กับกองทัพบก VADS ได้จัดเตรียมชุดเครื่องมือในการพัฒนารวมถึงคอมไพเลอร์ Unix/VADS สามารถโฮสต์บนแพลตฟอร์ม Unix ที่หลากหลาย เช่น DEC Ultrix และ Sun 3/60 Solaris ที่กำหนดเป้าหมายไปที่ Motorola 68020 ในการประเมิน Army CECOM [35]ในไม่ช้าก็มีคอมไพเลอร์ Ada จำนวนมากที่ผ่านการทดสอบ Ada Validation โครงการ Free Software Foundation GNU ได้พัฒนาGNU Compiler Collection (GCC) ซึ่งให้ความสามารถหลักในการสนับสนุนหลายภาษาและเป้าหมาย เวอร์ชัน Ada GNATเป็นหนึ่งในคอมไพเลอร์ Ada ที่ใช้กันอย่างแพร่หลายมากที่สุด GNAT ฟรีแต่ยังมีการสนับสนุนเชิงพาณิชย์ เช่น AdaCore ซึ่งก่อตั้งขึ้นในปี 1994 เพื่อจัดหาโซลูชันซอฟต์แวร์เชิงพาณิชย์สำหรับ Ada GNAT Pro รวม GNAT ที่ใช้ GNU GCC เข้ากับชุดเครื่องมือเพื่อให้มีสภาพแวดล้อมการพัฒนาแบบบูรณาการ

ภาษาระดับสูงยังคงขับเคลื่อนการวิจัยและพัฒนาคอมไพเลอร์อย่างต่อเนื่อง พื้นที่โฟกัสรวมถึงการเพิ่มประสิทธิภาพและการสร้างโค้ดอัตโนมัติ แนวโน้มของภาษาโปรแกรมและสภาพแวดล้อมการพัฒนามีอิทธิพลต่อเทคโนโลยีคอมไพเลอร์ คอมไพเลอร์เพิ่มเติมรวมอยู่ในการกระจายภาษา (PERL, Java Development Kit) และเป็นส่วนหนึ่งของ IDE (VADS, Eclipse, Ada Pro) ความสัมพันธ์และการพึ่งพาซึ่งกันและกันของเทคโนโลยีเติบโตขึ้น การถือกำเนิดของบริการเว็บส่งเสริมการเติบโตของภาษาเว็บและภาษาสคริปต์ สคริปต์ติดตามย้อนกลับไปในยุคแรก ๆ ของ Command Line Interfaces (CLI) ซึ่งผู้ใช้สามารถป้อนคำสั่งที่จะดำเนินการโดยระบบ แนวคิด User Shell พัฒนาขึ้นด้วยภาษาสำหรับเขียนโปรแกรมเชลล์ การออกแบบ Windows รุ่นแรกให้ความสามารถในการตั้งโปรแกรมแบบแบตช์อย่างง่าย การแปลงแบบดั้งเดิมของภาษาเหล่านี้ใช้ล่าม แม้ว่าจะไม่ได้ใช้กันอย่างแพร่หลาย แต่คอมไพเลอร์ Bash และ Batch ก็ถูกเขียนขึ้นแล้ว ภาษาที่ตีความที่ซับซ้อนมากขึ้นเมื่อเร็วๆ นี้ได้กลายเป็นส่วนหนึ่งของชุดเครื่องมือสำหรับนักพัฒนา ภาษาสคริปต์สมัยใหม่ ได้แก่ PHP, Python, Ruby และ Lua (Lua ใช้กันอย่างแพร่หลายในการพัฒนาเกม) ทั้งหมดนี้รองรับล่ามและคอมไพเลอร์(36)

"เมื่อสาขาการคอมไพล์เริ่มขึ้นในช่วงปลายทศวรรษ 50 จุดเน้นของมันถูกจำกัดอยู่ที่การแปลโปรแกรมภาษาระดับสูงเป็นรหัสเครื่อง ... ฟิลด์คอมไพเลอร์มีความเกี่ยวพันกับสาขาวิชาอื่นๆ มากขึ้น รวมถึงสถาปัตยกรรมคอมพิวเตอร์ ภาษาโปรแกรม วิธีการที่เป็นทางการ วิศวกรรมซอฟต์แวร์และความปลอดภัยของคอมพิวเตอร์” [37]บทความ "Compiler Research: The Next 50 Years" กล่าวถึงความสำคัญของภาษาเชิงวัตถุและ Java ความปลอดภัยและการคำนวณแบบคู่ขนานถูกอ้างถึงในเป้าหมายการวิจัยในอนาคต

การสร้างคอมไพเลอร์

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

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

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

คอมไพเลอร์แบบผ่านครั้งเดียวและแบบหลายรอบ

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

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

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

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

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

โครงสร้างคอมไพเลอร์สามขั้นตอน

การออกแบบคอมไพเลอร์

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

  • ส่วนหน้าจะสแกนอินพุตและตรวจสอบไวยากรณ์และความหมายตามภาษาต้นฉบับที่ระบุ สำหรับภาษาที่พิมพ์แบบคงที่จะทำการตรวจสอบประเภทโดยรวบรวมข้อมูลประเภท ถ้าโปรแกรมอินพุตไม่ถูกต้องทางไวยากรณ์หรือมีข้อผิดพลาดประเภท จะสร้างข้อผิดพลาดและ/หรือข้อความเตือน ซึ่งมักจะระบุตำแหน่งในซอร์สโค้ดที่ตรวจพบปัญหา ในบางกรณีข้อผิดพลาดที่แท้จริงอาจ (มาก) ก่อนในโปรแกรม ลักษณะของส่วนหน้ารวมถึงการวิเคราะห์คำศัพท์ การวิเคราะห์ไวยากรณ์ และการวิเคราะห์เชิงความหมาย ส่วนหน้าจะเปลี่ยนโปรแกรมอินพุตให้เป็นตัวแทนระดับกลาง(IR) สำหรับการประมวลผลต่อไปโดยปลายตรงกลาง IR นี้มักจะเป็นตัวแทนระดับล่างของโปรแกรมที่เกี่ยวกับซอร์สโค้ด
  • ระดับกลางดำเนินการปรับให้เหมาะสมบน IR ที่ไม่ขึ้นกับสถาปัตยกรรม CPU ที่เป็นเป้าหมาย ความเป็นอิสระของซอร์สโค้ด/รหัสเครื่องนี้มีจุดมุ่งหมายเพื่อให้สามารถใช้การเพิ่มประสิทธิภาพทั่วไปร่วมกันระหว่างเวอร์ชันของคอมไพเลอร์ที่สนับสนุนภาษาต่างๆ และโปรเซสเซอร์เป้าหมาย ตัวอย่างของการปรับให้เหมาะสมระดับกลาง ได้แก่ การลบที่ไม่มีประโยชน์ ( การกำจัดโค้ดที่ไม่ ทำงาน ) หรือโค้ดที่ไม่สามารถเข้าถึงได้ ( การวิเคราะห์ความ สามารถในการเข้าถึง ) การค้นพบและการแพร่กระจายของค่าคงที่ ( การแพร่กระจายคงที่ ) การย้ายตำแหน่งของการคำนวณไปยังตำแหน่งที่ดำเนินการน้อยกว่า (เช่น ออกจากลูป) หรือความเชี่ยวชาญด้านการคำนวณตามบริบท ในที่สุดก็สร้าง IR ที่ "ปรับให้เหมาะสม" ซึ่งใช้โดยส่วนหลัง
  • ส่วนหลังใช้ IR ที่ปรับให้เหมาะสมจากปลายตรงกลาง มันอาจทำการวิเคราะห์ การแปลง และการปรับแต่งเพิ่มเติมที่เฉพาะเจาะจงสำหรับสถาปัตยกรรม CPU เป้าหมาย ส่วนหลังจะสร้างรหัสแอสเซมบลีที่ขึ้นกับเป้าหมาย ดำเนินการจัดสรรการลงทะเบียนในกระบวนการ ส่วนหลังดำเนินการจัดตารางคำสั่งซึ่งจะจัดลำดับคำสั่งใหม่เพื่อให้หน่วยปฏิบัติการ แบบขนาน ไม่ว่างโดยการเติมช่องหน่วงเวลา แม้ว่าปัญหาการปรับให้เหมาะสมส่วนใหญ่จะเป็นแบบ NP-hard , heuristicเทคนิคในการแก้ปัญหานั้นได้รับการพัฒนามาอย่างดีและปัจจุบันได้นำไปใช้ในคอมไพเลอร์คุณภาพการผลิต โดยทั่วไปแล้ว เอาต์พุตของส่วนหลังจะเป็นรหัสเครื่องสำหรับโปรเซสเซอร์และระบบปฏิบัติการเฉพาะ

แนวทาง front/middle/back-end นี้ทำให้สามารถรวมส่วนหน้าสำหรับภาษาต่างๆ กับส่วนหลังสำหรับCPU ที่แตกต่างกัน ในขณะที่แบ่งปันการเพิ่มประสิทธิภาพของส่วนตรงกลาง [38]ตัวอย่างที่ใช้งานได้จริงของแนวทางนี้คือGNU Compiler Collection , Clang ( คอมไพเลอร์ C/C++ ที่ใช้LLVM ), [39]และAmsterdam Compiler Kitซึ่งมีส่วนหน้าหลายส่วน การเพิ่มประสิทธิภาพที่ใช้ร่วมกัน และส่วนหลังหลายส่วน

ส่วนหน้า

ตัวอย่างLexerและparserสำหรับC เริ่มจากลำดับของอักขระ " if(net>0.0)total+=net*(1.0+tax/100.0);" เครื่องสแกนจะประกอบลำดับของโทเค็นและจัดหมวดหมู่แต่ละรายการ เช่นตัวระบุคำสงวนตัวเลขหรือตัวดำเนินการ ลำดับหลังจะถูกแปลงโดย parser เป็นแผนผังไวยากรณ์ซึ่งจะได้รับการปฏิบัติโดยขั้นตอนของคอมไพเลอร์ที่เหลือ สแกนเนอร์และ parser จัดการส่วนปกติและถูกต้องตามบริบทของไวยากรณ์สำหรับ Cตามลำดับ

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

แม้ว่าฟรอนท์เอนด์จะเป็นฟังก์ชันหรือโปรแกรมแบบเสาหินเดียวก็ได้ เช่นเดียวกับในโปรแกรมแยกวิเคราะห์ แบบไม่มีเครื่องสแกน ระบบนี้ถูกนำไปใช้และวิเคราะห์ตามธรรมเนียมเป็นหลายขั้นตอน ซึ่งอาจดำเนินการตามลำดับหรือพร้อมกัน วิธีนี้เป็นที่นิยมเนื่องจากเป็นแบบแยกส่วนและ แยก ข้อกังวล โดยทั่วไปแล้วในปัจจุบัน ส่วนหน้าแบ่งออกเป็นสามขั้นตอน: การวิเคราะห์คำศัพท์ (หรือที่เรียกว่า lexing หรือการสแกน) การวิเคราะห์ไวยากรณ์ (หรือที่เรียกว่าการสแกนหรือการแยกวิเคราะห์) และการวิเคราะห์เชิงความหมาย. การแยกวิเคราะห์และการแยกวิเคราะห์ประกอบด้วยการวิเคราะห์วากยสัมพันธ์ (ไวยากรณ์ของคำและไวยากรณ์วลี ตามลำดับ) และในกรณีง่าย ๆ โมดูลเหล่านี้ (lexer และ parser) สามารถสร้างได้โดยอัตโนมัติจากไวยากรณ์สำหรับภาษานั้น แม้ว่าในกรณีที่ซับซ้อนกว่านั้น จำเป็นต้องมีการแก้ไขด้วยตนเอง . ไวยากรณ์คำศัพท์และไวยากรณ์วลีมักเป็นไวยากรณ์ที่ไม่มีบริบทซึ่งทำให้การวิเคราะห์ง่ายขึ้นอย่างมาก โดยมีความไวต่อบริบทที่จัดการในขั้นตอนการวิเคราะห์เชิงความหมาย ขั้นตอนการวิเคราะห์เชิงความหมายโดยทั่วไปจะซับซ้อนกว่าและเขียนด้วยมือ แต่สามารถดำเนินการอัตโนมัติบางส่วนหรือทั้งหมดได้โดยใช้แอตทริบิวต์ไวยากรณ์ ขั้นตอนเหล่านี้สามารถแยกย่อยได้อีก: lexing เป็นการสแกนและประเมินผล และการแยกวิเคราะห์เป็นการสร้างแผนผังโครงสร้างที่เป็นรูปธรรม(CST, parse tree) แล้วแปลงเป็นแผนผังไวยากรณ์นามธรรม (AST, แผนผังไวยากรณ์) ในบางกรณีมีการใช้เฟสเพิ่มเติม โดยเฉพาะการสร้างเส้นใหม่และ การ ประมวลผลล่วงหน้าแต่สิ่งเหล่านี้มีน้อยมาก

ขั้นตอนหลักของส่วนหน้ามีดังต่อไปนี้:

  • การสร้างบรรทัดใหม่จะแปลงลำดับอักขระอินพุตเป็นรูปแบบบัญญัติที่พร้อมสำหรับตัวแยกวิเคราะห์ ภาษาที่หยุดคีย์เวิร์ดหรืออนุญาตให้มีการเว้นวรรคภายในตัวระบุโดยอำเภอใจจำเป็นต้องใช้เฟสนี้ ตัวบนลงล่างแบบเรียกซ้ำซึ่งใช้ในปี 1960 มักจะอ่านแหล่งที่มาทีละอักขระและไม่ต้องการขั้นตอนการสร้างโทเค็นแยกจากกัน Atlas AutocodeและImp(และการใช้งานALGOLและCoral 66) เป็นตัวอย่างของภาษาสตรอป ซึ่งคอมไพเลอร์จะมีเฟสการสร้างเส้นใหม่
  • การประมวลผล ล่วงหน้ารองรับการแทนที่แมโคร และ การคอมไพล์แบบโดยปกติ ขั้นตอนก่อนการประมวลผลจะเกิดขึ้นก่อนการวิเคราะห์วากยสัมพันธ์หรือเชิงความหมาย เช่นในกรณีของ C ตัวประมวลผลล่วงหน้าจัดการกับโทเค็นคำศัพท์มากกว่ารูปแบบวากยสัมพันธ์ อย่างไรก็ตาม บางภาษา เช่น Schemeรองรับการแทนที่มาโครตามรูปแบบวากยสัมพันธ์
  • การวิเคราะห์คำศัพท์ (หรือที่เรียกว่า lexingหรือ tokenization ) แบ่งข้อความซอร์สโค้ดออกเป็นลำดับของชิ้นส่วนเล็กๆ ที่เรียกว่าlexical tokens [40]ระยะนี้สามารถแบ่งออกเป็นสองขั้นตอน: การสแกนซึ่งแบ่งข้อความที่ป้อนเข้าเป็นหน่วยวากยสัมพันธ์ที่เรียกว่า lexemesและกำหนดหมวดหมู่ และการประเมินซึ่งแปลง lexemes เป็นค่าที่ประมวลผล โทเค็นคือคู่ที่ประกอบด้วยชื่อโทเค็น และ ค่าโทเค็นที่ไม่บังคับ [41]หมวดหมู่โทเค็นทั่วไปอาจรวมถึงตัวระบุ คีย์เวิร์ด ตัวคั่น ตัวดำเนินการ ตัวอักษร และความคิดเห็น แม้ว่าชุดของหมวดหมู่โทเค็นจะแตกต่างกันไปในภาษาโปรแกรมต่างๆ ไวยากรณ์ lexeme โดยทั่วไปแล้วเป็นภาษาปกติดังนั้น ออโตมาตันสถานะจำกัดที่สร้างจากนิพจน์ทั่วไปจึงสามารถนำมาใช้เพื่อจดจำได้ ซอฟต์แวร์ที่ทำการวิเคราะห์คำศัพท์เรียกว่าตัววิเคราะห์คำศัพท์ นี่อาจไม่ใช่ขั้นตอนที่แยกจากกัน—สามารถใช้ร่วมกับขั้นตอนการแยกวิเคราะห์ในการparsing แบบไม่ใช้เครื่องสแกนซึ่งในกรณีนี้การแยกวิเคราะห์จะทำที่ระดับอักขระ ไม่ใช่ระดับโทเค็น
  • การวิเคราะห์ไวยากรณ์ (หรือที่เรียกว่า parsing ) เกี่ยวข้องกับการแยกวิเคราะห์ลำดับโทเค็นเพื่อระบุโครงสร้างวากยสัมพันธ์ของโปรแกรม ระยะนี้โดยทั่วไปจะสร้าง parse treeซึ่งแทนที่ลำดับเชิงเส้นของโทเค็นด้วยโครงสร้างแบบต้นไม้ที่สร้างขึ้นตามกฎของ ไวยากรณ์ที่ เป็นทางการซึ่งกำหนดไวยากรณ์ของภาษา ต้นไม้แยกวิเคราะห์มักจะถูกวิเคราะห์ เสริม และแปลงโดยขั้นตอนต่อมาในคอมไพเลอร์ [42]
  • การวิเคราะห์เชิงความหมายจะเพิ่มข้อมูลเชิงความหมายให้กับแผนผังการแยกวิเคราะห์และสร้างตารางสัญลักษณ์ ขั้นตอนนี้ดำเนินการตรวจสอบเชิงความหมาย เช่น การตรวจสอบประเภท (การตรวจสอบข้อผิดพลาดของประเภท) หรือการผูกวัตถุ (การเชื่อมโยงตัวแปรและการอ้างอิงฟังก์ชันกับคำจำกัดความ) หรือ การกำหนดที่ แน่นอน (กำหนดให้ตัวแปรท้องถิ่นทั้งหมดต้องเริ่มต้นก่อนใช้งาน) การปฏิเสธโปรแกรมที่ไม่ถูกต้อง หรือการออก คำเตือน การวิเคราะห์เชิงความหมายมักต้องการ parse tree ที่สมบูรณ์ หมายความว่าเฟสนี้มีเหตุผลตามหลังเฟสการแยกวิเคราะห์และมีเหตุผลก่อนการสร้างโค้ดเฟส แม้ว่ามักจะเป็นไปได้ที่จะพับหลายเฟสเป็นรหัสเดียวในการใช้งานคอมไพเลอร์

ตอนกลาง

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

ขั้นตอนหลักของปลายตรงกลางมีดังต่อไปนี้:

การวิเคราะห์คอมไพเลอร์เป็นข้อกำหนดเบื้องต้นสำหรับการเพิ่มประสิทธิภาพคอมไพเลอร์และทำงานร่วมกันอย่างแน่นหนา ตัวอย่างเช่นการวิเคราะห์การพึ่งพาเป็นสิ่งสำคัญสำหรับการแปลงลู

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

การวิเคราะห์ระหว่างขั้นตอนและการปรับให้เหมาะสมเป็นเรื่องปกติในคอมไพเลอร์เชิงพาณิชย์สมัยใหม่จากHP , IBM , SGI , Intel , Microsoft และ Sun Microsystems GCCซอฟต์แวร์เสรี ถูกวิพากษ์วิจารณ์มาเป็นเวลานานเนื่องจากขาดการเพิ่มประสิทธิภาพระหว่างขั้นตอนที่มีประสิทธิภาพ แต่กำลังเปลี่ยนแปลงไปในแง่นี้ คอมไพเลอร์โอเพ่นซอร์สอีกตัวหนึ่งที่มีโครงสร้างพื้นฐานการวิเคราะห์และการเพิ่มประสิทธิภาพอย่างเต็มรูปแบบคือOpen64ซึ่งหลายองค์กรใช้เพื่อการวิจัยและวัตถุประสงค์เชิงพาณิชย์

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

ด้านหลัง

แบ็คเอนด์มีหน้าที่รับผิดชอบในการเพิ่มประสิทธิภาพเฉพาะสถาปัตยกรรม CPU และสำหรับการสร้างโค้ด[43 ]

ขั้นตอนหลักของส่วนหลังมีดังต่อไปนี้:

  • การเพิ่มประสิทธิภาพขึ้นอยู่กับเครื่อง : การเพิ่มประสิทธิภาพที่ขึ้นอยู่กับรายละเอียดของสถาปัตยกรรม CPU ที่คอมไพเลอร์กำหนดเป้าหมาย [44]ตัวอย่างที่เด่นชัดคือ การปรับ ช่องมองภาพให้เหมาะสมที่สุด ซึ่งจะเขียนลำดับคำสั่งแอสเซมเบลอร์สั้น ๆ ใหม่เป็นคำสั่งที่มีประสิทธิภาพมากขึ้น
  • การสร้างโค้ด : ภาษากลางที่แปลงแล้วจะถูกแปลเป็นภาษาที่ส่งออก ซึ่งมักจะเป็นภาษาเครื่อง ดั้งเดิม ของระบบ สิ่งนี้เกี่ยวข้องกับการตัดสินใจด้านทรัพยากรและการจัดเก็บ เช่น การตัดสินใจเลือกตัวแปรที่จะพอดีกับรีจิ สเตอร์ และหน่วยความจำ การเลือกและการกำหนดเวลาของคำสั่งเครื่องที่เหมาะสมพร้อมกับโหมดการกำหนดแอดเดรสที่ เกี่ยวข้อง (ดูอัลกอริธึม Sethi–Ullmanด้วย) อาจจำเป็นต้องสร้างข้อมูลการดีบักเพื่ออำนวยความสะดวกในการดีบัก

ความถูกต้องของคอมไพเลอร์

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

ภาษาที่คอมไพล์เทียบกับภาษาที่แปลแล้ว

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

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

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

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

ประเภท

การจำแนกประเภทคอมไพเลอร์หนึ่งประเภทคือโดยแพลตฟอร์มที่โค้ดที่สร้างขึ้นรัน นี้เรียกว่าแพลตฟอร์มเป้าหมาย

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

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

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

แม้ว่าประเภทคอมไพเลอร์ทั่วไปจะแสดงรหัสเครื่อง แต่ก็มีประเภทอื่นๆ อีกมาก:

ดูเพิ่มเติม

อ้างอิง

  1. ^ PC Mag Staff (28 กุมภาพันธ์ 2019) "สารานุกรม: คำจำกัดความของคอมไพเลอร์" . PCMag.com . สืบค้นเมื่อ28 กุมภาพันธ์ 2017 .
  2. ^ a b Compilers: Principles, Techniques, and Toolsโดย Alfred V. Aho, Ravi Sethi, Jeffrey D. Ullman - Second Edition, 2007
  3. ^ ซัน เฉิงเหนียน; เลอ วู; จาง, Qirun; ซู เจิ้นตง (2016). "เพื่อทำความเข้าใจข้อบกพร่องของคอมไพเลอร์ใน GCC และ LLVM " อ สม . อิสสตา 2016: 294–305 ดอย : 10.1145/2931037.2931074 . ISBN 9781450343909. S2CID  8339241 .
  4. ^ บันทึกการบรรยาย Compilers: Principles, Techniques, and Tools Jing-Shin Chang Department of Computer Science & Information Engineering National Chi-Nan University
  5. ^ Naur, P. et al. "รายงาน ALGOL 60" Communications of the ACM 3 (พฤษภาคม 1960), 299–314
  6. ชอมสกี โนม; ไลท์ฟุต, เดวิด ดับเบิลยู. (2002). โครงสร้างวากยสัมพันธ์ . วอลเตอร์ เดอ กรอยเตอร์. ISBN 978-3-11-017279-9.
  7. กรีส, เดวิด (2012). "ภาคผนวก 1: แบบฟอร์ม Backus-Naur" . ศาสตร์แห่งการเขียนโปรแกรม . สื่อวิทยาศาสตร์และธุรกิจของสปริงเกอร์ หน้า 304. ISBN 978-1461259831.
  8. ไอเวอร์สัน, เคนเนธ อี. (1962). ภาษาโปรแกรม . จอห์น ไวลีย์ แอนด์ ซันส์. ISBN 978-0-471430-14-8.
  9. ^ แบคคัส, จอห์น. "ประวัติของ FORTRAN I, II และ III" (PDF) . ประวัติภาษาโปรแกรมมิ่ง . Softwarepreservation.org .
  10. พอร์เตอร์ อดัมส์, วิกกี้ (5 ตุลาคม พ.ศ. 2524) กัปตันเกรซ เอ็ม. ฮ็อปเปอร์: แม่ของโคบอล อินโฟเวิลด์ 3 (20): 33. ISSN 0199-6649.
  11. ^ แม็กคาร์ธี เจ.; เบรย์ตัน, อาร์.; เอ็ดเวิร์ด, ดี.; ฟ็อกซ์, พี.; Hodes, L.; ลัคแฮม, D.; มาลิง, K.; ปาร์ค, ดี.; รัสเซล, เอส. (มีนาคม 2503) "คู่มือโปรแกรมเมอร์ LISP I" (PDF) บอสตัน รัฐแมสซาชูเซตส์: กลุ่มปัญญาประดิษฐ์ ศูนย์คอมพิวเตอร์ MIT และห้องปฏิบัติการวิจัย
  12. ^ Compilers Principles, Techniques, & Tools ฉบับที่ 2 โดย Aho, Lam, Sethi, Ullman ISBN 0-321-48681-1 
  13. ฮอปเปอร์, เกรซ เมอร์เรย์ (1952) "การศึกษาคอมพิวเตอร์". การดำเนินการของการประชุมระดับชาติ ACM ปี 1952 (พิตต์สเบิร์ก) : 243–249 ดอย : 10.1145/609784.609818 . S2CID 10081016 . 
  14. ริดจ์เวย์, ริชาร์ด เค. (1952) "รวบรวมกิจวัตรประจำวัน". การดำเนินการของการประชุมระดับชาติ ACM ปี 1952 (โตรอนโต) : 1-5. ดอย : 10.1145/800259.808980 . S2CID 14878552 . 
  15. ^ "ฟังก์ชันเรียกซ้ำของนิพจน์เชิงสัญลักษณ์และการคำนวณด้วยเครื่อง ", Communications of the ACM, เมษายน 1960
  16. แม็กคาร์ธี จอห์น; อับราฮัม, พอล ดับเบิลยู.; เอ็ดเวิร์ดส์, แดเนียล เจ.; ฮาร์ต, ทิโมธีพี.; เลวิน, ไมเคิล ไอ. (1965). คู่มือโปรแกรมเมอร์ Lisp 1.5 สำนักพิมพ์เอ็มไอที ISBN 9780262130110.
  17. ^ " BCPL: เครื่องมือสำหรับการเขียนคอมไพเลอร์และการเขียนโปรแกรมระบบ " M. Richards, University Mathematical Laboratory Cambridge, England 1969
  18. BCPL: The Language and Its Compiler, M Richards, Cambridge University Press (ตีพิมพ์ครั้งแรก 31 ธันวาคม 1981)
  19. ^ คู่มือผู้ใช้ BCPL Cintsys และ Cintpos, M. Richards, 2017
  20. ^ คอร์บาโต เอฟเจ; Vyssotsky, VA "บทนำและภาพรวมของระบบ MULTICS" . การประชุม คอมพิวเตอร์ร่วมฤดูใบไม้ร่วงปี 2508 Multicians.org
  21. รายงาน II ของ SHARE Advanced Language Development Committee, 25 มิถุนายน 2507
  22. ^ Multicians.org บทความ "ทางเลือกของ PL/I" บรรณาธิการ /tom Van Vleck
  23. ^ "PL/I As a Tool for System Programming", FJ Corbato, Datamation 6 พฤษภาคม 1969 ฉบับ
  24. ^ " The Multics PL/1 Compiler ", RA Freiburghouse, GE, Fall Joint Computer Conference 1969
  25. Dennis M. Ritchie, " The Development of the C Language ", ACM Second History of Programming Languages ​​Conference, เมษายน 1993
  26. ^ SC Johnson, "a Portable C Compiler: Theory and Practice", 5th ACM POPL Symposium, มกราคม 1978
  27. ^ A. Snyder, A Portable Compiler for the Language C , MIT, 1974.
  28. K. Nygaard, University of Oslo, Norway, " Basic Concepts in Object Oriented Programming ", SIGPLAN Notices V21, 1986
  29. ^ B. Stroustrup: "การเขียนโปรแกรมเชิงวัตถุคืออะไร" การประชุม ASU ครั้งที่ 14 ปี 2529
  30. ^ Bjarne Stroustrup, "ภาพรวมของภาษาการเขียนโปรแกรม C++", คู่มือเทคโนโลยีวัตถุ (บรรณาธิการ: Saba Zamir, ISBN 0-8493-3135-8 ) 
  31. ^ Leverett, Cattell, Hobbs, Newcomer, Reiner, Schatz, Wulf: "An Overview of the Production Quality Compiler-Compiler Project", CMU-CS-89-105, 1979
  32. ^ W. Wulf, K. Nori, " Delayed binding in PQCC created compilers ", CMU Research Showcase Report, CMU-CS-82-138, 1982
  33. Joseph M. Newcomer, David Alex Lamb, Bruce W. Leverett, Michael Tighe, William A. Wulf - Carnegie-Mellon University and David Levine, Andrew H. Reinerit - Intermetrics: "TCOL Ada: Revised Report on An Intermediate Representation for the DOD ภาษาโปรแกรมมาตรฐาน", 1979
  34. William A. Whitaker, "Ada - the project: the DoD High Order Working Group", ACM SIGPLAN Notices (Volume 28, No. 3, March 1991)
  35. ^ CECOM Center for Software Engineering Advanced Software Technology, "Final Report - Evaluation of ACEC Benchmark Suite for Real-Time Applications", AD-A231 968, 1990
  36. ^ P.Biggar, E. de Vries, D. Gregg, "A Practical Solution for Scripting Language Compilers", ยื่นเรื่อง Science of Computer Programming, 2009
  37. ^ M.Hall, D. Padua, K. Pingali, "Compiler Research: The Next 50 Years", ACM Communications 2009 Vol 54 #2
  38. ↑ Cooper and Torczon 2012, พี. 8
  39. ^ แลตต์เนอร์, คริส (2017). "LLVM" . ในบราวน์เอมี่; วิลสัน, เกร็ก (สหพันธ์). สถาปัตยกรรมของแอปพลิเค ชันโอเพ่นซอร์ส เก็บจากต้นฉบับเมื่อ 2 ธันวาคม 2559 . สืบค้นเมื่อ28 กุมภาพันธ์ 2017 .
  40. อาโห แลม, เศรษฐี, อุลมัน 2550, น. 5-6, 109-189
  41. อาโห แลม, เศรษฐี, อุลมัน 2550, น. 111
  42. อาโห แลม, เศรษฐี, อุลมัน 2550, น. 8, 191-300
  43. ↑ a b Blindell , Gabriel Hjort (3 มิถุนายน 2016). การเลือกคำสั่ง : หลักการ วิธีการ และการใช้งาน สวิตเซอร์แลนด์. ISBN 9783319340197. สธ . 951745657  .
  44. ^ Cooper and Toczon (2012), p. 540
  45. ^ "บทช่วยสอนการแปลภาษา" (PDF ) มหาวิทยาลัยวอชิงตัน .
  46. ไอค็อก, จอห์น (2003). "ประวัติโดยย่อของ Just-in-Time". เอซีเอ็ม คอมพิวเตอร์ เอาตัวรอด 35 (2 มิถุนายน): 93–113 ดอย : 10.1145/857076.857077 . S2CID 15345671 . 
  47. ^ Swartz จอร์แดนเอส.; เบตซ์, วอห์; โรส, โจนาธาน (22-25 กุมภาพันธ์ 2541) "เราเตอร์ที่ขับเคลื่อนด้วยการกำหนดเส้นทางที่รวดเร็วสำหรับ FPGA" (PDF ) FPGA '98 Proceedings of the 1998 ACM/SIGDA Sixth International Symposium on Field Programmable Gate Arrays มอนเทอร์เรย์ แคลิฟอร์เนีย: ACM : 140–149 ดอย : 10.1145/275107.275134 . ISBN  978-0897919784. S2CID  7128364 . เก็บถาวร (PDF)จากต้นฉบับเมื่อ 9 สิงหาคม 2017
  48. ^ พนักงาน Xilinx (2009) " ภาพ รวมการ สังเคราะห์ XST" Xilinx, Inc. เก็บถาวรจากต้นฉบับเมื่อวันที่ 2 พฤศจิกายน2559 สืบค้นเมื่อ28 กุมภาพันธ์ 2017 .
  49. ^ เจ้าหน้าที่ Altera (2017) "เครื่องยนต์ Spectra-Q™ " Altera.com เก็บถาวรจากต้นฉบับเมื่อ 10 ตุลาคม 2559 . สืบค้นเมื่อ28 กุมภาพันธ์ 2017 .

อ่านเพิ่มเติม

ลิงค์ภายนอก