ฉันจะสร้างภาษาการเขียนโปรแกรมของตัวเองและคอมไพเลอร์ได้อย่างไร [ปิด]


427

ฉันถี่ถ้วนกับการเขียนโปรแกรมและได้เจอภาษาต่างๆเช่นภาษาเบสิกภาษาฟอร์แทรนภาษาโคบอล LISP โลโก้ Java, C ++, C, MATLAB, Mathematica, Python, Ruby, Perl, JavaScript, Assembly เป็นต้น ฉันไม่เข้าใจว่าผู้คนสร้างภาษาการเขียนโปรแกรมและประดิษฐ์คอมไพเลอร์อย่างไร ฉันยังไม่เข้าใจว่าผู้คนสร้างระบบปฏิบัติการเช่น Windows, Mac, UNIX, DOS และอื่น ๆ อย่างไร สิ่งอื่น ๆ ที่ลึกลับสำหรับฉันคือวิธีที่ผู้คนสร้างห้องสมุดเช่น OpenGL, OpenCL, OpenCV, Cocoa, MFC และอื่น ๆ สิ่งสุดท้ายที่ฉันไม่สามารถเข้าใจได้ก็คือวิธีที่นักวิทยาศาสตร์คิดค้นภาษาแอสเซมบลีและแอสเซมเบลอร์สำหรับไมโครโปรเซสเซอร์ ฉันอยากจะเรียนรู้สิ่งเหล่านี้ทั้งหมดและฉันอายุ 15 ปี ฉันมักจะต้องการเป็นนักวิทยาศาสตร์คอมพิวเตอร์ที่ชอบ Babbage, Turing, Shannon หรือ Dennis Ritchie


ฉันได้อ่านหนังสือการออกแบบคอมไพเลอร์ของ Aho แล้วและแนวคิดระบบปฏิบัติการของ Tanenbaum และพวกเขาทั้งหมดพูดถึงแนวคิดและรหัสในระดับสูงเท่านั้น พวกเขาจะไม่เข้าไปในรายละเอียดและความแตกต่างและวิธีประดิษฐ์คอมไพเลอร์หรือระบบปฏิบัติการ ฉันต้องการความเข้าใจที่เป็นรูปธรรมเพื่อที่ฉันจะสามารถสร้างขึ้นเองได้และไม่ใช่เพียงความเข้าใจในสิ่งที่เป็นเธรดเซมาฟอร์กระบวนการหรือการวิเคราะห์คำ ฉันถามพี่ชายเกี่ยวกับสิ่งนี้ทั้งหมด เขาเป็นนักเรียน SB ใน EECS ที่ MIT และยังไม่ทราบว่าจะสร้างสิ่งเหล่านี้ได้อย่างไรในโลกแห่งความเป็นจริง สิ่งที่เขารู้ก็คือความเข้าใจเกี่ยวกับแนวคิดการออกแบบคอมไพเลอร์และระบบปฏิบัติการเช่นเดียวกับที่คุณได้กล่าวถึง (เช่นเธรดการซิงโครไนซ์การทำงานพร้อมกันการจัดการหน่วยความจำการวิเคราะห์คำศัพท์การสร้างรหัสระดับกลางเป็นต้น)


ถ้าคุณอยู่ใน Unix / Linux, คุณจะได้รับข้อมูลเกี่ยวกับเครื่องมือเฉพาะ: lex, และyacc bison
mouviciel

ข้อเสนอแนะแรกของฉันคืออ่านหนังสือมังกรโดย Aho amazon.com/Compilers-Principles-Techniques-Alfred-Aho/dp/…
Julian

1
อาจไม่เป็นประโยชน์เกินไป แต่ฉันแนะนำให้ดำเนินการผ่านsites.google.com/site/steveyegge2/blog-rants (บล็อกของ Steve Yegge) และ steve-yegge.blogspot.com/ (บล็อกอื่น ๆ ของ Steve Yegge)
KK

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

1
คำใบ้: ล่ามนั้นง่ายกว่าตัวแปลภาษา มันเป็นแค่คลาสที่ "ทำอะไรบางอย่าง" ตามข้อความอินพุตที่อ่านทีละบรรทัด คำแนะนำอื่น: ผูกสิ่งนี้กับภาพสะท้อนและคุณสามารถควบคุมวัตถุด้วยสคริปต์ของคุณเอง
Dave Cousineau

คำตอบ:


407

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

ที่กล่าวว่าฉันสามารถหยุดที่:

ฉันไม่เข้าใจว่าผู้คนสร้างภาษาการเขียนโปรแกรมและประดิษฐ์คอมไพเลอร์อย่างไร

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

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

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

หรือพิจารณาโดเมนที่คุณสนใจจากนั้นออกแบบภาษาเฉพาะโดเมน (DSL) ที่ระบุวิธีแก้ไขปัญหาในโดเมนนั้น คุณพูดถึงโลโก้ นี่เป็นตัวอย่างที่ดีของ DSL สำหรับโดเมน "การวาดเส้น" นิพจน์ทั่วไปเป็น DSL สำหรับโดเมน "ค้นหารูปแบบในสตริง" LINQ ใน C # / VB เป็น DSL สำหรับโดเมน "ตัวกรองการเข้าร่วมการเรียงลำดับและข้อมูลโครงการ" HTML เป็น DSL สำหรับโดเมน "อธิบายโครงร่างของข้อความในหน้า" และอื่น ๆ มีโดเมนจำนวนมากที่สามารถแก้ไขปัญหาที่ใช้ภาษาได้ หนึ่งในรายการโปรดของฉันคือ Inform7 ซึ่งเป็น DSL สำหรับโดเมน "เกมผจญภัยแบบข้อความ" มันอาจเป็นภาษาการเขียนโปรแกรมระดับสูงที่สุดที่ฉันเคยเห็น

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

  1. ศัพท์ : สิ่งที่เป็นกฎสำหรับคำในภาษาสิ่งที่ตัวละครที่ถูกกฎหมาย, ตัวเลขที่มีลักษณะอย่างไรและอื่น ๆ
  2. วากยสัมพันธ์ : คำศัพท์ภาษารวมเข้ากับหน่วยที่ใหญ่กว่าได้อย่างไร ในหน่วย C # ที่มีขนาดใหญ่กว่าจะมีสิ่งต่าง ๆ เช่นนิพจน์คำสั่งวิธีการคลาสและอื่น ๆ
  3. semantic : จากโปรแกรมด้านกฎหมาย syntactically คุณคิดได้อย่างไรว่าโปรแกรมทำอะไร

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

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

ฉันเขียนบล็อกเกี่ยวกับการออกแบบ C #, VB, VBScript, JavaScript และภาษาและเครื่องมืออื่น ๆ ถ้าเรื่องนี้คุณสนใจตรวจสอบออก http://blogs.msdn.com/ericlippert (historical) และhttp://ericlippert.com (ปัจจุบัน)

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

http://blogs.msdn.com/b/ericlippert/archive/2010/02/04/how-many-passes.aspx

ท้ายที่สุดถ้าคุณกำลังมองหางานทำสิ่งนี้เมื่อคุณอายุมากแล้วลองพิจารณา Microsoft เป็นนักศึกษาฝึกงานและพยายามเข้าทำงานในแผนกนักพัฒนา นั่นเป็นวิธีที่ฉันลงเอยกับงานของฉันในวันนี้!


คุณได้เขียนเกี่ยวกับการปรับแต่งคอมไพเลอร์ดีกรีดีกรีใดที่ไม่ได้ทำอีกต่อไปเนื่องจาก CLR สามารถทำได้โดยอัตโนมัติ?

6
@ Thorbjørn: ขอให้ชัดเจนเกี่ยวกับคำศัพท์ "คอมไพเลอร์" คืออุปกรณ์ใด ๆ ที่แปลจากภาษาโปรแกรมหนึ่งไปเป็นอีกภาษาหนึ่ง หนึ่งในสิ่งที่ดีเกี่ยวกับการมีคอมไพเลอร์ C # ที่เปลี่ยน C # เป็น IL และคอมไพเลอร์ IL ("jitter") ที่เปลี่ยน IL เป็นรหัสเครื่องก็คือคุณจะต้องเขียน C # คอมไพเลอร์เป็น IL (ง่าย!) และ ใส่การเพิ่มประสิทธิภาพเฉพาะโปรเซสเซอร์ในกระวนกระวายใจ ไม่ใช่ว่าการเพิ่มประสิทธิภาพของคอมไพเลอร์คือ "ไม่ได้ทำ" มันเป็นสิ่งที่ทีมคอมไพเลอร์ jit ทำเพื่อพวกเรา ดูblogs.msdn.com/b/ericlippert/archive/2009/06/11/…
Eric Lippert

6
@ Cyclotis04: Inform6 รวบรวม Z-code ซึ่งเป็นตัวอย่างที่มีชื่อเสียงมากในช่วงแรกของเครื่องเสมือนที่ใช้ bytecode นั่นคือวิธีที่เกม Infocom ทั้งหมดในช่วงปี 1980 อาจมีขนาดใหญ่กว่าหน่วยความจำและพกพาไปยังสถาปัตยกรรมที่หลากหลาย เกมดังกล่าวถูกคอมไพล์ด้วยรหัส z จากนั้นจึงใช้ตัวแปลรหัส z พร้อมเพจหน่วยความจำรหัสสำหรับเครื่องหลายเครื่อง ปัจจุบันของหลักสูตรที่คุณสามารถเรียกใช้ล่าม zcode บนนาฬิกาข้อมือถ้าคุณต้องการ แต่กลับมาในวันที่เป็นเทคโนโลยีชั้นสูง ดูen.wikipedia.org/wiki/Z-machineสำหรับรายละเอียด
Eric Lippert

@EricLippert คอมไพเลอร์ไม่ใช่อุปกรณ์อุปกรณ์เป็นสิ่งที่มีฮาร์ดแวร์เราสามารถพูดได้ว่าโปรแกรมที่กำหนดไว้ล่วงหน้าซึ่งมีชุดของกฎในการแปลงข้อมูลที่ป้อนเข้าสู่รหัสเครื่อง
dharam

2
@dhams: อุปกรณ์ใด ๆ ที่ทำขึ้นเพื่อวัตถุประสงค์เฉพาะ คอมไพเลอร์ทุกตัวที่ฉันเคยเขียนถูกเรียกใช้บนฮาร์ดแวร์ที่สร้างขึ้นโดยมีวัตถุประสงค์เพื่อให้คอมไพเลอร์มีอยู่
Eric Lippert

127

คุณอาจพบว่าLets Build a Compilerโดย Jack Crenshaw เป็นการแนะนำที่น่าสนใจเกี่ยวกับการเขียนคอมไพเลอร์และภาษาแอสเซมบลี

ผู้เขียนให้มันง่ายมากและเพ่งความสนใจไปที่การสร้างฟังก์ชั่นจริง


2
สิ่งที่น่าสนใจเกี่ยวกับคำนำของ Crenshaw ก็คือมันจะจบลง (สปอยเลอร์: มันไม่สมบูรณ์) เพียงแค่เวลาที่คุณพบเจอกับปัญหาที่จะทำให้คุณรู้ว่าเฮ้ฉันควรจะออกแบบภาษาของฉันให้สมบูรณ์ก่อนเริ่มใช้งาน แล้วคุณก็บอกว่าเฮ้ถ้าฉันต้องเขียนสเปคภาษาเต็มทำไมไม่ทำอย่างเป็นทางการในสัญกรณ์อย่างเป็นทางการที่ฉันสามารถป้อนลงในเครื่องมือเพื่อสร้างตัวแยกวิเคราะห์ได้? แล้วคุณทำมันเหมือนคนอื่น ๆ
ใจดี

3
@Kindall คุณต้องทำมันด้วยตัวเองเพื่อที่จะรู้ว่ามันมีเหตุผลที่จะใช้เครื่องมือ

72

"ฉันต้องการเรียนรู้สิ่งนี้จริงๆ " หากคุณจริงจังในระยะยาว:

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

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

  • รวบรวม / อ่านข้อความคอมไพเลอร์มาตรฐาน: Aho / Ullman ฯลฯ พวกเขามีสิ่งที่ชุมชนเห็นด้วยเป็นสิ่งพื้นฐาน คุณอาจไม่ได้ใช้ทุกอย่างจากหนังสือเหล่านั้น แต่คุณควรจะรู้ว่ามันมีอยู่แล้วและคุณควรรู้ว่าทำไมคุณไม่ใช้มัน ฉันคิดว่า Muchnick นั้นยอดเยี่ยม แต่มันก็เป็นหัวข้อขั้นสูง

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

  • จุดเริ่มต้นที่ดีจริงๆคือการเรียนรู้เกี่ยวกับ BNF (Backus Naur Form) ตัวแยกวิเคราะห์และตัวแยกวิเคราะห์ BNF ถูกนำไปใช้อย่างกว้างขวางในพื้นที่คอมไพเลอร์และคุณไม่สามารถพูดคุยกับเพื่อนของคุณได้หากคุณไม่รู้

หากคุณต้องการการแนะนำครั้งแรกที่ยอดเยี่ยมในการรวบรวมและค่าโดยตรงของ BNF ไม่ใช่เพียงแค่เอกสารประกอบ แต่เป็นเครื่องมือที่ประมวลผลได้เป็นโลหะให้ดูบทช่วยสอนนี้(ไม่ใช่ของฉัน) เกี่ยวกับการสร้างคอมไพเลอร์ "meta" บทความจาก2507 (ใช่คุณอ่านถูกต้อง) ["META II ภาษาเขียนคอมไพเลอร์เชิงไวยากรณ์" โดย Val Schorre (http://doi.acm.org/10.1145/800257.808896)] IMHO นี้เป็นหนึ่งในเอกสาร comp-sci ที่ดีที่สุดหนึ่งเดียวที่เคยเขียน: มันสอนให้คุณสร้างคอมไพเลอร์คอมไพเลอร์ใน 10 หน้า ตอนแรกฉันเรียนรู้จากเอกสารนี้

สิ่งที่ฉันเขียนเกี่ยวกับข้างต้นมาจากประสบการณ์ส่วนตัวมากมายและฉันคิดว่ามันให้บริการฉันค่อนข้างดี YMMV แต่ IMHO ไม่มาก


54
-1 ไม่จำเป็นทั้งหมด
Neil Butterworth

77
@nbt ไม่จำเป็นต้องมีข้อใดข้อหนึ่งข้างต้น แต่ทั้งหมดข้างต้นช่วยได้ มากจริงๆ
Konrad Rudolph

1
ฉันไม่เห็นด้วยอย่างยิ่งกับ "เรียนรู้คณิตศาสตร์ให้คิดอย่างเป็นนามธรรม!" ข้อเสนอแนะ แม้ว่าคุณคิดว่า "การเรียนรู้ที่จะคิดอย่างเป็นนามธรรม" มีประโยชน์อย่างยิ่งในการสร้างภาษาโปรแกรมและคอมไพเลอร์ของคุณเอง (ฉันไม่ - ฉันคิดว่ามันมีประโยชน์มากกว่าที่จะเรียนรู้ด้วยการทำมากกว่าการใช้อ้อมอ้อมเหล่านี้ คณิตศาสตร์ไม่ใช่สนามเดียวที่มีความคิดเชิงนามธรรม! (ฉันนักคณิตศาสตร์ครับดังนั้นผมไม่ได้ปฏิเสธการใช้คณิตศาสตร์ทั่วไปเพียงแค่การบังคับใช้ในกรณีนี้โดยเฉพาะอย่างยิ่ง ... )
grautur

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

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

46

นี่คือหนังสือออนไลน์ / แน่นอนว่าคุณสามารถทำตามที่เรียกว่าองค์ประกอบของระบบคอมพิวเตอร์: การสร้างคอมพิวเตอร์ที่ทันสมัยจากหลักการแรก

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

บทที่:

  1. ภาพรวมของหลักสูตร
  2. บูลีนลอจิก
  3. ชิป Combinatorial
  4. ชิปเรียงลำดับ
  5. ภาษาเครื่อง
  6. สถาปัตยกรรมคอมพิวเตอร์
  7. ผู้ประกอบ
  8. เครื่องเสมือนฉัน: เลขคณิต
  9. เครื่องเสมือน II: การควบคุม
  10. ภาษาโปรแกรม
  11. คอมไพเลอร์ I: การวิเคราะห์ไวยากรณ์
  12. Compiler II: การสร้างรหัส
  13. ระบบปฏิบัติการ
  14. รายการสินค้า

สนุกกว่าเดิม


ขอบคุณสำหรับการแก้ไขคนที่ไม่รู้จัก ฉันลองสองสามครั้ง แต่ไม่สามารถรับความคิดของฉันจดจ่อเพียงพอสำหรับคำอธิบาย ... แต่ไม่ต้องการพูดถึงหนังสือเล่มนี้ หนังสือเล่มนี้เป็นออนไลน์ขณะที่แผนเชื่อมโยงการศึกษา: www1.idc.ac.il/tecs/plan.html นอกจากนี้ยังมีราคาออนไลน์ที่สมเหตุสมผล สนุกกับทุกคน
Joe Internet

ฉันจะแนะนำตัวเองนี้ ... สำหรับคนขี้เกียจลองดูคำแนะนำ 10 นาที: จาก NAND ถึง Tetris ใน 12 ขั้นตอน @ youtube.com/watch?v=JtXvUoPx4Qs
Richard Anthony Hein

46

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

ภาษาไม่จำเป็นต้องเป็นภาษาการเขียนโปรแกรม พวกเขาสามารถเป็นภาษาใด ๆที่สามารถเขียนกฎลงไปได้ คุณอาจจะเคยเห็นGoogle Translate ; นั่นเป็นคอมไพเลอร์เพราะมันสามารถแปลภาษาหนึ่ง (พูดเยอรมัน) เป็นอีกภาษาหนึ่ง (ญี่ปุ่นหรือบางที)

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

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

คุณสามารถเขียนโปรแกรมที่กลับคำทุกคำในสตริงได้หรือไม่? ตัวอย่างเช่น:

When the cat's away, the mice will play.

กลายเป็น

nehW eht s'tac yawa, eht ecim lliw yalp.

นั่นไม่ใช่โปรแกรมที่ยากต่อการเขียน แต่คุณต้องคิดถึงบางสิ่ง:

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

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

คุณสามารถเขียนโปรแกรมที่ใช้ชุดคำสั่งการวาดและส่งออกไฟล์ PNG (หรือ JPEG) ได้หรือไม่? อาจจะเป็นสิ่งนี้:

image 100 100
background black
color red
line 20 55 93 105
color green
box 0 0 99 99

คุณต้องคิดอีกครั้งเพื่อกำหนดภาษา:

  • คำแนะนำดั้งเดิมคืออะไร?
  • หลังจากคำว่า "บรรทัด" คืออะไร สิ่งที่เกิดขึ้นหลังจาก "สี"? เช่นเดียวกันกับ "พื้นหลัง", "กล่อง" ฯลฯ
  • ตัวเลขคืออะไร
  • อนุญาตให้ป้อนไฟล์เปล่าหรือไม่
  • ตกลงหรือไม่ที่จะใช้อักษรตัวพิมพ์ใหญ่คำ?
  • อนุญาตให้ใช้จำนวนลบได้หรือไม่
  • จะเกิดอะไรขึ้นหากคุณไม่ให้คำสั่ง "ภาพ"
  • ตกลงเพื่อไม่ระบุสีหรือไม่?

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

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


7
myFirstCompiler = (str) -> ("" + (str || "")). split (''). reverse (). join (''); jsfiddle.net/L7qSr
Larry Battle

21

หากคุณสนใจในการออกแบบคอมไพเลอร์ลองดูDragon Book (ชื่ออย่างเป็นทางการ: คอมไพเลอร์: หลักการเทคนิคและเครื่องมือ) มันได้รับการยกย่องอย่างกว้างขวางว่าเป็นหนังสือคลาสสิกในหัวข้อนี้


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

13
-1 มีเพียงคนที่ไม่ได้อ่านเท่านั้นที่คิดว่าหนังสือมังกรนั้นดี และโดยเฉพาะอย่างยิ่งมันไม่ได้ตอบคำถาม
Neil Butterworth

33
หนังสือมังกร สำหรับคนที่กระตือรือร้นอายุสิบห้าปี? ฉันอยากให้เขารักษาความกระตือรือร้นของเขาสักครู่
David Thornley

1
ทางเลือกที่เข้าถึงได้มากขึ้น: 'การเขียนโปรแกรมภาษาเน้น' 3e
willjcroz

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

10

"มาสร้างคอมไพเลอร์กันเถอะ" แนะนำแล้ว มีเวอร์ชั่น "ทันสมัย" โดยใช้ Haskell แทนที่จะเป็น Turbo Pascal: http://alephnullplex.appspot.com/blog/view/2010/01/12/lbach-1-introduction

การรักษาด้วย Haskell มีล่าม Scheme ที่ให้คำแนะนำซึ่งสามารถให้ความคิดเพิ่มเติม: เขียนโครงการด้วยตัวเองใน 48 ชั่วโมง


10

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

ทุกโปรแกรมมีสามขั้นตอน:

  1. อ่านบางสิ่ง
  2. ประมวลผลข้อมูล: แปลข้อมูลอินพุตเป็นข้อมูลเอาต์พุต
  3. เขียนข้อมูลอื่น - ข้อมูลขาออก

ลองคิดดูสิ: อะไรคืออินพุตของคอมไพเลอร์? สตริงอักขระจากไฟล์ต้นฉบับ

ผลลัพธ์จากคอมไพเลอร์คืออะไร? สตริงของไบต์ที่แสดงคำสั่งเครื่องกับคอมพิวเตอร์เป้าหมาย

ดังนั้นขั้นตอน "กระบวนการ" ของคอมไพเลอร์คืออะไร? เฟสนั้นทำอะไร

หากคุณพิจารณาว่าคอมไพเลอร์ - เหมือนโปรแกรมอื่น ๆ - มีการรวมเหล่านี้ขั้นตอนที่สามคุณจะมีความคิดที่ดีของวิธีการคอมไพเลอร์จะถูกสร้าง


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

1
@Mason Wheeler: ฉันคิดว่าใครก็ตามที่ต้องการเขียนคอมไพเลอร์ (และออกแบบภาษาเป้าหมาย?) น่าจะคิดว่าไวยากรณ์แบบเรียกซ้ำและตารางสัญลักษณ์เป็นแนวคิดพื้นฐานที่ค่อนข้างสวย
FumbleFingers

8

ฉันไม่ใช่ผู้เชี่ยวชาญ แต่นี่คือแทงของฉัน:

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

การขโมยคำตอบของคนอื่นจาก SO ( https://stackoverflow.com/questions/3826692/how-do-i-translate-assembly-to-binary ) ชุดประกอบมีลักษณะดังนี้:

label:  LDA #$00
        JMP label

จากนั้นคุณเรียกใช้มันผ่านแอสเซมเบลอร์และเปลี่ยนเป็นสิ่งนี้:

$A9 $00
$4C $10 $00

มีเพียงทุกอย่างที่ถูกบีบอัดเช่นนี้:

$A9 $00 $4C $10 $00

มันไม่ได้วิเศษจริงๆ

คุณไม่สามารถเขียนใน notepad ได้เนื่องจาก notepad ใช้ ASCII (ไม่ใช่ hex) คุณจะใช้โปรแกรมแก้ไขฐานสิบหกหรือเขียนไบต์ออกทางโปรแกรม คุณเขียนเลขฐานสิบหกนั้นลงในไฟล์ตั้งชื่อมันว่า "a.exe" หรือ "a.out" จากนั้นบอกให้ระบบปฏิบัติการรัน

แน่นอนว่าซีพียูและระบบปฏิบัติการที่ทันสมัยมีความซับซ้อนจริงๆ แต่นั่นเป็นแนวคิดพื้นฐาน

หากคุณต้องการเขียนคอมไพเลอร์ใหม่นี่คือวิธีที่มันทำ:

1) เขียนภาษาที่ตีความโดยใช้บางอย่างเช่นเครื่องคิดเลขใน pyparsing (หรือกรอบการแยกวิเคราะห์ที่ดีอื่น ๆ ) ที่จะทำให้คุณได้รับความเร็วในพื้นฐานของการแยกวิเคราะห์

2) เขียนนักแปล แปลภาษาของคุณให้เป็นภาษาจาวาสคริปต์ ตอนนี้ภาษาของคุณจะทำงานในเบราว์เซอร์

3) เขียนนักแปลไปยังระดับที่ต่ำกว่าเช่น LLVM, C หรือ Assembly

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

4) (บ้า) เขียนเครื่องมือเพิ่มประสิทธิภาพ ทีมขนาดใหญ่ทำงานมานานหลายทศวรรษในเรื่องนี้

4) (มีสติ) มีส่วนร่วมในชุมชนที่มีอยู่ GCC, LLVM, PyPy, ทีมงานหลักที่ทำงานเกี่ยวกับล่าม


8

หลายคนได้รับคำตอบที่ยอดเยี่ยม ฉันจะเพิ่มข้อเสนอแนะอีกสองสามข้อ อันดับแรกหนังสือที่ดีสำหรับสิ่งที่คุณพยายามทำคือตำราการใช้งานคอมไพเลอร์สมัยใหม่ของ Appel (เลือกC , JavaหรือStandard ML ) หนังสือเล่มนี้จะนำคุณไปสู่การใช้งานคอมไพเลอร์อย่างสมบูรณ์สำหรับภาษาอย่าง Tiger, ไปสู่ ​​MIPS แอสเซมบลีที่สามารถเรียกใช้ในอีมูเลเตอร์พร้อมกับไลบรารีสนับสนุนรันไทม์น้อยที่สุด สำหรับบัตรเดียวผ่านทุกอย่างที่จำเป็นเพื่อให้การทำงานเป็นภาษารวบรวมมันเป็นหนังสือที่ดีงาม1

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

ในที่สุดฉันพูดถึงว่า Appel มีข้อความของเขาใน C, Java และ Standard ML - หากคุณจริงจังกับการสร้างคอมไพเลอร์และภาษาการเขียนโปรแกรมฉันแนะนำให้เรียนรู้ ML และใช้ Appel เวอร์ชันนั้น ภาษาตระกูล ML มีระบบการพิมพ์ที่แข็งแกร่งมีคุณสมบัติการใช้งานที่โดดเด่น - คุณสมบัติที่แตกต่างจากภาษาอื่น ๆ มากมายดังนั้นการเรียนรู้พวกเขาหากคุณไม่ทราบว่าภาษาที่ใช้งานได้จะทำให้ทักษะการใช้ภาษาของคุณเป็นจริง นอกจากนี้การจับคู่รูปแบบและความตั้งใจในการใช้งานของพวกเขานั้นเหมาะสมอย่างยิ่งกับประเภทของกิจวัตรที่คุณต้องทำบ่อยครั้งในคอมไพเลอร์ดังนั้นคอมไพเลอร์ที่เขียนด้วยภาษา ML จะสั้นและเข้าใจง่ายกว่าคอมไพเลอร์ที่เขียนใน C Java หรือภาษาที่คล้ายกัน หนังสือของฮาร์เปอร์ใน Standard ML เป็นแนวทางที่ดีในการเริ่มต้นใช้งาน การทำงานที่ควรเตรียมคุณให้พร้อมในการดำเนินการตามหนังสือรวบรวม ML ของ Appel ถ้าคุณเรียนรู้ Standard ML ก็จะง่ายต่อการรับ OCaml สำหรับการทำงานในภายหลัง IMO มีเครื่องมือที่ดีกว่าสำหรับโปรแกรมเมอร์ที่ทำงานอยู่ (รวมเข้ากับสภาพแวดล้อมระบบปฏิบัติการโดยรอบได้ดีขึ้นสร้างโปรแกรมที่ปฏิบัติการได้ง่ายและมีเครื่องมือสร้างคอมไพเลอร์ที่น่าทึ่งเช่น ulex และ Menhir)


1สำหรับการอ้างอิงระยะยาวฉันชอบ Dragon Book เนื่องจากมีรายละเอียดเพิ่มเติมเกี่ยวกับสิ่งที่ฉันน่าจะอ้างถึงเช่นการทำงานภายในของอัลกอริธึม parser และมีการครอบคลุมวิธีการต่าง ๆ ที่กว้างขึ้น สำหรับการผ่านครั้งแรก โดยพื้นฐานแล้ว Appel สอนวิธีหนึ่งให้คุณทำสิ่งต่าง ๆ ผ่านทางคอมไพเลอร์และแนะนำคุณผ่านมัน The Dragon Book ครอบคลุมทางเลือกการออกแบบที่แตกต่างกันอย่างละเอียด แต่ให้คำแนะนำน้อยลงเกี่ยวกับวิธีการทำงานบางอย่าง


แก้ไข : แทนที่การอ้างอิง Aho ที่ไม่ถูกต้องด้วย Sethi พูดถึง CTMCP


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

ฉันชอบการรวบรวมของ Appel กับการต่อเนื่อง แต่ฉันพบว่าหนังสือของเขาถือว่ามีความรู้มาก่อน
Jon Harrop

6

ฉันต้องสร้างคอมไพเลอร์สำหรับชั้นเรียนในวิทยาลัย

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

เมื่อคุณมีไวยากรณ์ลงไป (กฎของภาษาของคุณ) การเขียนคอมไพเลอร์นั้นง่ายพอ ๆ กับการทำตามกฎเหล่านั้น คอมไพเลอร์มักแปลเป็นรหัสเครื่อง แต่ถ้าคุณไม่ต้องการเรียนรู้ x86 ฉันขอแนะนำให้คุณดูที่ MIPS หรือสร้าง Virtual Machine ของคุณเอง

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

โชคดี!


8
แนวคิดง่ายหรือไม่ ใช่. ง่ายจริงเหรอ? ไม่
นีลบัตเตอร์เวิร์ ธ

7
อืม คอมไพเลอร์หลังจากการสแกน / การแยกวิเคราะห์จำเป็นต้องทำการตรวจสอบประเภท / การอนุมานการเพิ่มประสิทธิภาพการจัดสรรการลงทะเบียน ฯลฯ ฯลฯ ขั้นตอนเหล่านี้เป็นอะไรที่ง่าย (เมื่อใช้โค้ดที่แปลแล้วคุณเพียงแค่เลื่อนชิ้นส่วนเหล่านี้ไปยังระยะรันไทม์)
Macke

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

6

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

ตอนนี้ฉันได้เขียนสิ่งนี้ฉันจะต้องอ่านใหม่อีกครั้ง


5

คุณอาจต้องการตรวจสอบคำถามนี้ดีมาก (และคำตอบ) ใน StackOverflow: เรียนรู้การเขียนคอมไพเลอร์ มันมีรายการทรัพยากรมากมาย


5

มีคำตอบที่ยอดเยี่ยมในชุดข้อความนี้ แต่ฉันแค่ต้องการเพิ่มของฉันเพราะฉันเคยมีคำถามเดียวกัน (นอกจากนี้ฉันอยากจะชี้ให้เห็นว่าหนังสือที่โจ - อินเทอร์เน็ตแนะนำนั้นเป็นทรัพยากรที่ยอดเยี่ยม)

คำถามแรกคือคอมพิวเตอร์ทำงานอย่างไร? นี่คือวิธี: อินพุต -> คำนวณ -> เอาท์พุท

ก่อนอื่นให้พิจารณาส่วน "คำนวณ" เราจะดูว่าอินพุตและเอาต์พุตทำงานอย่างไรในภายหลัง

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

ในการตอบคำถามนี้เราจำเป็นต้องเข้าใจโครงสร้างของโปรเซสเซอร์ ต่อไปนี้เป็นมุมมองที่ค่อนข้างง่าย หน่วยประมวลผลกลางประกอบด้วยสองส่วน หนึ่งคือชุดของตำแหน่งหน่วยความจำที่อยู่ภายในโปรเซสเซอร์ซึ่งทำหน้าที่เป็นหน่วยความจำที่ใช้งานได้ สิ่งเหล่านี้เรียกว่า“ การลงทะเบียน” ที่สองคือกลุ่มของเครื่องจักรอิเล็กทรอนิกส์ที่สร้างขึ้นเพื่อดำเนินการบางอย่างโดยใช้ข้อมูลในการลงทะเบียนมีสองทะเบียนพิเศษที่เรียกว่า "โปรแกรมเคาน์เตอร์" หรือพีซีและ "คำแนะนำการลงทะเบียน" หรือ IR โปรเซสเซอร์พิจารณาหน่วยความจำที่จะแบ่งพาร์ติชันเป็นสามส่วน ส่วนแรกคือ "หน่วยความจำโปรแกรม" ซึ่งเก็บโปรแกรมคอมพิวเตอร์ที่กำลังทำงาน ประการที่สองคือ "หน่วยความจำข้อมูล" ที่สามใช้สำหรับวัตถุประสงค์พิเศษเราจะพูดถึงมันในภายหลัง ตัวนับโปรแกรมประกอบด้วยตำแหน่งของคำสั่งถัดไปที่จะอ่านจากหน่วยความจำโปรแกรม The Instruction Counter มีหมายเลขที่อ้างถึงการปฏิบัติการปัจจุบันที่กำลังดำเนินการอยู่ การดำเนินการแต่ละครั้งที่โปรเซสเซอร์สามารถดำเนินการได้ถูกอ้างถึงโดยหมายเลขที่เรียกว่า opcode ของการดำเนินการ การทำงานของคอมพิวเตอร์เป็นหลักคือการอ่านตำแหน่งหน่วยความจำที่อ้างอิงโดยตัวนับโปรแกรมไปยัง Instruction Register (และจะเพิ่มตัวนับ Program เพื่อให้ชี้ไปยังตำแหน่งหน่วยความจำของคำสั่งถัดไป) ถัดไปจะอ่านคำแนะนำในการลงทะเบียนและดำเนินการตามที่ต้องการ ตัวอย่างเช่นคำสั่งอาจจะอ่านตำแหน่งหน่วยความจำที่เฉพาะเจาะจงลงในทะเบียนหรือเพื่อเขียนลงทะเบียนหรือดำเนินการบางอย่างโดยใช้ค่าของรีจิสเตอร์สองตัวและเขียนเอาต์พุตไปยังรีจิสเตอร์ที่สาม The Instruction Counter มีหมายเลขที่อ้างถึงการปฏิบัติการปัจจุบันที่กำลังดำเนินการอยู่ การดำเนินการแต่ละครั้งที่โปรเซสเซอร์สามารถดำเนินการได้ถูกอ้างถึงโดยหมายเลขที่เรียกว่า opcode ของการดำเนินการ การทำงานของคอมพิวเตอร์เป็นหลักคือการอ่านตำแหน่งหน่วยความจำที่อ้างอิงโดยตัวนับโปรแกรมไปยัง Instruction Register (และจะเพิ่มตัวนับ Program เพื่อให้ชี้ไปยังตำแหน่งหน่วยความจำของคำสั่งถัดไป) ถัดไปจะอ่านคำแนะนำในการลงทะเบียนและดำเนินการตามที่ต้องการ ตัวอย่างเช่นคำสั่งอาจจะอ่านตำแหน่งหน่วยความจำที่เฉพาะเจาะจงลงในทะเบียนหรือเพื่อเขียนลงทะเบียนหรือดำเนินการบางอย่างโดยใช้ค่าของรีจิสเตอร์สองตัวและเขียนเอาต์พุตไปยังรีจิสเตอร์ที่สาม The Instruction Counter มีหมายเลขที่อ้างถึงการปฏิบัติการปัจจุบันที่กำลังดำเนินการอยู่ การดำเนินการแต่ละครั้งที่โปรเซสเซอร์สามารถดำเนินการได้ถูกอ้างถึงโดยหมายเลขที่เรียกว่า opcode ของการดำเนินการ การทำงานของคอมพิวเตอร์เป็นหลักคือการอ่านตำแหน่งหน่วยความจำที่อ้างอิงโดยตัวนับโปรแกรมไปยัง Instruction Register (และจะเพิ่มตัวนับ Program เพื่อให้ชี้ไปยังตำแหน่งหน่วยความจำของคำสั่งถัดไป) ถัดไปจะอ่านคำแนะนำในการลงทะเบียนและดำเนินการตามที่ต้องการ ตัวอย่างเช่นคำสั่งอาจจะอ่านตำแหน่งหน่วยความจำที่เฉพาะเจาะจงลงในทะเบียนหรือเพื่อเขียนลงทะเบียนหรือดำเนินการบางอย่างโดยใช้ค่าของรีจิสเตอร์สองตัวและเขียนเอาต์พุตไปยังรีจิสเตอร์ที่สาม การดำเนินการแต่ละครั้งที่โปรเซสเซอร์สามารถดำเนินการได้ถูกอ้างถึงโดยหมายเลขที่เรียกว่า opcode ของการดำเนินการ การทำงานของคอมพิวเตอร์เป็นหลักคือการอ่านตำแหน่งหน่วยความจำที่อ้างอิงโดยตัวนับโปรแกรมไปยัง Instruction Register (และจะเพิ่มตัวนับ Program เพื่อให้ชี้ไปยังตำแหน่งหน่วยความจำของคำสั่งถัดไป) ถัดไปจะอ่านคำแนะนำในการลงทะเบียนและดำเนินการตามที่ต้องการ ตัวอย่างเช่นคำสั่งอาจจะอ่านตำแหน่งหน่วยความจำที่เฉพาะเจาะจงลงในทะเบียนหรือเพื่อเขียนลงทะเบียนหรือดำเนินการบางอย่างโดยใช้ค่าของรีจิสเตอร์สองตัวและเขียนเอาต์พุตไปยังรีจิสเตอร์ที่สาม การดำเนินการแต่ละครั้งที่โปรเซสเซอร์สามารถดำเนินการได้ถูกอ้างถึงโดยหมายเลขที่เรียกว่า opcode ของการดำเนินการ การทำงานของคอมพิวเตอร์เป็นหลักคือการอ่านตำแหน่งหน่วยความจำที่อ้างอิงโดยตัวนับโปรแกรมไปยัง Instruction Register (และจะเพิ่มตัวนับ Program เพื่อให้ชี้ไปยังตำแหน่งหน่วยความจำของคำสั่งถัดไป) ถัดไปจะอ่านคำแนะนำในการลงทะเบียนและดำเนินการตามที่ต้องการ ตัวอย่างเช่นคำสั่งอาจจะอ่านตำแหน่งหน่วยความจำที่เฉพาะเจาะจงลงในทะเบียนหรือเพื่อเขียนลงทะเบียนหรือดำเนินการบางอย่างโดยใช้ค่าของรีจิสเตอร์สองตัวและเขียนเอาต์พุตไปยังรีจิสเตอร์ที่สาม การทำงานของคอมพิวเตอร์เป็นหลักคือการอ่านตำแหน่งหน่วยความจำที่อ้างอิงโดยตัวนับโปรแกรมไปยัง Instruction Register (และจะเพิ่มตัวนับ Program เพื่อให้ชี้ไปยังตำแหน่งหน่วยความจำของคำสั่งถัดไป) ถัดไปจะอ่านคำแนะนำในการลงทะเบียนและดำเนินการตามที่ต้องการ ตัวอย่างเช่นคำสั่งอาจจะอ่านตำแหน่งหน่วยความจำที่เฉพาะเจาะจงลงในทะเบียนหรือเพื่อเขียนลงทะเบียนหรือดำเนินการบางอย่างโดยใช้ค่าของรีจิสเตอร์สองตัวและเขียนเอาต์พุตไปยังรีจิสเตอร์ที่สาม การทำงานของคอมพิวเตอร์เป็นหลักคือการอ่านตำแหน่งหน่วยความจำที่อ้างอิงโดยตัวนับโปรแกรมไปยัง Instruction Register (และจะเพิ่มตัวนับ Program เพื่อให้ชี้ไปยังตำแหน่งหน่วยความจำของคำสั่งถัดไป) ถัดไปจะอ่านคำแนะนำในการลงทะเบียนและดำเนินการตามที่ต้องการ ตัวอย่างเช่นคำสั่งอาจจะอ่านตำแหน่งหน่วยความจำที่เฉพาะเจาะจงลงในทะเบียนหรือเพื่อเขียนลงทะเบียนหรือดำเนินการบางอย่างโดยใช้ค่าของรีจิสเตอร์สองตัวและเขียนเอาต์พุตไปยังรีจิสเตอร์ที่สาม

ตอนนี้คอมพิวเตอร์ทำงานอย่างไร Input / Output? ฉันจะให้คำตอบที่ง่ายมาก ดูhttp://en.wikipedia.org/wiki/Input/outputและhttp://en.wikipedia.org/wiki/Interrupt. มากขึ้น มันใช้สองสิ่งนั่นคือส่วนที่สามของหน่วยความจำและสิ่งที่เรียกว่าขัดจังหวะ อุปกรณ์ทุกชิ้นที่เชื่อมต่อกับคอมพิวเตอร์จะต้องสามารถแลกเปลี่ยนข้อมูลกับโปรเซสเซอร์ได้ มันใช้ส่วนที่สามของหน่วยความจำที่กล่าวถึงข้างต้น ตัวประมวลผลจะจัดสรรหน่วยความจำให้กับแต่ละอุปกรณ์และอุปกรณ์และตัวประมวลผลสื่อสารผ่านหน่วยความจำชิ้นนั้น แต่ตัวประมวลผลทราบตำแหน่งใดที่อ้างถึงอุปกรณ์ใดและอุปกรณ์ต้องการแลกเปลี่ยนข้อมูลเมื่อใด นี่คือที่ที่อินเทอร์รัปต์เข้ามาอินเทอร์รัปต์เป็นสัญญาณที่ส่งไปยังโปรเซสเซอร์เพื่อหยุดสิ่งที่มันกำลังทำอยู่และบันทึกทั้งหมดที่ลงทะเบียนไปยังตำแหน่งที่ทราบแล้วเริ่มทำอย่างอื่น มีการขัดจังหวะจำนวนมากแต่ละรายการจะถูกระบุด้วยหมายเลขเฉพาะ สำหรับการขัดจังหวะแต่ละครั้งจะมีโปรแกรมพิเศษที่เกี่ยวข้อง เมื่อมีการขัดจังหวะ โปรเซสเซอร์ดำเนินการโปรแกรมที่สอดคล้องกับการขัดจังหวะ ตอนนี้ขึ้นอยู่กับประวัติและวิธีการที่อุปกรณ์ฮาร์ดแวร์เชื่อมต่อกับเมนบอร์ดคอมพิวเตอร์ทุกอุปกรณ์ได้รับการขัดจังหวะที่ไม่ซ้ำกันและหน่วยความจำชิ้น ในขณะที่การบูทระบบปฏิบัติการด้วยความช่วยเหลือของไบออสจะกำหนดตำแหน่งอินเตอร์รัปต์และหน่วยความจำของอุปกรณ์แต่ละตัวและตั้งค่าโปรแกรมพิเศษสำหรับอินเทอร์รัปต์เพื่อจัดการอุปกรณ์อย่างเหมาะสม ดังนั้นเมื่ออุปกรณ์ต้องการข้อมูลบางอย่างหรือต้องการส่งข้อมูลบางอย่างมันจะส่งสัญญาณขัดจังหวะ โปรเซสเซอร์หยุดการทำงานชั่วคราวจัดการกับการขัดจังหวะแล้วกลับไปที่สิ่งที่กำลังทำอยู่ มีอินเทอร์รัปต์หลายชนิดเช่นสำหรับ hdd คีย์บอร์ด ฯลฯ สิ่งสำคัญอย่างหนึ่งคือตัวจับเวลาระบบซึ่งจะเรียกอินเทอร์รัปต์ตามช่วงเวลาปกติ นอกจากนี้ยังมี opcodes ที่สามารถเรียกการขัดจังหวะที่เรียกว่าการขัดจังหวะซอฟต์แวร์

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

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

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

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

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

ดังนั้นในการเขียนระบบปฏิบัติการคุณต้องเขียน“ boot-loader” จากนั้นคุณต้องเขียนรหัสเพื่อจัดการกับอินเตอร์รัปต์และอุปกรณ์ จากนั้นคุณต้องเขียนรหัสทั้งหมดสำหรับการจัดการกระบวนการการจัดการอุปกรณ์ ฯลฯ จากนั้นคุณต้องเขียน api ซึ่งทำให้โปรแกรมที่ทำงานอยู่ในระบบปฏิบัติการของคุณเข้าถึงอุปกรณ์และทรัพยากรอื่น ๆ และในที่สุดคุณต้องเขียนโค้ดที่อ่านโปรแกรมจากดิสก์ตั้งค่าเป็นกระบวนการและเริ่มดำเนินการ

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


4

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

สิ่งที่ผูกมันเข้าด้วยกันก็คือการหาโครงการที่เป็นรูปธรรมที่จะทำ (จากนั้นก็พบว่าฉันต้องการเพียงเซตย่อยเล็ก ๆ ของทฤษฎีทั้งหมด)

Java VM ให้จุดเริ่มต้นที่ดีแก่ฉัน: เป็นแนวคิด "ตัวประมวลผล" แต่มันถูกแยกออกจากรายละเอียดที่ยุ่งเหยิงของ CPU จริง นอกจากนี้ยังเป็นส่วนสำคัญและมักจะมองข้ามกระบวนการเรียนรู้: แยกสิ่งต่าง ๆ ออกจากกันก่อนที่จะรวมเข้าด้วยกันอีกครั้ง (เช่นเด็กที่เคยทำกับวิทยุในสมัยก่อน)

เล่นกับเครื่องถอดรหัสและ Hello, World class ใน Java อ่านข้อมูลจำเพาะ JVM แล้วลองเข้าใจว่าเกิดอะไรขึ้น สิ่งนี้จะทำให้คุณเข้าใจอย่างถ่องแท้ว่าคอมไพเลอร์กำลังทำอะไรอยู่

จากนั้นเล่นด้วยรหัสที่สร้าง Hello, World class (เนื่องจากคุณกำลังสร้างคอมไพเลอร์เฉพาะแอปพลิเคชันสำหรับภาษาที่มีความเชี่ยวชาญสูงซึ่งคุณสามารถพูดได้ว่า Hello, World)

ลองเขียนโค้ดที่จะสามารถอ่านได้ใน Hello, World ที่เขียนในภาษาอื่นและส่งออกคลาสเดียวกัน ทำให้เป็นอย่างนั้นคุณสามารถเปลี่ยนสตริงจาก "Hello, World" เป็นอย่างอื่น

ตอนนี้ให้ลองคอมไพล์ (ใน Java) คลาสที่คำนวณนิพจน์ทางคณิตศาสตร์เช่น "2 * (3 + 4)" แยกคลาสนี้ออกจากกันเขียน "ของเล่นคอมไพเลอร์" ที่สามารถรวมเข้าด้วยกันอีกครั้ง


3

1) วิดีโอการบรรยายที่ยอดเยี่ยมจาก University of Washington:

CSE P 501 คอมไพเลอร์ก่อสร้าง - ฤดูใบไม้ร่วง 2009 www.cs.washington.edu/education/courses/csep501/09au/lectures/video.html *

2) SICP http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/ และหนังสือที่มีชื่อเดียวกัน นี่เป็นข้อบังคับสำหรับวิศวกรซอฟต์แวร์ใด ๆ

3) นอกจากนี้เกี่ยวกับการเขียนโปรแกรมการทำงาน Haskell, แลมบ์ดาแคลคูลัสความหมาย (รวมถึง denotational) และการใช้งานคอมไพเลอร์สำหรับภาษาการทำงาน คุณสามารถเริ่มต้นจาก 2005-SS-FP.V10.2005-05-24.HDV หากคุณรู้จัก Haskell แล้ว วิดีโอUxxเป็นคำตอบ โปรดติดตามวิดีโอVxxก่อน

http://video.s-inf.de/#FP.2005-SS-Giesl.(COt).HD_Videoaufzeichnung

(วิดีโอเป็นภาษาอังกฤษหลักสูตรอื่น ๆ เป็นภาษาเยอรมัน)

  • ผู้ใช้ใหม่สามารถโพสต์ลิงค์ได้สูงสุดสองลิงค์

3

ANTLRเป็นจุดเริ่มต้นที่ดี มันเป็นกรอบการสร้างภาษาคล้ายกับ Lex และ Yacc มีกุยที่เรียกว่าANTLRWorksที่ทำให้กระบวนการง่าย

ในโลก. NET มีDynamic Language Runtimeซึ่งสามารถใช้ในการสร้างรหัสใน. NET โลก ฉันได้เขียนภาษานิพจน์ชื่อZentrumที่สร้างรหัสโดยใช้ DLR มันจะแสดงวิธีแยกวิเคราะห์และดำเนินการนิพจน์ที่พิมพ์แบบคงที่และแบบไดนามิก


2

สำหรับการแนะนำอย่างง่ายเกี่ยวกับวิธีการทำงานของคอมไพเลอร์และวิธีการสร้างภาษาการเขียนโปรแกรมของคุณเองฉันขอแนะนำหนังสือเล่มใหม่http://createyourproglang.comซึ่งมุ่งเน้นที่ทฤษฎีการออกแบบภาษามากขึ้นโดยไม่ต้องรู้เกี่ยวกับ OS / CPU ภายในเช่น lexers, parsers ล่ามและอื่น ๆ

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


2

หากสิ่งที่คุณพูดนั้นเป็นความจริงคุณมีประวัติของนักวิจัยที่มีแนวโน้มและความเข้าใจที่เป็นรูปธรรมสามารถรับได้เพียงทางเดียวเท่านั้นคือการศึกษา และฉันไม่ได้พูดว่า " อ่านหนังสือวิทยาศาสตร์คอมพิวเตอร์ระดับสูงทั้งหมด (พิเศษเหล่านี้ ) เขียนโดยอัจฉริยะนี้!"; ฉันหมายถึง: คุณต้องอยู่กับคนระดับสูงเพื่อที่จะเป็นนักวิทยาศาสตร์คอมพิวเตอร์เช่น Charles Babbage, Alan Turing, Claude Shannon หรือ Dennis Ritchie ฉันไม่ได้ดูถูกคนที่สอนตัวเอง (ฉันเป็นหนึ่งในนั้น) แต่มีคนไม่มากที่เหมือนกับคุณ ฉันอย่างจริงจังขอแนะนำโปรแกรมระบบสัญลักษณ์ (เอสเอส)ที่มหาวิทยาลัยสแตนฟอ ตามที่เว็บไซต์ของพวกเขาพูดว่า:

โปรแกรมสัญลักษณ์ระบบ (SSP) ที่มหาวิทยาลัยสแตนฟอร์ดมุ่งเน้นไปที่คอมพิวเตอร์และจิตใจ: ระบบประดิษฐ์และธรรมชาติที่ใช้สัญลักษณ์เพื่อแสดงข้อมูล SSP รวบรวมนักศึกษาและคณาจารย์ที่สนใจในแง่มุมต่าง ๆ ของความสัมพันธ์ระหว่างมนุษย์กับคอมพิวเตอร์รวมถึง ...

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

2

ฉันจะแนะนำบางสิ่งบางอย่างออกจากสนามด้านซ้าย: เรียนรู้ Python (หรือบางทีอาจเป็น Ruby แต่ฉันมีประสบการณ์มากขึ้นใน Python ดังนั้นนั่นคือสิ่งที่ฉันจะพูดคุย) และไม่เพียงแค่ตะลุยมันเท่านั้น แต่ทำความรู้จักกับมันในระดับลึก

มีหลายสาเหตุที่ฉันแนะนำสิ่งนี้:

  1. Python เป็นภาษาที่ออกแบบมาอย่างดีเยี่ยม แม้ว่าจะมีหูดน้อย แต่ก็มี IMHO น้อยกว่าภาษาอื่น ๆ หากคุณเป็นนักออกแบบภาษาที่กำลังดีควรเปิดเผยภาษาที่ดีที่สุดเท่าที่จะเป็นไปได้

  2. การปรับใช้มาตรฐานของงูใหญ่ (CPython) เป็นโอเพ่นซอร์สและมีเอกสารที่ดีทำให้เข้าใจได้ง่ายขึ้นว่าภาษาทำงานอย่างไรภายใต้ประทุน

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

  4. Python มีคุณสมบัติใหม่มากมายที่เสนอไว้ซึ่งบันทึกไว้ใน PEP ที่มีหมายเลข (ข้อเสนอการปรับปรุง Python) PEP น่าสนใจที่จะอ่านเพื่อดูว่านักออกแบบภาษาพิจารณาใช้งานคุณลักษณะอย่างไรก่อนที่จะเลือกวิธีที่พวกเขาทำ (PEPs ที่ยังอยู่ระหว่างการพิจารณามีความน่าสนใจเป็นพิเศษในเรื่องนี้)

  5. Python มีการผสมผสานคุณสมบัติจากกระบวนทัศน์การเขียนโปรแกรมที่หลากหลายดังนั้นคุณจะได้เรียนรู้เกี่ยวกับวิธีการต่างๆในการแก้ปัญหาและมีเครื่องมือที่หลากหลายเพื่อพิจารณารวมถึงในภาษาของคุณเอง

  6. Python ช่วยให้การขยายภาษาง่ายขึ้นในหลาย ๆ ด้านด้วยเครื่องมือตกแต่ง, metaclasses, hooks นำเข้า ฯลฯ เพื่อให้คุณสามารถเล่นกับคุณสมบัติภาษาใหม่ได้โดยไม่ต้องออกจากภาษา (นอกเหนือจาก: บล็อกของรหัสเป็นวัตถุชั้นหนึ่งใน Ruby ดังนั้นคุณสามารถเขียนโครงสร้างการควบคุมใหม่เช่นลูปได้ฉันรู้สึกว่าโปรแกรมเมอร์ Ruby ไม่จำเป็นต้องพิจารณาว่าการขยายภาษานั้นเป็นอย่างไร คุณเขียนโปรแกรมใน Ruby แต่มันเจ๋งมาก)

  7. ใน Python คุณสามารถถอดแยกรหัสที่สร้างโดยคอมไพเลอร์หรือแม้แต่เขียนของคุณเองตั้งแต่เริ่มต้นและให้ล่ามดำเนินการ (ฉันได้ทำสิ่งนี้ด้วยตัวเองแล้วมันก็น่าสะใจ แต่สนุก)

  8. Python มีห้องสมุดที่ดีสำหรับการแยกวิเคราะห์ คุณสามารถแยกวิเคราะห์รหัสไพ ธ อนลงในแผนผังต้นไม้แบบนามธรรมแล้วจัดการมันโดยใช้โมดูล AST โมดูล PyParsing มีประโยชน์สำหรับการแยกวิเคราะห์ภาษาโดยพลการเช่นภาษาที่คุณออกแบบ ในทางทฤษฎีคุณสามารถเขียนภาษาคอมไพเลอร์ภาษาแรกของคุณใน Python ถ้าคุณต้องการ (และมันสามารถสร้าง C, แอสเซมบลีหรือเอาท์พุท Python ได้)

วิธีการสืบสวนนี้อาจเป็นไปได้ด้วยวิธีการที่เป็นทางการมากขึ้นเนื่องจากคุณจะเริ่มรับรู้แนวความคิดที่คุณศึกษาในภาษาที่คุณทำงานด้วยและในทางกลับกัน

มีความสุข!


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

1

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

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

หัวใจของระบบปฏิบัติการคือเคอร์เนลซึ่งจัดการทรัพยากร (เช่นการจัดสรรหน่วยความจำ / การจัดสรรคืน) และสลับระหว่างงาน / กระบวนการ / โปรแกรม

แอสเซมเบลอร์เป็นการแปลงข้อความ -> ไบต์

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

ฉันอยากจะแนะนำให้เขียนเป็น C; C เป็นภาษากลางสำหรับการทำงานในระดับนั้น


1
ในทางตรงกันข้ามนี่เป็นสถานที่ที่ดีสำหรับภาษาระดับสูงมาก ตราบใดที่คุณสามารถกำหนดแต่ละไบต์ในไฟล์คุณสามารถสร้างคอมไพเลอร์ / แอสเซมเบลอร์ (ซึ่งง่ายกว่า) ในภาษาใดก็ได้ บอกว่า Perl หรือ VBA สวรรค์ความเป็นไปได้!
เอียน

1

ดูหนังสือของ Kenneth Louden "Compiler Construction"

http://www.cs.sjsu.edu/~louden/cmptext/

มันให้วิธีการที่ดีกว่าในการพัฒนาคอมไพเลอร์

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


1

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

ประตูสู่การเปิดเผยเดียวกันคือภาษาแอสเซมบลี "มิกซ์" Knuth ใช้ในตัวอย่างของเขา "Mix" ดูเหมือนจะล้าสมัยในวันนี้ แต่ก็ยังมีผล DE-mystifying


0

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

ฉันขอแนะนำให้คุณเข้าใจระบบปฏิบัติการโดยทั่วไปก่อนและวิธีการรวบรวม / ดำเนินการภาษาที่มีอยู่ (เช่น. (C / C ++), ใน VM (Java) หรือโดยล่าม (Python / Javascript)

ฉันเชื่อว่าเราใช้แนวคิดระบบปฏิบัติการหนังสือโดย Abraham Silberschatz, Peter B. Galvin, Greg Gagne ในหลักสูตรระบบปฏิบัติการของฉัน (ในปีที่ 2) นี่เป็นหนังสือที่ยอดเยี่ยมซึ่งให้คำแนะนำอย่างละเอียดเกี่ยวกับส่วนประกอบแต่ละส่วนของระบบปฏิบัติการ - ราคาค่อนข้างแพง แต่คุ้มค่าและควรใช้สำเนาที่เก่า / ใช้แล้ว


แนวคิดของ OS? น้อยมากที่จำเป็นในการสร้างคอมไพเลอร์ สิ่งที่จำเป็นต้องมีความเข้าใจในสถาปัตยกรรมซอฟต์แวร์: ช่องว่างที่อยู่กองหัวข้อ (ถ้าเขาต้องการที่จะเรียนรู้คอมไพเลอร์เขาเรียนรู้เกี่ยวกับการขนานกันดีกว่าอนาคตของเขา)
Ira Baxter

ทันทีหลังจากบอกว่าเขาต้องการเรียนรู้การออกแบบภาษาและคอมไพเลอร์เขาบอกว่าเขาต้องการเรียนรู้เกี่ยวกับระบบปฏิบัติการ
David Thornley

@Ira - เห็นด้วย ฉันไม่เคยระบุว่าการทำความเข้าใจระบบปฏิบัติการจำเป็นต้องสร้างคอมไพเลอร์ / ภาษาเพียงแค่อธิบายว่ามันอาจเป็นจุดเริ่มต้นที่ง่ายขึ้น ทุกคนมุ่งความสนใจไปที่ 'คอมไพเลอร์' ในคำถามของเขา แต่เขายังกล่าวด้วยว่าเขาต้องการความเข้าใจที่ดีขึ้นเกี่ยวกับระบบปฏิบัติการและไลบรารี สำหรับเด็กอายุ 15 ปีที่ยังเรียนรู้เกี่ยวกับสถาปัตยกรรมมันจะมีประโยชน์มากขึ้นในการทำความเข้าใจเกี่ยวกับการจัดการหน่วยความจำการทำเกลียวการล็อก i / o ฯลฯ มากกว่าการเรียนรู้วิธีกำหนดไวยากรณ์ด้วย yacc (IMHO)
plafond

ขออภัย ... พลาดจุดที่ต้องการเรียนรู้เกี่ยวกับระบบปฏิบัติการ (อาคาร) ประเด็นของฉันคือ: เขาไม่จำเป็นต้องมีความรู้เรื่องระบบปฏิบัติการมากมายสำหรับคอมไพเลอร์ ในความเป็นจริงมันเป็นหัวข้อที่แตกต่างอย่างสิ้นเชิงยกเว้นที่คอมไพเลอร์และระบบปฏิบัติการโต้ตอบเพื่อให้บรรลุวัตถุประสงค์ร่วมกัน (Multics ต้องการคอมไพเลอร์ PL / 1 เพื่อสร้างการเรียกฟังก์ชันในวิธีการบางอย่างเพื่อเปิดใช้งาน VM ระดับโลกเป็นต้น
Ira Baxter

0

มันเป็นหัวข้อใหญ่ แต่แทนที่จะแปรงคุณด้วยความขี้เล่น "ไปอ่านหนังสือเด็ก" แทนฉันยินดีที่จะให้พอยน์เตอร์เพื่อช่วยคุณห่อหัวของคุณรอบ ๆ มัน

คอมไพเลอร์ส่วนใหญ่และ / หรือล่ามทำงานเช่นนี้:

tokenize : สแกนข้อความรหัสและทำลายมันลงในรายการของสัญญาณ

ขั้นตอนนี้อาจเป็นเรื่องยุ่งยากเพราะคุณไม่สามารถแยกสตริงในช่องว่างได้คุณต้องจำไว้ว่าif (bar) foo += "a string";เป็นรายการของโทเค็น 8 รายการ: WORD, OPEN_PAREN, WORD, CLOSE_PAREN, WORD, ASIGNMENT_ADD, STRING_LITERAL, TERMINATOR อย่างที่คุณเห็นเพียงแค่การแยกซอร์สโค้ดในช่องว่างไม่ทำงานคุณต้องอ่านตัวละครแต่ละตัวเป็นลำดับดังนั้นหากคุณพบตัวอักษรและตัวเลขที่คุณอ่านต่อไปเรื่อย ๆ จนกว่าคุณจะตีตัวอักษรที่ไม่ใช่ตัวอักษรและสตริงนั้น เพิ่งอ่านเป็นคำที่จะจัดประเภทเพิ่มเติมในภายหลัง คุณสามารถตัดสินใจด้วยตัวคุณเองว่า tokenizer ของคุณเป็นอย่างไร: ไม่ว่าจะกลืน"a string"เป็นโทเค็นเดียวที่เรียกว่า STRING_LITERAL เพื่อแยกวิเคราะห์เพิ่มเติมในภายหลังหรือไม่ว่าจะเห็น"a string" เช่น OPEN_QUOTE, UNPARSED_TEXT, CLOSE_QUOTE หรืออะไรก็ตามนี่เป็นเพียงหนึ่งในตัวเลือกมากมายที่คุณต้องตัดสินใจด้วยตัวคุณเองในขณะที่คุณกำลังเขียนโค้ด

ไฟแนนเชี่ยล : ตอนนี้คุณมีรายการโทเค็นแล้ว คุณอาจติดแท็กโทเค็นบางส่วนที่มีการจำแนกประเภทที่ไม่ชัดเจนเช่น WORD เพราะในช่วงแรกที่คุณผ่านไปคุณไม่ต้องใช้ความพยายามมากเกินไปในการค้นหาบริบทของอักขระแต่ละตัว ดังนั้นให้อ่านรายการโทเค็นแหล่งที่มาของคุณอีกครั้งและจัดประเภทโทเค็นที่ไม่ชัดเจนแต่ละประเภทด้วยโทเค็นที่เฉพาะเจาะจงมากขึ้นโดยยึดตามคำหลักในภาษาของคุณ ดังนั้นคุณมีคำเช่น "if" และ "if" อยู่ในรายการคำหลักพิเศษที่เรียกว่า symbol IF ดังนั้นคุณจึงเปลี่ยนประเภทสัญลักษณ์ของโทเค็นนั้นจาก WORD เป็น IF และ WORD ใด ๆ ที่ไม่อยู่ในรายการคำหลักพิเศษของคุณ เช่น WORD foo เป็น IDENTIFIER

แยกวิเคราะห์ : ดังนั้นตอนนี้คุณจึงเปิดif (bar) foo += "a string";รายการโทเค็น lexed ที่มีลักษณะเช่นนี้: ถ้า OPEN_PAREN IDENTIFER CLOSE_PAREN IDENTIFIER ASIGN_ADD STRING_LITERAL TERMINATOR ขั้นตอนคือการรับรู้ลำดับของโทเค็นเป็นคำสั่ง นี่คือการแยกวิเคราะห์ คุณทำได้โดยใช้ไวยากรณ์เช่น:

ประกาศ: = ASIGN_EXPRESSION | IF_STATEMENT

IF_STATEMENT: = IF, PAREN_EXPRESSION, คำชี้แจง

ASIGN_EXPRESSION: = IDENTIFIER, ASIGN_OP, VALUE

PAREN_EXPRESSSION: = OPEN_PAREN, VALUE, CLOSE_PAREN

ค่า: = IDENTIFIER | STRING_LITERAL | PAREN_EXPRESSION

ASIGN_OP: = EQUAL | ASIGN_ADD | ASIGN_SUBTRACT | ASIGN_MULT

การผลิตที่ใช้ "|" ระหว่างคำศัพท์หมายถึง "จับคู่สิ่งเหล่านี้" ถ้ามีเครื่องหมายจุลภาคระหว่างข้อกำหนดหมายความว่า "จับคู่ลำดับของคำนี้"

คุณใช้สิ่งนี้อย่างไร เริ่มต้นด้วยโทเค็นแรกพยายามจับคู่ลำดับโทเค็นของคุณกับการผลิตเหล่านี้ ดังนั้นก่อนอื่นคุณลองจับคู่รายการโทเค็นของคุณกับ STATEMENT ดังนั้นคุณจึงอ่านกฎสำหรับ STATEMENT และมันบอกว่า "STATEMENT เป็น ASIGN_EXPRESSION หรือ IF_STATEMENT" ดังนั้นคุณจึงลองจับคู่ ASIGN_EXPRESSION ก่อนเพื่อให้คุณค้นหากฎไวยากรณ์สำหรับ ASIGN_EXPRESSION และมันบอกว่า "ASIGN_EXPRESSION เป็น IDENTIFIER ตามด้วย ASIGN_OP แล้วตามด้วย VALUE ดังนั้นคุณจึงค้นหากฎไวยากรณ์สำหรับ IDENTIFIER และคุณเห็นว่าไม่มี Ruke ไวยากรณ์สำหรับ IDENTIFIER ซึ่งหมายความว่า IDENTIFIER" terminal "หมายความว่ามันไม่จำเป็นต้องเพิ่มเติม การแยกวิเคราะห์เพื่อจับคู่เพื่อให้คุณสามารถลองจับคู่โดยตรงกับโทเค็นของคุณ แต่โทเค็นต้นทางแรกของคุณคือ IF และ IF ไม่เหมือนกับ IDENTIFIER ดังนั้นการจับคู่ล้มเหลว เกิดอะไรขึ้น คุณกลับไปที่กฎ STATEMENT และลองจับคู่คำถัดไป: IF_STATEMENT คุณค้นหา IF_STATEMENT มันเริ่มต้นด้วย IF, ค้นหา IF, ถ้าเป็นเทอร์มินัล, เปรียบเทียบเทอร์มินัลกับโทเค็นแรกของคุณ, IF โทเค็นที่ตรงกัน, ไปเรื่อย ๆ ต่อไป, เทอมถัดไปคือ PAREN_EXPRESSION, ค้นหา PAREN_EXPRESSION PAREN_EXPRESSION เริ่มต้นด้วย OPEN_PAREN ค้นหา OPEN_PAREN เป็นเทอร์มินัลจับคู่ OPEN_PAREN กับโทเค็นถัดไปของคุณจับคู่กับ .... และอื่น ๆ

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

แต่ละครั้งที่แยกวิเคราะห์ () ตรงกับการผลิตเช่น ASIGN_EXPRESSION คุณสร้างโครงสร้างที่เป็นตัวแทนของชิ้นส่วนของรหัสนั้น โครงสร้างนี้มีการอ้างอิงถึงโทเค็นต้นฉบับ คุณเริ่มสร้างรายการโครงสร้างเหล่านี้ เราจะเรียกโครงสร้างทั้งหมดนี้ว่าแผนผังบทคัดย่อของบทคัดย่อ (AST)

รวบรวมและ / หรือดำเนินการ : สำหรับโปรดักชั่นบางอย่างในไวยากรณ์ของคุณคุณได้สร้างฟังก์ชั่นการจัดการที่ถ้าได้รับโครงสร้าง AST มันจะรวบรวมหรือดำเนินการอัน AST

ลองดูที่ชิ้นส่วนของ AST ของคุณที่มีประเภท ASIGN_ADD ดังนั้นในฐานะล่ามคุณจะมีฟังก์ชัน ASIGN_ADD_execute () ฟังก์ชันนี้ถูกส่งเป็นชิ้นส่วนของ AST ที่สอดคล้องกับแผนผังการแยกวิเคราะห์foo += "a string"ดังนั้นฟังก์ชันนี้จึงดูโครงสร้างนั้นและรู้ว่าเทอมแรกในโครงสร้างจะต้องเป็น IDENTIFIER และเทอมที่สองคือ VALUE ดังนั้น ASIGN_ADD_execute () ส่งผ่านคำว่า VALUE ไปยังฟังก์ชัน VALUE_eval () ซึ่งส่งคืนออบเจกต์ที่แสดงค่าที่ประเมินในหน่วยความจำจากนั้น ASIGN_ADD_execute () จะค้นหา "foo" ในตารางตัวแปรของคุณและเก็บการอ้างอิงถึงสิ่งที่ถูกส่งกลับโดย eval_value () ฟังก์ชัน

นั่นคือล่าม คอมไพเลอร์จะมีฟังก์ชั่นจัดการแทนแปล AST เป็นรหัสไบต์หรือรหัสเครื่องแทนการดำเนินการ

ขั้นตอนที่ 1 ถึง 3 และ 4 สามารถทำได้ง่ายขึ้นโดยใช้เครื่องมือเช่น Flex และ Bison (aka. Lex และ Yacc) แต่การเขียนล่ามตัวเองตั้งแต่เริ่มต้นอาจเป็นแบบฝึกหัดที่ช่วยให้โปรแกรมเมอร์สามารถบรรลุผลได้มากที่สุด ความท้าทายในการเขียนโปรแกรมอื่น ๆ นั้นดูเล็กน้อยหลังจากการประชุมสุดยอดครั้งนี้

คำแนะนำของฉันคือการเริ่มต้นเล็ก ๆ : ภาษาเล็ก ๆ ที่มีไวยากรณ์เล็ก ๆ และลองแยกวิเคราะห์และดำเนินการคำสั่งง่ายๆไม่กี่คำแล้วเติบโตจากที่นั่น

อ่านสิ่งเหล่านี้และขอให้โชคดี!

http://www.iro.umontreal.ca/~felipe/IFT2030-Automne2002/Complements/tinyc.c

http://en.wikipedia.org/wiki/Recursive_descent_parser


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

0

เขตข้อมูลคอมพิวเตอร์มีความซับซ้อนเพียงเพราะมีเวลาในการพัฒนาไปในหลายทิศทาง หัวใจของมันเป็นเพียงเครื่องจักรที่คำนวณได้

คอมพิวเตอร์ที่ชื่นชอบมากพื้นฐานของฉันคือแฮร์รี่พอร์เตอร์คอมพิวเตอร์ Relay มันให้รสชาติของการทำงานของคอมพิวเตอร์ในระดับฐาน จากนั้นคุณสามารถเริ่มชื่นชมสิ่งต่าง ๆ เช่นภาษาและระบบปฏิบัติการ

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


-1

ไปดูที่http://mikeos.berlios.de/

มีระบบปฏิบัติการง่าย ๆ ในแอสเซมบลี x86

เขามีการสอนที่ดีเกี่ยวกับวิธีการเขียนระบบปฏิบัติการอย่างง่ายตั้งแต่เริ่มต้น


-1

หนังสือแนะนำที่ดีอีกเล่มหนึ่งคือ "Compilerbau" ของ N. Wirth จากปี 1986 (การสร้างคอมไพเลอร์) ซึ่งมีความยาวประมาณ 100 หน้าและอธิบายสั้นกระชับรหัสที่ออกแบบมาอย่างดีสำหรับภาษาของเล่น PL / 0 รวมถึง parser เครื่องสร้างรหัสและเครื่องเสมือน นอกจากนี้ยังแสดงวิธีการเขียน parser ที่อ่านในไวยากรณ์เพื่อแยกวิเคราะห์ในรูปแบบ EBNF หนังสือเล่มนี้เป็นภาษาเยอรมัน แต่ผมเขียนสรุปและแปลรหัสเพื่อหลามการออกกำลังกายให้ดูhttp://www.d12k.org/cmplr/w86/intro.html


-1

หากคุณมีความสนใจในการทำความเข้าใจสาระสำคัญของภาษาการเขียนโปรแกรมฉันขอแนะนำให้คุณทำงานผ่าน PLAI (http://www.cs.brown.edu/~sk/Publications/Books/ProgLangs/) เพื่อทำความเข้าใจแนวคิดและ การดำเนินการของพวกเขา นอกจากนี้ยังจะช่วยคุณในการออกแบบภาษาของคุณเอง


-1

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

  • ตัวเลขที่อนุญาต
  • ผู้ประกอบการที่ได้รับอนุญาต
  • ลำดับความสำคัญของผู้ประกอบการ
  • การตรวจสอบไวยากรณ์
  • กลไกค้นหาตัวแปร
  • ตรวจจับรอบ
  • การเพิ่มประสิทธิภาพ

ตัวอย่างเช่นคุณมีสูตรดังต่อไปนี้เครื่องคิดเลขของคุณควรจะสามารถคำนวณค่าของ x:

a = 1
b = 2
c = a + b
d = (3 + b) * c
x = a - d / b

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.