ประเภทของผู้แปล ควรเลือกกฎ A:x ถ้า a อยู่ใน FIRST(x) ทำไมมันถึงสำคัญ

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

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

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

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

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

วิธีการใช้งานอีกวิธีหนึ่งคือเมื่อโปรแกรมทำงานด้วย ล่ามไม่มีการแปลเลย ล่ามจะจำลองเครื่องโดยทางโปรแกรมซึ่งมีลูปเรียกใช้การดึงข้อมูลซึ่งทำงานตามคำสั่งในภาษาระดับสูงมากกว่าคำสั่งของเครื่อง เช่น การจำลองซอฟต์แวร์สร้าง เครื่องเสมือนซึ่งใช้ภาษา วิธีการนี้เรียกว่าการตีความที่บริสุทธิ์ การตีความแบบบริสุทธิ์มักใช้สำหรับภาษาที่มีโครงสร้างแบบง่าย (เช่น APL หรือ Lisp) ล่าม บรรทัดคำสั่งประมวลผลคำสั่งในสคริปต์บน UNIX หรือในแบตช์ไฟล์ (.bat) บน MS-DOS ซึ่งโดยปกติจะอยู่ในโหมดการตีความล้วน

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

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

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

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

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

หมวดที่ 7 การแปล เรียบเรียง และตีความ

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

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

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

นักแปล -โปรแกรมหรือ วิธีการทางเทคนิคการแสดง การออกอากาศของรายการ. โปรแกรมเครื่องที่แปลจากภาษาหนึ่งเป็นอีกภาษาหนึ่ง โดยเฉพาะอย่างยิ่ง จากภาษาโปรแกรมหนึ่งเป็นอีกภาษาหนึ่ง โปรแกรมประมวลผลที่ออกแบบมาเพื่อแปลงซอร์สโปรแกรมเป็นออบเจกต์โมดูล

ตัวแปลมักจะทำการวินิจฉัยข้อผิดพลาด สร้างพจนานุกรมของตัวระบุ พิมพ์ข้อความโปรแกรม ฯลฯ

รายการออกอากาศ -การแปลงโปรแกรมที่นำเสนอในภาษาโปรแกรมหนึ่งเป็นโปรแกรมในภาษาอื่นและในแง่หนึ่งเทียบเท่ากับภาษาแรก

ภาษาที่แสดงโปรแกรมอินพุตเรียกว่า ภาษาต้นฉบับและตัวโปรแกรมเอง รหัสแหล่งที่มา. ภาษาที่ส่งออกเรียกว่า ภาษาเป้าหมายหรือ รหัสวัตถุ.

ประเภทของผู้แปล

นักแปลแบ่งออกเป็น:

· ที่อยู่. อุปกรณ์การทำงานที่แปลงที่อยู่เสมือน ที่อยู่เสมือน) ไปยังที่อยู่จริง (อังกฤษ ที่อยู่หน่วยความจำ).

· กล่องโต้ตอบ. ให้การใช้ภาษาการเขียนโปรแกรมในโหมดการแบ่งเวลา

· มัลติพาส. สร้างโมดูลออบเจกต์ในหลายๆ มุมมองของซอร์สโปรแกรม

· กลับ. เช่นเดียวกับรีเลย์ ดูเพิ่มเติมที่: decompiler, disassembler

· ผ่านครั้งเดียว. สร้างโมดูลวัตถุในการสแกนตามลำดับของโปรแกรมต้นทาง

· การเพิ่มประสิทธิภาพ. ดำเนินการปรับรหัสให้เหมาะสมในโมดูลวัตถุที่สร้างขึ้น

· Syntactically-Oriented (วากยสัมพันธ์). ได้รับคำอธิบายของไวยากรณ์และความหมายของภาษาและข้อความในภาษาที่อธิบายเป็นอินพุตซึ่งแปลตามคำอธิบายที่ระบุ

· ทดสอบ. ชุดมาโครภาษาแอสเซมบลีที่ให้คุณตั้งค่าขั้นตอนการดีบักต่างๆ ในโปรแกรมที่เขียนด้วยภาษาแอสเซมบลี



นักแปลจะดำเนินการในรูปแบบ คอมไพเลอร์ หรือ ล่าม . ในแง่ของการทำงาน คอมไพเลอร์และล่ามนั้นแตกต่างกันมาก

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

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

การรวบรวม- การแปลโปรแกรมที่เขียนด้วยภาษาต้นทางเป็นโมดูลวัตถุ ดำเนินการโดยคอมไพเลอร์

รวบรวม -เพื่อแปลโปรแกรมเครื่องจากภาษาเชิงปัญหาเป็นภาษาเชิงเครื่อง

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

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



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

ความแตกต่างระหว่างการเรียบเรียงและการตีความ

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

2. โปรแกรมที่คอมไพล์ทำงานเร็วกว่า แต่โปรแกรมที่แปลแล้วแก้ไขและเปลี่ยนแปลงได้ง่ายกว่า

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

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

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

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

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

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

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


ขั้นตอนการรวบรวมแบ่งออกเป็นหลายขั้นตอน:

1. พรีโปรเซสเซอร์โปรแกรมต้นทางถูกประมวลผลโดยการแทนที่แมโครและไฟล์ส่วนหัวที่มีอยู่

2. การวิเคราะห์คำศัพท์และวากยสัมพันธ์โปรแกรมจะถูกแปลงเป็นสตริงของโทเค็นจากนั้นจึงเป็นตัวแทนต้นไม้ภายใน

3. การเพิ่มประสิทธิภาพทั่วโลกการแสดงภายในของโปรแกรมจะถูกแปลงซ้ำๆ เพื่อลดขนาดและเวลาดำเนินการของโปรแกรม

4. การสร้างรหัสการแสดงภายในจะถูกแปลงเป็นบล็อกคำสั่งตัวประมวลผล ซึ่งจะถูกแปลงเป็นข้อความแอสเซมเบลอร์หรือรหัสวัตถุ

5. การประกอบ.หากมีการสร้างข้อความแอสเซมบลี แอสเซมบลีจะได้รับรหัสวัตถุ

6. การประกอบ.แอสเซมเบลอร์รวมไฟล์อ็อบเจกต์หลายไฟล์เป็นไฟล์เรียกทำงานหรือไลบรารี

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

ที่ขั้นตอน LA ตรวจพบข้อผิดพลาด (ที่ง่ายที่สุด) บางอย่าง (อักขระไม่ถูกต้อง การบันทึกตัวเลขไม่ถูกต้อง ตัวระบุ ฯลฯ)

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

งานหลักของการวิเคราะห์คำศัพท์ - ทุบ ข้อความที่ป้อน, ประกอบด้วยลำดับของอักขระตัวเดียว, เป็นลำดับของคำ, หรือ lexemes เช่น แยกคำเหล่านี้ออกจากลำดับอักขระที่ต่อเนื่องกัน จากมุมมองนี้ อักขระทั้งหมดของลำดับการป้อนข้อมูลจะถูกแบ่งออกเป็นอักขระที่เป็นของ lexemes และอักขระที่แยก lexemes (ตัวคั่น) ในบางกรณี อาจไม่มีตัวคั่นระหว่างโทเค็น ในทางกลับกัน ในบางภาษา โทเค็นอาจมีอักขระที่ไม่มีนัยสำคัญ (เช่น อักขระเว้นวรรคใน Fortran) ใน C ค่าคั่นของอักขระตัวคั่นสามารถบล็อกได้ ("\" ที่ท้ายบรรทัดภายใน "...")

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

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

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

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

ตัววิเคราะห์คำศัพท์สามารถเป็นได้ทั้งช่วงการแปลอิสระหรือรูทีนย่อยที่ทำงานบนหลักการ "ให้โทเค็น" ในกรณีแรก (รูปที่ 3.1, a) ผลลัพธ์ของตัววิเคราะห์คือไฟล์โทเค็น ในกรณีที่สอง (รูปที่ 3.1, b) โทเค็นจะออกทุกครั้งที่เข้าถึงตัววิเคราะห์ (ในกรณีนี้คือ กฎแอตทริบิวต์ของคลาสโทเค็นจะถูกส่งกลับตามผลลัพธ์ของฟังก์ชัน "ตัววิเคราะห์คำศัพท์" และค่าของโทเค็นจะถูกส่งผ่านตัวแปรส่วนกลาง) ในแง่ของการประมวลผลค่าโทเค็น โปรแกรมแยกวิเคราะห์สามารถส่งคืนค่าของโทเค็นแต่ละรายการได้ ซึ่งในกรณีนี้การสร้างตารางออบเจกต์ (ตัวระบุ สตริง ตัวเลข ฯลฯ) จะถูกเลื่อนไปยังเฟสถัดไป หรืออาจสร้างตารางออบเจกต์เองก็ได้ . ในกรณีนี้ ตัวชี้ไปยังรายการของตารางที่เกี่ยวข้องจะได้รับเป็นค่าของ lexeme

ข้าว. 3.1:

การทำงานของตัววิเคราะห์คำศัพท์นั้นได้รับจากออโตมาตอนที่มีขอบเขตจำกัด อย่างไรก็ตามคำอธิบายโดยตรง เครื่องสถานะไม่สะดวกจากมุมมองเชิงปฏิบัติ ดังนั้น ในการระบุตัววิเคราะห์คำศัพท์ ตามกฎแล้ว จะใช้นิพจน์ทั่วไปหรือไวยากรณ์เชิงเส้นขวา พิธีการทั้งสามแบบ (finite automata, Regular expression และ right-linear grammar) มีพลังในการแสดงออกเหมือนกัน โดยเฉพาะอย่างยิ่งตาม นิพจน์ทั่วไปหรือไวยากรณ์เชิงเส้นตรง เราสามารถสร้างเครื่องสถานะที่จดจำภาษาเดียวกันได้

งานหลักของการแยกวิเคราะห์ - การวิเคราะห์โครงสร้างของโปรแกรม ตามกฎแล้ว โครงสร้างจะถูกเข้าใจว่าเป็นต้นไม้ที่สอดคล้องกับการแยกวิเคราะห์ในไวยากรณ์ของภาษาที่ไม่มีบริบท ในปัจจุบัน การวิเคราะห์ LL(1) (และตัวแปรแบบวนซ้ำแบบโคตร) หรือการวิเคราะห์แบบ LR(1) และแบบแปรผัน (LR(0), SLR(1), LALR(1) และอื่นๆ) มักใช้กันมากที่สุด การสืบเชื้อสายแบบเรียกซ้ำมักใช้เมื่อตั้งโปรแกรมตัวแยกวิเคราะห์ด้วยตนเอง LR(1) - เมื่อใช้ระบบอัตโนมัติสำหรับการสร้างตัวแยกวิเคราะห์

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

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

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

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

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

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

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

ส่งงานที่ดีของคุณในฐานความรู้เป็นเรื่องง่าย ใช้แบบฟอร์มด้านล่าง

การทำงานที่ดีไปที่ไซต์">

นักศึกษา บัณฑิต นักวิทยาศาสตร์รุ่นเยาว์ที่ใช้ฐานความรู้ในการศึกษาและการทำงานจะขอบคุณมาก

โฮสต์ที่ http://www.allbest.ru

การแนะนำ

1.1 การแยกวิเคราะห์จากบนลงล่าง

1.2 การแยกวิเคราะห์จากล่างขึ้นบน

1.2.1 LR(k) - ไวยากรณ์

1.2.1.1 LR(0) - ไวยากรณ์

1.2.2 LALR(1) ไวยากรณ์

2. การพัฒนานักแปล

2.1 การวิเคราะห์ความต้องการ

2.2 การออกแบบ

2.2.1 การออกแบบตัววิเคราะห์คำศัพท์

2.2.4 การใช้งานซอฟต์แวร์ของ parser

2.3 การเข้ารหัส

2.4 การทดสอบ

บทสรุป

รายการแหล่งที่มาที่ใช้

ภาคผนวก ก. รายการข้อความโปรแกรมของผู้แปล

ภาคผนวก ข. ผลการทดสอบ

ภาคผนวก ค. แผนผังโปรแกรมแปลภาษา

การแนะนำ

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

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

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

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

ความหมายของภาษาการเขียนโปรแกรมแตกต่างกันไปในวงกว้างมาก พวกเขาไม่เพียง แต่แตกต่างกันในการดำเนินการเฉพาะของการดำเนินงานแต่ละรายการเท่านั้น แต่ยังรวมถึงกระบวนทัศน์การเขียนโปรแกรมที่กำหนดความแตกต่างพื้นฐานในวิธีการพัฒนาโปรแกรม ลักษณะเฉพาะของการดำเนินงานอาจเกี่ยวข้องกับทั้งโครงสร้างของข้อมูลที่ประมวลผลและกฎสำหรับการประมวลผลประเภทข้อมูลเดียวกัน ภาษาต่างๆ เช่น PL/1 และ APL รองรับการทำงานของเมทริกซ์และเวกเตอร์ ภาษาส่วนใหญ่ทำงานกับสเกลาร์เป็นหลัก โดยมีขั้นตอนและฟังก์ชันที่เขียนโดยโปรแกรมเมอร์เพื่อจัดการกับอาร์เรย์ แต่ถึงแม้จะดำเนินการเพิ่มจำนวนเต็มสองจำนวน ภาษาเช่น C และ Pascal ก็สามารถทำงานแตกต่างกันได้

ควบคู่ไปกับประเพณี การเขียนโปรแกรมเชิงขั้นตอนเรียกอีกอย่างว่าความจำเป็น มีกระบวนทัศน์เช่นการเขียนโปรแกรมเชิงฟังก์ชัน การเขียนโปรแกรมลอจิกและการเขียนโปรแกรมเชิงวัตถุ โครงสร้างของแนวคิดและวัตถุของภาษาขึ้นอยู่กับกระบวนทัศน์ที่เลือกซึ่งส่งผลต่อการนำนักแปลไปปฏิบัติด้วย
แม้แต่ภาษาเดียวกันก็สามารถทำได้หลายวิธี นี่เป็นเพราะความจริงที่ว่าทฤษฎีของไวยากรณ์อย่างเป็นทางการอนุญาตให้มีวิธีการต่างๆในการแยกวิเคราะห์ประโยคเดียวกัน ตามนี้ คอมไพเลอร์ด้วยวิธีต่างๆ สามารถรับผลลัพธ์เดียวกัน (โปรแกรมวัตถุ) จากข้อความต้นทางต้นฉบับ
อย่างไรก็ตาม ภาษาโปรแกรมทั้งหมดมีจำนวน ลักษณะทั่วไปและพารามิเตอร์ ความเหมือนกันนี้ยังกำหนดหลักการของการจัดระเบียบนักแปลที่คล้ายคลึงกันสำหรับทุกภาษา
ภาษาโปรแกรมถูกออกแบบมาเพื่อให้เขียนโปรแกรมได้ง่ายขึ้น ดังนั้นตัวดำเนินการและโครงสร้างข้อมูลจึงมีประสิทธิภาพมากกว่าในภาษาเครื่อง
เพื่อเพิ่มการมองเห็นของโปรแกรม แทนที่จะใช้รหัสตัวเลข สัญลักษณ์ หรือ การแสดงกราฟิกโครงสร้างภาษาที่มนุษย์สามารถอ่านได้มากขึ้น
สำหรับภาษาใด ๆ ถูกกำหนด:
- ชุดสัญลักษณ์ที่ใช้เขียนโปรแกรมได้ถูกต้อง (ตัวอักษร) องค์ประกอบพื้นฐาน
- ชุดของโปรแกรมที่ถูกต้อง (ไวยากรณ์)
- "ความหมาย" ของแต่ละโปรแกรมที่ถูกต้อง (ความหมาย)
โดยไม่คำนึงถึงความเฉพาะเจาะจงของภาษา นักแปลใดๆ ก็ตามสามารถถือเป็นตัวแปลงการทำงาน F ที่ให้การจับคู่ X ถึง Y อย่างชัดเจน โดยที่ X เป็นโปรแกรมในภาษาต้นทาง Y เป็นโปรแกรมในภาษาเป้าหมาย ดังนั้น กระบวนการแปลจึงสามารถแสดงอย่างเป็นทางการได้ค่อนข้างเรียบง่ายและชัดเจน: Y = F(X)
อย่างเป็นทางการแต่ละคน โปรแกรมที่ถูกต้อง X เป็นชุดอักขระจากตัวอักษร A บางตัว แปลงเป็นสตริง Y ที่สอดคล้องกัน ประกอบด้วยอักขระจากตัวอักษร B
ภาษาการเขียนโปรแกรม เช่นเดียวกับระบบที่ซับซ้อนอื่นๆ ถูกกำหนดผ่านลำดับชั้นของแนวคิดที่กำหนดความสัมพันธ์ระหว่างองค์ประกอบต่างๆ แนวคิดเหล่านี้เกี่ยวข้องกันตามกฎวากยสัมพันธ์ แต่ละโปรแกรมที่สร้างขึ้นตามกฎเหล่านี้มีโครงสร้างลำดับชั้นที่สอดคล้องกัน
ในเรื่องนี้สำหรับทุกภาษาและโปรแกรมของพวกเขาสามารถแยกแยะคุณลักษณะทั่วไปต่อไปนี้เพิ่มเติมได้: แต่ละภาษาต้องมีกฎที่อนุญาตให้สร้างโปรแกรมที่สอดคล้องกับภาษานี้หรือตระหนักถึงความสอดคล้องระหว่างโปรแกรมที่เขียนและภาษาที่กำหนด

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

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

1. วิธีการแยกวิเคราะห์

พิจารณาวิธีการพื้นฐานของการวิเคราะห์ทางไวยากรณ์

1.1 การแยกวิเคราะห์จากบนลงล่าง

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

1.1.1 LL(k) - ภาษาและไวยากรณ์

พิจารณาแผนผังเอาต์พุตในกระบวนการรับเอาต์พุตด้านซ้ายของห่วงโซ่ สายกลางในกระบวนการส่งออกประกอบด้วยสายโซ่ของขั้ว w, สายซ้ายสุดที่ไม่ใช่ขั้ว A, ส่วนที่พิมพ์ด้านล่างของ x:

-S--

/ \

/ -ก-x-\

/ | \

-ว---คุณ----

รูปที่ 1

หากต้องการแยกวิเคราะห์ต่อไป จำเป็นต้องแทนที่ nonterminal A ตามกฎข้อใดข้อหนึ่งของแบบฟอร์ม A:y ถ้าการแยกวิเคราะห์จำเป็นต้องมีการกำหนดขึ้น (ไม่มีการย้อนรอย) กฎนี้จำเป็นต้องเลือกในลักษณะพิเศษ ไวยากรณ์กล่าวกันว่ามีคุณสมบัติ LL(k) หากในการเลือกกฎ ก็เพียงพอแล้วที่จะพิจารณาเฉพาะ wAx และอักขระ k ตัวแรกของสตริง u ที่ไม่ได้ค้นหา ตัวอักษรตัวแรก L (ซ้าย, ซ้าย) หมายถึงการดูสตริงอินพุตจากซ้ายไปขวา ตัวที่สอง - จากเอาต์พุตซ้ายที่ใช้

เรากำหนดโซ่สองชุด:

ก) FIRST(x) - ชุดของสตริงเทอร์มินัลที่ได้มาจาก x ย่อเป็นอักขระ k

b) FOLLOW(A) - ชุดของสตริงเทอร์มินัลที่สั้นลงเป็น k ซึ่งสามารถตามหลัง A ในสตริงเอาต์พุตได้ทันที

ไวยากรณ์มีคุณสมบัติ LL(k) if จากการมีอยู่ของอนุมานซ้ายสองสาย:

S::wAx:wzx::อู๋

S::wAx:wtx::wv

เงื่อนไข FIRST(u)=FIRST(v) หมายถึง z=t

ในกรณีของ k=1 ในการเลือกกฎสำหรับ A ก็เพียงพอแล้วที่จะรู้เฉพาะ A ที่ไม่ใช่เทอร์มินัล และ a - อักขระตัวแรกของสตริง u:

- เลือกกฎ A:x ถ้า a อยู่ใน FIRST(x)

- ควรเลือกกฎ A:e ถ้า a รวมอยู่ใน FOLLOW(A)

LL(k)-property มีข้อ จำกัด ที่ค่อนข้างเข้มงวดเกี่ยวกับไวยากรณ์ ตัวอย่างเช่น LL(2) ไวยากรณ์ S: aS | a ไม่มีคุณสมบัติ LL(1) เนื่องจาก FIRST(aS)=FIRST(a)=ก. ในกรณีนี้ คุณสามารถลดค่า k ได้โดยใช้ "การแยกตัวประกอบ" (การใส่คร่อมตัวประกอบ):

S:aA

ตอบ: ส | อี

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

1.1.2 วิธีสืบเชื้อสายแบบเรียกซ้ำ

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

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

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

รหัสของกฎใด ๆ มีการดำเนินการสำหรับอักขระแต่ละตัวที่รวมอยู่ใน ด้านขวากฎ. การดำเนินการจะแสดงตามลำดับที่สัญลักษณ์ปรากฏในกฎ หลังจากการดำเนินการครั้งล่าสุด รหัสประกอบด้วยการส่งคืนจากขั้นตอน

การใช้การสืบเชื้อสายแบบเรียกซ้ำในภาษาระดับสูงทำให้ง่ายต่อการตั้งโปรแกรมและดีบัก

1.2 การแยกวิเคราะห์จากล่างขึ้นบน

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

-S--

/ \

/-x-\

/ | \

--w--b--u-

รูปที่ 2

เอาต์พุตระดับกลางมีรูปแบบ xbu โดยที่ x คือสายโซ่ของขั้วต่อและไม่ใช่ขั้วต่อซึ่งส่วนที่สแกนของสายขั้วต่อ w เป็นเอาต์พุต bu คือส่วนที่ไม่ได้สแกนของสายขั้วต่อ b คืออักขระถัดไป หากต้องการแยกวิเคราะห์ต่อไป คุณสามารถเพิ่มอักขระ b ลงในส่วนที่สแกนของเชน (ดำเนินการที่เรียกว่า "shift") หรือเลือกที่ส่วนท้ายของ x เช่นเชน z (x=yz) ที่หนึ่งในไวยากรณ์ กฎ B:z สามารถนำไปใช้กับ z และแทนที่ x กับห่วงโซ่ yB (ดำเนินการที่เรียกว่า "convolution"):

-ส-- -ส--

/ \ / \

/-x-b- \ /yB- \

/ | \ / | \

--ว--ข--คุณ- --ว--ข--คุณ-

รูปที่ 3 - หลังการเปลี่ยนแปลง รูปที่ 4 - หลังการบิด

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

ลำดับการทำงานกะและสัญญาเป็นสิ่งสำคัญ ดังนั้น การแยกวิเคราะห์เชิงกำหนดคุณต้องเลือกระหว่างการเลื่อนและการหดตัว (และกฎการบิดงอที่แตกต่างกัน) ในทุกช่วงเวลา

1.2.1 LR(k) - ไวยากรณ์

ถ้าในระหว่างการแยกวิเคราะห์ LR เป็นไปได้ที่จะทำการตัดสินใจเลื่อน/ย่อที่กำหนดโดยการพิจารณาเฉพาะสตริง x และอักขระ k ตัวแรกของส่วนที่ไม่ได้สแกนของสตริงอินพุต u (อักขระ k เหล่านี้เรียกว่าสตริงขั้นสูง) ไวยากรณ์ กล่าวกันว่ามีคุณสมบัติ LR(k)

-S--

/ \

/-x-\

--ว----คุณ--

รูปที่ 5

ความแตกต่างระหว่างไวยากรณ์ LL(k)- และ LR(k) ในแง่ของโครงสร้างที่มา:

-S-

/ | \

/เอ\

/ / \ \

-w---v---ยู-

รูปที่ 6

ในกรณีของไวยากรณ์ LL(k) เราสามารถกำหนดกฎที่ใช้กับ A โดย w และสัญลักษณ์ k ตัวแรกของ vu โดยไม่ซ้ำกัน และในกรณีของไวยากรณ์ LR(k) โดย w, v และ k ตัวแรก สัญลักษณ์ของคุณ อาร์กิวเมนต์หลวมนี้แสดงว่า LL(k)-ภาษา< LR(k)-языки (при k > 0).

1.2.1.1 LR(0) - ไวยากรณ์

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

เรากำหนดชุดต่อไปนี้:

L(A:v) - บริบทด้านซ้ายของกฎ A:v - ชุดสถานะของสแต็ก ทันทีก่อนที่จะยุบ v เป็น A ในระหว่างการแยกวิเคราะห์ LR ที่ประสบความสำเร็จทั้งหมด แน่นอน ทุกสตริงใน L(A:v) ลงท้ายด้วย v หากหาง v ของโซ่ดังกล่าวทั้งหมดถูกตัดออก เราก็จะได้ชุดของโซ่ที่เกิดขึ้นทางด้านซ้ายของ A ในกระบวนการของการอนุมานด้านขวาที่ประสบความสำเร็จทั้งหมด แสดงว่าชุดนี้ L(A) - บริบทด้านซ้ายของ nonterminal A

ให้เราสร้างไวยากรณ์สำหรับชุด L(A) ขั้วและไม่ใช่ขั้วของไวยากรณ์เดิมจะเป็นขั้วของไวยากรณ์ใหม่ ส่วนที่ไม่ใช่ขั้วของไวยากรณ์ใหม่จะแสดงแทน ,... - ค่าของพวกเขาจะเป็นบริบทด้านซ้ายของเทอร์มินัลที่ไม่ใช่ของไวยากรณ์ดั้งเดิม ถ้า S เป็นสัญลักษณ์เริ่มต้นของไวยากรณ์ดั้งเดิม ไวยากรณ์ของบริบทด้านซ้ายจะมีกฎอยู่ : e - บริบทด้านซ้ายของ S มีสตริงว่างสำหรับแต่ละกฎของไวยากรณ์ดั้งเดิม เช่น A: B C d E

และเพิ่มกฎให้กับไวยากรณ์ใหม่:

: - L(B) รวม L(A)

: B - L(C) รวม L(A) B

: B C d - L(E) รวมถึง L(A) B C d

ไวยากรณ์ที่ได้จะมีรูปแบบพิเศษ (ไวยากรณ์ดังกล่าวเรียกว่า left-linear) ดังนั้นชุดของบริบทด้านซ้าย

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

เรียกสถานการณ์ LR(0) ว่ากฎไวยากรณ์โดยมีตำแหน่งที่ทำเครื่องหมายไว้ระหว่างสัญลักษณ์ทางด้านขวาของกฎ ตัวอย่างเช่น สำหรับไวยากรณ์ S:A; ตอบ:aAA; A:b มี LR(0)-สถานการณ์ต่อไปนี้: S:_A; ส:อ_; ตอบ:_aAA; ตอบ:a_AA; ก:aA_A; ก:aAA_; ตอบ:_b; ตอบ:b_ (ตำแหน่งจะแสดงด้วยเครื่องหมายขีดล่าง)

เราจะบอกว่าห่วงโซ่ x สอดคล้องกับสถานการณ์ А:b_c ถ้า x=ab และ a เป็นของ L(A) (กล่าวอีกนัยหนึ่ง การอนุมาน LR สามารถดำเนินต่อไปได้ x_... = ab_...:: abc_...:: aA_...:: S_.) ในเงื่อนไขเหล่านี้ L(A:b) คือเซตของ สตริงที่เข้ากับสถานการณ์ A:b_, L(A)

- เชนที่สอดคล้องกับสถานการณ์ A:_b สำหรับกฎใดๆ A:b

ให้ V(u) เป็นเซตของสถานการณ์ที่สอดคล้องกับ u แสดงว่าฟังก์ชัน V เป็นอุปนัย

ถ้าชุด V(u) มีสถานการณ์ A:b_cd ดังนั้น สถานการณ์ A:bc_d จะเป็นของ V(uc) (c - เทอร์มินัลหรือไม่ใช่เทอร์มินัล b, d - ลำดับ (อาจว่างเปล่า) ของเทอร์มินัลและไม่ใช่เทอร์มินัล) ไม่มีสถานการณ์อื่นเช่น A:b_d โดยที่ b ไม่ว่างเปล่าใน V(uc) มันยังคงเพิ่มสถานการณ์ของแบบฟอร์ม C:_... ถึง V(uc) สำหรับแต่ละ nonterminal C ซึ่งบริบทด้านซ้ายประกอบด้วย uc ถ้าสถานการณ์ A:..._C... (C-nonterminal) อยู่ในชุด V(uc) ดังนั้น uc อยู่ในชุด L(C) และ V(uc) รวมถึงสถานการณ์ในรูปแบบ C:_... สำหรับกฎไวยากรณ์ C ทั้งหมด

V(e) มีสถานการณ์ S:_... (S-อักษรเริ่มต้น) เช่นเดียวกับสถานการณ์ A:_... ถ้า A ที่ไม่ใช่ขั้วเกิดขึ้นทันทีหลังจาก _ ในสถานการณ์ที่รวมอยู่ใน V(e) แล้ว .

สุดท้าย เราพร้อมที่จะกำหนดไวยากรณ์ LR(0) ให้คุณเป็นเนื้อหาของสแต็กในระหว่างการแยกวิเคราะห์ LR และให้ V(u) เป็นชุดของสถานการณ์ LR(0) ที่สอดคล้องกับ u ถ้า V(u) มีสถานการณ์ในรูปแบบ A:x_ (x-sequence of terminal and nonterminals) ดังนั้น u จะอยู่ใน L(A:x) และ x สามารถพับเป็น A ได้ ถ้า V(u) มีสถานการณ์ A:..._a. .. (a-terminal) จากนั้นอนุญาตให้เปลี่ยนได้ มีใครพูดถึงความขัดแย้งแบบ shift-reduce ถ้าทั้ง shift และการหดตัวได้รับอนุญาตสำหรับสตริง u เดียวกัน มีคนพูดถึงความขัดแย้งของการพับหากอนุญาตให้มีการพับตามกฎที่แตกต่างกัน

ไวยากรณ์เรียกว่า LR(0) หากไม่มีข้อขัดแย้ง shift-fold หรือ roll-down สำหรับสถานะสแต็กทั้งหมดในกระบวนการอนุมาน LR

1.2.1.2 LR(k) - ไวยากรณ์

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

นอกจากนี้ เราจะรวมห่วงโซ่ขั้นสูงไว้ในบริบทด้านซ้ายของกฎด้วย ถ้ารากศัพท์ที่ถูกต้องใช้รากศัพท์ wAu: wvu ดังนั้นคู่ wv,FIRSTk(u) จะเป็นของ Lk(A:v) และคู่ของ w,FIRSTk(u) จะเป็นของ Lk(A) ชุดของบริบทด้านซ้าย เช่นในกรณีของ LR(0) สามารถคำนวณได้โดยใช้การเหนี่ยวนำบนห่วงโซ่ด้านซ้าย เรียก LR(k)-situation ว่าคู่: กฎไวยากรณ์ที่มีตำแหน่งที่ทำเครื่องหมายไว้และห่วงโซ่ความยาวล่วงหน้าที่ค่า k มากที่สุด เราจะแยกกฎออกจากห่วงโซ่ขั้นสูงด้วยเส้นแนวตั้ง

เราจะบอกว่าห่วงโซ่ x สอดคล้องกับสถานการณ์ A:b_c|t ถ้ามีเอาต์พุต LR: x_yz = ab_yz:: abc_z:: aA_z:: S_ และ FIRSTk(z)=t กฎสำหรับการคำนวณอุปนัยของชุดสถานะ Vk มีดังนี้:

Vk(e) มีสถานการณ์ S:_a|e สำหรับกฎ S:a ทั้งหมด โดยที่ S เป็นอักขระเริ่มต้น สำหรับแต่ละสถานการณ์ A:_Ba|u จาก Vk(e) แต่ละกฎ B:b และเชน x ที่เป็นของ FIRSTk(au) ต้องเพิ่มสถานการณ์ B:_b|x ให้กับ Vk(e)

หากสถานการณ์ A:b_cd|u เข้าสู่ Vк(w) ดังนั้น สถานการณ์ A:bc_d|u จะเป็นของ Vk(wc) สำหรับแต่ละสถานการณ์ A:b_Cd|u จาก Vk(wc) แต่ละกฎ C:f และเชน x ที่เป็นของ FIRSTk(du) เราต้องเพิ่มสถานการณ์ C:_f|x ถึง Vk(wc)

เราใช้ชุด LR(k)-state ที่สร้างขึ้นเพื่อแก้ปัญหา shift-convolution ให้คุณเป็นเนื้อหาของสแต็กและ x เป็นเชนล่วงหน้า เห็นได้ชัดว่า A:b convolution สามารถทำได้หาก Vk(u) มีสถานการณ์ A:b_|x การตัดสินใจว่าจะยอมรับการเปลี่ยนแปลงได้หรือไม่นั้นต้องการความแม่นยำหากไวยากรณ์มีกฎ e ในสถานการณ์ A:b_c|t (c ไม่ว่างเปล่า) การเปลี่ยนแปลงเป็นไปได้หาก c เริ่มต้นจากเทอร์มินัลและ x เป็นของ FIRSTk(ct) พูดอย่างไม่เป็นทางการ คุณสามารถดันอักขระด้านซ้ายสุดของด้านขวาของกฎไปยังสแต็ก เพื่อเตรียมการบิดที่ตามมา ถ้า c เริ่มต้นจากเทอร์มินัลที่ไม่ใช่ (สถานการณ์จะเหมือน A:b_Cd|t) จากนั้นจึงกดสัญลักษณ์ลงบนสแต็กเพื่อเตรียมการพับใน C เป็นไปได้ก็ต่อเมื่อ C ไม่สร้างสตริงว่าง ตัวอย่างเช่น ในสถานะ V(e)= S:_A|e; A:_AaAb|e,a, A:_|e,a เมื่อได้รับเทอร์มินอลเชนจาก A ในบางขั้นตอนจำเป็นต้องใช้กฎ A:e กับ A ที่ไม่ใช่เทอร์มินอลซึ่งอยู่ที่ปลายด้านซ้ายของเชน

ให้เรานิยามชุด EFFk(x) ที่ประกอบด้วยองค์ประกอบทั้งหมดของชุด FIRSTk(x) ซึ่งรากศัพท์ไม่ได้แทนที่ nonterminal ที่ปลายด้านซ้ายของ x (ถ้ามี) ด้วยสตริงว่าง ในข้อกำหนดเหล่านี้ การเปลี่ยนแปลงจะยอมรับได้หากชุด Vk(u) มีสถานการณ์ А:b_c|t, c ไม่ว่างเปล่า และ x เป็นของ EFFk(ct)

ไวยากรณ์เรียกว่า LR(k)-grammar หากไม่มีสถานะ LR(k) มีสองสถานการณ์ A:b_|u และ B:c_d|v ซึ่ง u อยู่ใน EFFk(dv) คู่ดังกล่าวสอดคล้องกับความขัดแย้งแบบพับถ้า d ว่างเปล่า และความขัดแย้งแบบ shift-fold หาก d ไม่ว่างเปล่า

ในทางปฏิบัติ ไวยากรณ์ LR(k) จะไม่ใช้สำหรับ k>1 มีสองเหตุผลสำหรับเรื่องนี้ ครั้งแรก: มาก เบอร์ใหญ่สถานะ LR(k) ประการที่สอง สำหรับภาษาใดก็ตามที่กำหนดโดยไวยากรณ์ LR(k) จะมีไวยากรณ์ LR(1) อยู่ นอกจากนี้ยังมี LR(1)-grammar สำหรับภาษา CF ที่กำหนดขึ้น

จำนวนของ LR(1) - ระบุในทางปฏิบัติ ไวยากรณ์ที่น่าสนใจใหญ่มากด้วย ไวยากรณ์ดังกล่าวไม่ค่อยมีคุณสมบัติ LR(0) ในทางปฏิบัติ วิธีการที่อยู่ตรงกลางระหว่าง LR(0) และ LR(1) จะใช้กันทั่วไปมากกว่า ซึ่งเรียกว่า และ LALR(1)

1.2.2 LALR(1) ไวยากรณ์

ทั้งสองวิธีนี้มีพื้นฐานมาจากแนวคิดเดียวกัน ให้เราสร้างชุดของบัญญัติ LR(0) -state ของไวยากรณ์ ถ้าชุดนี้ไม่มีข้อขัดแย้ง ก็สามารถใช้ตัวแยกวิเคราะห์ LR(0) ได้ มิฉะนั้น เราจะพยายามแก้ไขข้อขัดแย้งที่เกิดขึ้นโดยพิจารณาจากสตริงล่วงหน้าที่มีอักขระตัวเดียว กล่าวอีกนัยหนึ่ง ลองสร้างตัวแยกวิเคราะห์ LR(1) ด้วยชุดของสถานะ LR(0)

วิธี LALR(1) (มองไปข้างหน้า) มีดังต่อไปนี้ ให้เราแนะนำความสัมพันธ์สมมูลในชุดของ LR(1) - สถานการณ์: เราจะพิจารณาสองสถานการณ์ที่เทียบเท่ากัน หากสถานการณ์ทั้งสองแตกต่างกันในสายโซ่ล่วงหน้าเท่านั้น ตัวอย่างเช่น สถานการณ์ A:Aa_Ab|e และ A:Aa_Ab|a นั้นเทียบเท่ากัน ให้เราสร้างชุดมาตรฐานของ LR(1)-state และรวมสถานะที่ประกอบด้วยชุดของสถานการณ์ที่เทียบเท่ากัน

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

2. การพัฒนานักแปล

2.1 การวิเคราะห์ความต้องการ

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

การออกแบบเครื่องวิเคราะห์คำศัพท์

การออกแบบเครื่องนิตยสาร

การใช้งานซอฟต์แวร์ของโปรแกรมแยกวิเคราะห์

การพัฒนาโมดูลการตีความ

การพัฒนาจะดำเนินการโดยใช้ระบบปฏิบัติการ Windows XP บนคอมพิวเตอร์ส่วนบุคคล ไอบีเอ็มคอมพิวเตอร์พีซีพร้อมโปรเซสเซอร์ อินเทล เพนเที่ยม IV.

ตามแนวโน้มการพัฒนาซอฟต์แวร์ ภาษาการเขียนโปรแกรม C# ในสภาพแวดล้อม Visual Studio 2010 ได้รับเลือกให้ใช้งานตัวแปลการฝึกอบรม

2.2 การออกแบบ

2.1.1 การออกแบบตัววิเคราะห์คำศัพท์

ศัพท์การวิเคราะห์รวมถึงการสแกนโปรแกรมแปล (ต้นฉบับ) และการจดจำคำศัพท์ที่ประกอบเป็นประโยคของข้อความต้นฉบับ โทเค็นรวมถึง โดยเฉพาะอย่างยิ่ง คำหลัก สัญญาณการดำเนินการ ตัวระบุ ค่าคงที่ อักขระพิเศษ ฯลฯ

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

lexeme สามารถอธิบายได้ด้วยคุณสมบัติหลักสองประการ หนึ่งในนั้นเป็นของ lexeme ของคลาสบางคลาส (ตัวแปร ค่าคงที่ การดำเนินการ ฯลฯ) แอตทริบิวต์ที่สองกำหนดองค์ประกอบเฉพาะของคลาสนี้

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

การดูตารางตัวระบุทำหน้าที่หลักสองประการ:

ก) เขียนชื่อใหม่ลงในตารางเมื่อประมวลผลการประกาศตัวแปร

b) ค้นหาชื่อที่บันทึกไว้ก่อนหน้านี้ในตาราง

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

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

ด้วยการเรียกใช้ตัววิเคราะห์คำศัพท์ เราจะแบ่งโปรแกรมออกเป็นโทเค็น หลังจากนั้นแต่ละโทเค็นจะผ่านการตรวจสอบความยาว (โทเค็นต้องมีความยาวไม่เกิน 11 อักขระ) เมื่อผ่านขั้นตอนนี้สำเร็จแล้ว เราจะตรวจสอบความถูกต้องของตำแหน่งของโทเค็น (คีย์เวิร์ด var, start, end, for, to, do, end_for) จากนั้นเราจะวิเคราะห์โทเค็นตัวแปร - ไม่ควรมีตัวเลขในคำอธิบายและทำซ้ำ ในขั้นตอนสุดท้าย เราตรวจสอบการสะกดโทเค็นที่ถูกต้อง (คีย์เวิร์ด ตัวระบุที่ไม่รู้จัก) หากการตรวจสอบอย่างน้อยหนึ่งรายการแสดงข้อผิดพลาด ตัววิเคราะห์คำศัพท์จะพิมพ์ข้อผิดพลาด

แผนผังของโปรแกรมการทำงานของตัววิเคราะห์คำศัพท์มีให้ในภาคผนวก B ในรูปที่ B.1

2.2.2 ออกแบบนิตยสารอัตโนมัติ

มากำหนดไวยากรณ์ต่อไปนี้:

G: (Vt, Va, I, R),

โดยที่ Vt คือเซตของสัญลักษณ์เทอร์มินัล Va คือเซตของสัญลักษณ์ที่ไม่ใช่เทอร์มินัล I คือสถานะเริ่มต้นของไวยากรณ์ R คือเซตของกฎไวยากรณ์

สำหรับไวยากรณ์นี้ เรากำหนดชุดของสัญลักษณ์เทอร์มินัลและไม่ใช่เทอร์มินัล:

มาเขียนกฎสำหรับไวยากรณ์ G ของเราและนำเสนอในตารางที่ 1

ตารางที่ 1 - กฎไวยากรณ์

หมายเลขกฎ

ด้านซ้ายของกฎ

ด้านขวาของกฎ

f ID = EX t EX d LE n;

ความต่อเนื่องของตารางที่ 1

หมายเลขกฎ

ด้านซ้ายของกฎ

ด้านขวาของกฎ

การกำหนด lexemes การแปล lexemes เป็นรหัสและรายการการกำหนดไวยากรณ์มีอยู่ในตาราง 2, 3, 4 ตามลำดับ

ตารางที่ 2 - สัญกรณ์ของ lexemes

สัญกรณ์ Lexem

คำหลัก "เริ่มต้น" (จุดเริ่มต้นของคำอธิบายของการกระทำ)

คำหลัก "สิ้นสุด" (สิ้นสุดคำอธิบายของการกระทำ)

คำหลัก "var" (การประกาศตัวแปร)

คำหลัก "อ่าน" (คำสั่งป้อนข้อมูล)

คำหลัก "เขียน" (คำสั่งเอาต์พุตข้อมูล)

คำหลัก "สำหรับ" (คำสั่งวนซ้ำ)

คำค้น "ถึง"

คำค้น "ทำ"

คำหลัก "end_case" (คำสั่งสิ้นสุดการวนซ้ำ)

ประเภทตัวแปร "จำนวนเต็ม"

การดำเนินการเพิ่มเติม

การดำเนินการลบ

การดำเนินการคูณ

ตัวคั่น ":"

อักขระตัวคั่น ";"

ตัวคั่น "("

อักขระคั่น ")"

อักขระคั่น ","

สัญกรณ์ Lexem

ตัวคั่น "="

ตารางที่ 3 - การแปล lexemes เป็นรหัส

<цифра>

<буква>

ตารางที่ 4 - รายการสัญลักษณ์ไวยากรณ์

การกำหนด

คำอธิบาย

โปรแกรม

คำอธิบายของการคำนวณ

คำอธิบายของตัวแปร

รายการตัวแปร

โอเปอเรเตอร์

งานที่มอบหมาย

การแสดงออก

การแสดงออกย่อย

การดำเนินการไบนารี

การดำเนินการแบบเอกนารี

รายการมอบหมาย

ตัวระบุ

คงที่

ให้เราสร้างตัวจำแนกจากน้อยไปมากที่กำหนดขึ้น

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

ก) หากมีสัญลักษณ์กลุ่ม B ที่สตริง AB รวมอยู่ในกฎไวยากรณ์บางข้อและมีสัญลักษณ์ xPERV "(B) เราจะสมมติว่าระหว่างสัญลักษณ์ x และ A ความสัมพันธ์ x หลัง A ถูกกำหนด

b) หากในไวยากรณ์ที่กำหนดมีกฎ B-\u003e bAb A, BV a ดังนั้นระหว่าง A และ x ความสัมพันธ์ A CONVERT x จะถูกกำหนด

ไวยากรณ์ทั้งหมดของเรายังคงเหมือนเดิม นั่นคือ:

G: (Vt, Va, I, R),

และกฎไวยากรณ์ D แสดงไว้ในตารางที่ 5

ตารางที่ 5 - กฎไวยากรณ์

หมายเลขกฎ

ด้านซ้ายของกฎ

ด้านขวาของกฎ

f ID = EX t EX d LE n;?

ความต่อเนื่องของตารางที่ 5

หมายเลขกฎ

ด้านซ้ายของกฎ

ด้านขวาของกฎ

ที่ไหน? - เครื่องหมายสำหรับปลายโซ่

ลองกำหนดบางกรณี:

ก) ID ประกอบด้วยตัวอักษรหลายตัว ตัวอักษรละตินนั่นคือ เราถือว่า u = ( a, b, c, d, e, f,g, h, i,j,k, l,m, n, o, p,q,r,s, t, คุณ, โวลต์, ว, x, y, z)

b) ค่าคงที่ CO ประกอบด้วยตัวเลข นั่นคือ เราจะถือว่า k = (0,1,2,3,4,5,6,7,8,9)

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

ก) ไม่มีกฎอิเล็กทรอนิกส์

b) มีกฎเกณฑ์ที่ x หลัง A หรือไม่? แปลง x = ?

ค) A -> โดยYg

และจำเป็นที่หลังจาก x? ในการแปลง x = ?

เช่น ในไวยากรณ์จะดำเนินการในหลังจาก x หรือ A หลังจาก x โดยที่ x คือเพรดิเคตสัญลักษณ์ของห่วงโซ่ b

ก) PERV "(PG) \u003d (PG?)

PRIM"(RG) = PRIM(DE) = (RG, v,:, ผม,;)

พริม" (AL) = พริม (b LE e)= (AL, b, e)

PERV" (DE) = PERV (v LV: i;) = (DE, v,:, i,;)

PERV" (LV) = PERV (ID, LV) = ( LV, ID )

PERV" (OP) =(OP, ID, CO)

PERV" (EQ) = PERV(ID = EX;) = (EQ, =,;)

PERV" (EX) = (EX, SB, -)

PERV" (BO) = (B0, +,*,-)

FIRST" (SB) = FIRST((EX)SB) ? FIRST(OP) ? FIRST(VO)=(SB, (,), OP, BO);

PERV" (LE) = PERV(EQ) = (LE, (,), =,;, f, t, d, n, w, r)

PERV" (UO) = (ยูโอ,-)

PERV" (ID)= PERV" (u) = (u)

PERV" (CO) = PERV" (k) = (k)PERV" (e) =( อี)

PERV" (ข) =( ข)

PERV" (จ) =( จ)

PERV" (วี) =( วี)

เพอร์วี" (w) =( w)

เพอร์วี" (r) =( r)

PERV" (i) =(i)

PERV" (ฉ) =( ฉ)

PERV" (ง) = (ง)

PERV" (น) =( น)

PERV" (ค) =( ค)

เพอร์วี" (+) =( +)

เพอร์ฟ" (*) =( *)

เพอร์วี" (-) = (-)

เพอร์วี" (,) =(,)

เพอร์วี" (;) =(;)

เพอร์ฟ" (:) =(:)

เพอร์วี" (=) = ( = )

เพอร์วี" (() =( ()

เพอร์วี" ()) =() )

PERV" (คุณ) = (คุณ)

PERV" (k) = (k)

b) NEXT `(AL) = (?)?NEXT"(PG)=(?,b,e)

NEXT ` (DE) = (?)?PRIM"(AL)= (?, b, e )

NEXT ` (LV) = (?)?PRIM"(:)= (?,:)

NEXT ` (OP) = (?)?PRIM"(SB)= (?,;,), d, t, +, -, *)

NEXT ` (EQ) = (?)?FIRST"(LE)=(?, (,),;, f, =, t, d, n,w,r )

NEXT ` (EX) = (?)?PRIM"(t)?PRIM"(d)?PRIM"(;)?PRIM"())=(?, t,d,;,))

NEXT ` (BO) = (?)?FIRST"(SB)= (?, (,), OP, BO)

NEXT ` (UO) = (?)?PRIM"(SB)= (?, (,), OP, BO)

NEXT ` (SB) = (?)?NEXT"(EX)= (?, t,d,;,), +, *, -)

ถัดไป ` (LE) = (?) ?PRIM"(e) ?PRIM"(n) = (?, e, n)

ถัดไป `(ID)=(?)? ถัดไป" (OP) ? FIRST" (=) =(?,;,), d, t, +, -, *, =)

ถัดไป `(CO) = (?)? ถัดไป" (OP)= (?,;,), d, t, +, -, *, =)

NEXT ` (b) =(?)?PRIM"(LE)= (?, u, =,;)

NEXT ` (e) =(?)?NEXT"(AL)= (?, b)

NEXT ` (v) =(?)?PRIM"(LV)= (?, คุณ )

ถัดไป ` (w) =(?)?PRIM"(()= (?, ()

ถัดไป ` (r) =(?)?PRIM"(() = (?, ()

ถัดไป ` (i) =(?)?PRIM"(;)= (?,; )

NEXT ` (f) =(?)?PRIM"(ID) = (?, u)

ถัดไป ` (d) =(?)?PRIM"(LE)= (?, u, =,;)

ถัดไป ` (n) =(?)?PRIM"(i) = (?, i )

ถัดไป ` (+) = (?)?ถัดไป"(IN) = (?, +,*,-)

ถัดไป ` (-) = (?)?ถัดไป"(IN) = (?, +,*,-)

ถัดไป ` (*) = (?)?ถัดไป"(IN) = (?, +,*,-)

NEXT ` (;) =(?)?NEXT" (DE)?NEXT `(LE1)?NEXT" (EQ) = (?, b, e, l, u )

NEXT ` (:) =(?)?PRIM"(i)= (?, i )

ถัดไป ` (=) = (?)?FIRST"(EX) = (? (,), u, k, +, -, *)

ถัดไป ` (() = (?)?PRIM"(DE)= (?, v,:, ฉัน,;)

ถัดไป ` ()) = (?)? PERV"(;) = (?,; )

ถัดไป ` (,) = (?)? PERV"(LV) = (?, คุณ)

ถัดไป `(คุณ)=(?)? PERV" (ID)= ( คุณ, ?)

ถัดไป `(k)=(?)? PERV (CO)= (?, k)

ค) PG -> เดอัล

AL หลัง DE = (b,e) หลัง DE = ((b DE), (e DE) )

e หลังจาก LE = ((e LE))

LE หลัง b = ((,), =,;, f, t, d, n, w, r) หลัง b = (((b), ()b), (=b), (;b), ( f b), (t b), (d b), (n b), (w b), (r b))

;หลังจาก i = ((; i))

ฉันหลังจาก: = ( (i:) )

: หลัง LV = ( ( : LV) )

LV หลัง v = ( (ID, v) )

LV หลัง = ((ID,))

หลังจาก ID = ((,u))

LE หลัง EQ = ((,), =,;, f, t, d, n, w, r ) หลัง EQ = (((EQ), () EQ), (= EQ), (; EQ), ( f EQ), (t EQ), (d EQ), (n EQ), (w EQ), (r EQ))

LE -> r (ดีอี);

; หลัง) = ((;)))

) หลัง DE = (((DE))

หลังจาก (= (= ((v)), (:)), (i)), (;)), (e)))

(หลังจาก r = (((r))

LE -> w (ดีอี);

; หลัง) = ((;)))

) สุดท้าย DE = (((DE))

DE หลังจาก (= ((v)), (:)), (i)), (;)), (e)))

(หลังจาก w = (((w))

LE -> f ID = EX t EX d LE n;

; หลัง n = ((;n))

n หลัง LE = ( (n, LE))

LE หลัง d = ( ((,), =,;, f, t, d, n, w, r)) ? หลัง d = (((d), ()d), (;d), (f d), (t d), (d d), (n d), (w d), (r d))

d หลัง EX = ((d, EX))

EX หลัง t = (BO, -) ? หลังจาก เสื้อ = ((BO เสื้อ), (- เสื้อ))

เสื้อ หลัง EX = ( เสื้อ EX)

เช่น หลัง == ((BO, -) ? หลัง == ((BO=), (-=))

หลังจาก ID=((=ID))

ID หลัง f = ((ID f))

EQ -> ID = EX;

; หลังจาก EX = ((; EX )

EX หลัง == (BO, -) ? หลัง == ((BO=), (-=))

หลังจากคุณ = ( (= คุณ))

SB หลัง UO = ( (,), OP, BO ) หลัง UO = (((UO), (OP UO), (BO UO) )

) หลัง EX = ( ()EX) )

EX หลัง (= (BO, -) ? หลัง (= ((BO (), (- ())

SB->SB BO SB

SB หลัง BO = ((,), OP, BO) หลัง BO = (((BO), ()BO), (OP BO), (BO BO))

BO หลัง SB = (+,*,-) หลัง SB = ((+SB), (*SB), (-SB))

ID หลัง u = ((u, u))

ช) PG ->เด อัล

AL ROLL PG = AL ROLL NEXT" (PG) = ((อัล ?))

e ROLL AL = e ROLL NEXT"(AL)= ((eb), (e?))

=; พับถัดไป"(DE) = ((;b), (;?))

LV FLOW LV = LV FLOW NEXT" (LV) = ((LV:), (LV?))

ID ROLL LV = ID ROLL NEXT" (LV) = ((ID:), (ID ?))

; แปลง LE=; พับถัดไป" (LE) = ((; e), (;?), (;n))

LE -> f ID = EX t EX d LE n;

; แปลง LE=; พับถัดไป" (LE) = ((; e), (;?), (;n))

EQ ROLL LE = EQ ROLL NEXT" (LE) = ((EQ อี), (EQ?), (EQ n))

EQ -> ID = EX;

; แปลง EQ=; พับถัดไป" (EQ) = ((; (), (;)), (;;), (;f), (;?), (;=), (;t), (;d), (; น), (;w), (;r))

SB ROLL EX = SB ROLL NEXT" (EX) = ((SB t), (SB?), (SB d), (SB)), (SB;), (SB(), (SB=), (SBf ), (SBn), (SBw), (SBr) )

) SB ROLL = SB NEXT ROLL" (SB) = (() t), ()?), () d), ())), ();))

OP ROLL SB = OP ROLL NEXT" (SB) = ((OP t), (OP ?), (OP d), (OP)), (OP;))

SB->SB BO SB

SB ROLL SB = SB ROLL NEXT" (SB) = ((SB, t), (SBd), (SB;) (SB)), (SB+), (SB-), (SB*), (SB? ) }

ม้วน UO = - ม้วนถัดไป" (UO) = ( (-?), (--))

ม้วน BO = + ม้วนถัดไป" (BO) = ((++), (+?), (+*), (+-))

* ROLL BO = * ROLL NEXT" (BO) = ((*+), (*?), (**), (*-))

ROLL BO = - ม้วนถัดไป" (BO) = ((-+), (-?), (-*), (--))

ID ROLL OP = ID ROLL NEXT" (OP) = ((ID+), (ID?), (ID*), (ID-))

CO FOLD OP = CO FOLD NEXT" (OP) = ((CO+), (CO?), (CO*), (CO-), (CO;), (COd), (COt), (CO)))

ID ROLL ID = ID ROLL NEXT" (ID) = ((ID)), (ID ?), (ID k), (ID+), (ID-), (ID*), (ID=), (IDt) , (IDd)))

u ROLL ID = l ROLL NEXT" (ID) = ((u)), (u?), (uk), (u+), (u-), (u*), (u=), (ut), (อู๊ด)))

CO ROLL CO = CO ROLL NEXT" (CO) = (CO+), (CO?), (CO*), (CO-), (CO;), (COd), (COt), (CO)))

k ROLL CO = k ROLL NEXT" (CO) = (k+), (k?), (k*), (k-), (k;), (kd), (kt), (k)))

พบสถานการณ์ความขัดแย้งหนึ่งเมื่อพับกฎ

OP ->ID และ ID -> u ID

เราป้อน ID1 -> ID ดังนั้นเราจึงเขียนกฎใหม่ ID1 -> u ID

ดังนั้นเราจะดำเนินการบิด

ID1 ROLL ID = ID1 ROLL NEXT" (ID) = ((ID1)), (ID1 ?), (ID1 k), (ID1+), (ID1-), (ID1*), (ID1=), (ID1t) , (ID1d)))

สำหรับแต่ละคู่ (x, A)? x หลังจาก A เราสร้างฟังก์ชั่นการเปลี่ยนแปลงที่กำหนดการดำเนินการโอน ?? (S 0, x, A) \u003d (S 0, A)

? (S0, b, DE) = (S0, DEb)

? (S0, e, DE) = (S0, DEe)

? (S0, e, LE) = (S0, LEe)

? (S0,), ข) = (S0, ข))

? (S0,;, b) = (S0, ข;)

? (S0, (, ข) = (S0, ข()

? (S0, =, ข) = (S0, ข=)

? (S0, f, b) = (S0, bf)

? (S0, t, b) = (S0, bt)

? (S0, d, b) = (S0, bd)

? (S0, n, b) = (S0, พันล้าน)

? (S0, w, b) = (S0, bw)

? (S0, r, b) = (S0, br)

? (S0,;, ผม) = (S0, ผม;)

? (S0, ผม, :) = (S0, ผม :)

? (S0,:LV) = (S0,LV:)

? (S0, รหัส, v) = (S0, vID)

? (S0,รหัส,) = (S0,รหัส)

? (S0, คุณ) = (S0, คุณ,)

? (S0, (, EQ)= (S0, EQ()

? (S0,), EQ)= (S0, EQ))

? (S0, =, EQ)= (S0, EQ=)

? (S0,;, EQ)= (S0, EQ;)

? (S0, f, EQ)= (S0, EQf)

? (S0, t, EQ)= (S0, EQt)

? (S0, d, EQ)= (S0, EQd)

? (S0, n, EQ)= (S0, EQn)

? (S0, w, EQ)= (S0, EQw)

? (S0, r, EQ)= (S0, EQr)

? (S0,;,)) = (S0,);)

? (S0, (, DE) = (S0, DE()

? (S0,v)) = (S0,)v)

? (S0,;,)) = (S0,);)

? (S0,i,)) = (S0,)i)

? (S0,:,)) = (S0,):)

? (S0,จ,)) = (S0,)จ)

? (S0, (, r) = (S0, r()

? (S0, (, w) = (S0, w()

? (S0,;, n) = (S0, n;)

? (S0, n, LE) = (S0, LEn)

? (S0, (, ง) = (S0, ง()

? (S0,), ง) = (S0, ง))

? (S0,;, ง) = (S0, ง;)

? (S0, f, d) = (S0, df)

? (S0, เสื้อ, ง) = (S0, dt)

? (S0, d, d) = (S0, dd)

? (S0, n, d) = (S0, dn)

? (S0, w, d) = (S0, dw)

? (S0, r, d) = (S0, dr)

? (S0, d, EX) = (S0, EXd)

? (S0, BO, เสื้อ) = (S0, tBO)

? (S0, -, เสื้อ) = (S0, เสื้อ-)

? (S0, เสื้อ, EX) = (S0, EXt)

? (S0, BO, =) = (S0, =BO)

? (S0, -, =) = (S0, =-)

? (S0, =, ID) = (S0, ID=)

? (S0, ID, f) = (S0, fID)

? (S0,;, EX) = (S0, EX;)

? (S0, =, ยู) = (S0, ยู=)

? (S0, (, UO) = (S0, ยูโอ()

? (S0, OP, UO) = (S0, UO OP)

? (S0, BO, UO) = (S0, UO บ่อ)

? (S0,), EX) = (S0, EX))

? (S0, BO, () = (S0, (BO)

? (S0, BO, -) = (S0, -BO)

? (S0, (, BO) = (S0, BO()

? (S0,),BO) = (S0,)BO)

? (S0, OP, BO) = (S0, BOOP)

? (S0, +, SB) = (S0, SB+)

? (S0, *, SB) = (S0, SB*)

? (S0, -, SB) = (S0, SB-)

? (S0, คุณ, คุณ) = (S0, คุณ)

สำหรับแต่ละคู่ (x, A)? และ CONVULT x สร้างฟังก์ชันทรานซิชันที่กำหนดการกระทำของคอนโวลูชั่น?? * (S 0, x, bA) \u003d (S 0, B) โดยที่ B-> bA

? * (S 0 , อัล ?) = (S 0 , PG)

? * (S 0 , จ , ข) = (S 0 , AL)

? * (S 0 , n, ?) = (S 0 , อัล)

? * (ส 0 ,;, ข) = (ส 0 , DE)

? * (ส 0 ,;, ?) = (ส 0 , เด)

? * (S 0 ,;, จ) = (S 0 , DE)

? * (S 0 , LV, :) = (S 0 , LV)

? * (S 0 , LV, ?) = (S 0 , LV)

? * (S 0 , รหัส ?) = (S 0 , LV)

? * (S 0 , ID, จ) = (S 0 , LV)

? * (S 0 ,;, จ) = (S 0 , LE)

? * (S 0 ,;, ?) = (S 0 , LE)

? * (S 0 ,;, n) = (S 0 , LE)

? * (S 0 , EQ, n) = (S 0 , LE)

? * (S 0 , EQ, จ) = (S 0 , LE)

? * (S 0 , EQ, ?) = (S 0 , LE)

? * (S 0 ,;, จ) = (S 0 , LE)

? * (S 0 ,;, ?) = (S 0 , LE)

? * (ส 0 ,;, () = (ส 0 , EQ)

? * (S 0 ,;,)) = (S 0 , EQ)

? * (ส 0 ,;, ฉ) = (ส 0 , EQ)

? * (ส 0 ,;, =) = (ส 0 , EQ)

? * (S 0 ,;, เสื้อ) = (S 0 , EQ)

? * (S 0 ,;, ง) = (S 0 , EQ)

? * (S 0 ,;, n) = (S 0 , EQ)

? * (ส 0 ,;, w) = (ส 0 , EQ)

? * (S 0 ,;, r) = (S 0 , EQ)

? * (S 0 , SB, ?) = (S 0 , EX)

? * (S 0 , SB, ง) = (S 0 , EX)

? * (S 0 , SB,)) = (S 0 , EX)

? * (S 0 , SB,;) = (S 0 , EX)

? * (S 0 , SB, w) = (S 0 , EX)

? * (S 0 , SB, r) = (S 0 , EX)

? * (S 0 , SB, f) = (S 0 , EX)

? * (S 0 , SB, =) = (S 0 , EX)

? * (S 0 , SB, เสื้อ) = (S 0 , EX)

? * (S 0 , SB, ?) = (S 0 , SB)

? * (S 0 , SB, () = (S 0 , SB)

? * (S 0 , SB,)) = (S 0 , SB)

? * (S 0 , SB, คุณ) = (S 0 , SB)

? * (S 0 , SB, k) = (S 0 , SB)

? * (S 0 , SB, +) = (S 0 , SB)

? * (S 0 , SB, -) = (S 0 , SB)

? * (S 0 , SB, *) = (S 0 , SB)

? * (S 0 , SB, จ) = (S 0 , SB)

? * (S 0 ,), เสื้อ) = (S 0 , SB)

? * (ส 0 ,) ?) = (ส 0 , SB)

? * (S 0 ,), เสื้อ) = (S 0 , SB)

(ส 0 ,))) = (ส 0 , SB)

? * (S 0 ,),;) = (S 0 , SB)

? * (ส 0 , -, ?) = (ส 0 , UO)

? * (ส 0 , -, -) = (ส 0 , UO)

? * (S 0 , +, +) = (S 0 , โบ)

? * (S 0 , +, ?) = (S 0 , BO)

? * (S 0 , +, *) = (S 0 , โบ)

? * (S 0 , -, +) = (S 0 , โบ)

? * (S 0 , -, ?) = (S 0 , BO)

? * (S 0 , -, *) = (S 0 , โบ)

? * (S 0 , -, -)) = (S 0 , BO)

? * (S 0 , *, +) = (S 0 , โบ)

? * (S 0 , *, ?) = (S 0 , BO)

? * (S 0 , *, *) = (S 0 , โบ)

? * (S 0 , *, -)) = (S 0 , BO)

? * (S 0 , คุณ, +) = (S 0 , BO)

? * (S 0 , คุณ , ?)= (S 0 , BO)

? * (S 0 , คุณ, *) = (S 0 , BO)

? * (S 0 , คุณ, -)) = (S 0 , BO)

? * (S 0 , k, +) = (S 0 , BO)

? * (S 0 , k , ?) = (S 0 , BO)

? * (S 0 , k, *) = (S 0 , BO)

? * (S 0 , k, -)) = (S 0 , BO)

? * (S 0 , CO , ?) = (S 0 , OP)

? * (S 0 , CO, +) = (S 0 , OP)

? * (S 0 , CO, *) = (S 0 , OP)

? * (S 0 , CO, -) = (S 0 , OP)

? * (S 0 , CO ,;) = (S 0 , OP)

? * (S 0 , CO, ง) = (S 0 , OP)

? * (S 0 , CO, เสื้อ) = (S 0 , OP)

? * (S 0 , ID, -) = (S 0 , OP)

? * (S 0 , ID, *) = (S 0 , OP)

? * (S 0 , รหัส ?) = (S 0 , OP)

? * (S 0 , ID, () = (S 0 , OP)

? * (S 0 , ID,)) = (S 0 , OP)

? * (S 0 , ID, u) = (S 0 , OP)

? * (S 0 , ID, k) = (S 0 , OP)

? * (S 0 , ID, -) = (S 0 , OP)

? * (S 0 , ID, +) = (S 0 , OP)

? * (S 0 , คุณ,)) = (S 0 , I OP)

? * (S 0 , ID1, *) = (S 0 , ID)

? * (S 0 , ID1, ?) = (S 0 , ID)

? * (S 0 , ID1, () = (S 0 , ID)

? * (S 0 , ID1,)) = (S 0 , ID)

? * (S 0 , ID1, u) = (S 0 , ID)

? * (S 0 , ID1, k) = (S 0 , ID)

? * (S 0 , ID1, -) = (S 0 , ID)

? * (S 0 , ID1, +) = (S 0 , ID)

? * (S 0 , คุณ,)) = (S 0 , ID)

? * (S 0 , คุณ , ?) = (S 0 , BO)

? * (S 0 , คุณ, k) = (S 0 , ID)

? * (S 0 , คุณ, *)) = (S 0 , ID)

? * (S 0 , คุณ, -)) = (S 0 , ID)

? * (S 0 , คุณ, +)) = (S 0 , ID)

? * (S 0 , u, d)) = (S 0 , ID)

? * (S 0 , u, t)) = (S 0 , ID)

? * (S 0 , คุณ, =)) = (S 0 , ID)

? * (S 0 , CO , ?) = (S 0 , CO)

? * (S 0 , CO, +) = (S 0 , CO)

? * (S 0 , CO, -) = (S 0 , CO)

? * (S 0 , CO, *) = (S 0 , CO)

? * (S 0 , CO ,;) = (S 0 , CO)

? * (S 0 , CO, ง) = (S 0 , CO)

? * (S 0 , CO, เสื้อ) = (S 0 , CO)

? * (S 0 , CO,)) = (S 0 , CO)

? * (S 0 , k, +) = (S 0 , CO)

? * (S 0 , k, -) = (S 0 , CO)

? * (S 0 , k, *) = (S 0 , CO)

? * (S 0 , k ,;) = (S 0 , CO)

?? * (S 0 , k, d) = (S 0 , CO)

? * (S 0 , k, เสื้อ) = (S 0 , CO)

? * (S 0 , k,)) = (S 0 , CO)

? * (S 0 , k, () = (S 0 , CO)

2.2.3 การใช้งานซอฟต์แวร์ของ parser

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

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

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

รอบการทำงานของเครื่องผลักดึงโดยไม่ต้องอ่านสัญลักษณ์อินพุต (รอบเปล่า);

วัฏจักรของออโตเมตันแบบผลักและดึงพร้อมการอ่านสัญลักษณ์อินพุต

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

แบบแผนของโปรแกรมงาน parser มีให้ในภาคผนวก B ในรูปที่ B.2

2.2.4 การพัฒนาโมดูลการตีความ

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

ลองพิจารณาหลักการพื้นฐานของการสร้างและการดำเนินการของรูปแบบนิพจน์ที่ลงท้ายด้วย

กฎพื้นฐานสำหรับการแปลงสัญกรณ์ infix ของ expression เป็น postfix มีดังต่อไปนี้

ตัวถูกดำเนินการอ่านจะถูกเพิ่มลงในสัญกรณ์ postfix การดำเนินการจะถูกผลักไปยังสแต็ก

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

วงเล็บเปิดอ่านถูกผลักเข้าไปในสแต็ก

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

หลังจากอ่านนิพจน์ทั้งหมดแล้ว การดำเนินการที่เหลืออยู่บนสแต็กจะถูกเพิ่มไปยังรายการ postfix

สัญกรณ์ postfix ของนิพจน์ช่วยให้สามารถประเมินได้ด้วยวิธีต่อไปนี้

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

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

รูปแบบการทำงานของล่ามมีให้ในภาคผนวก B ในรูปที่ B.3

2.3 การเข้ารหัส

โปรแกรมนี้ใช้งานในภาษา C# ในสภาพแวดล้อมการเขียนโปรแกรม Visual Studio 2010 ข้อความของโปรแกรมแสดงในภาคผนวก A

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

วัตถุประสงค์ของขั้นตอนและฟังก์ชันที่ใช้งานในโปรแกรมได้อธิบายไว้ในตาราง 6,7,8

ตารางที่ 6 - วัตถุประสงค์ของขั้นตอนและหน้าที่ของการวิเคราะห์คำศัพท์

เอกสารที่คล้ายกัน

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

    ภาคนิพนธ์ เพิ่ม 08/06/2013

    การออกแบบตัววิเคราะห์คำศัพท์และการแยกวิเคราะห์ สอนภาษา. กฎสำหรับการแปลงนิพจน์เชิงตรรกะเป็น POLIZ การก่อตัวของ triads การเพิ่มประสิทธิภาพของรายการ โครงสร้างเชิงตรรกะของโปรแกรม การทดสอบโมดูลนักแปล-ล่าม

    ภาคนิพนธ์ เพิ่ม 05/28/2013

    ลักษณะทั่วไปและการประเมินความสามารถของภาษาโปรแกรม C-sharp ความเหมือนและความแตกต่างจาก C ++ และ Java การพัฒนาด้วยความช่วยเหลือของภาษาการเขียนโปรแกรมของคำศัพท์และตัวแยกวิเคราะห์ การรวบรวมสเปรดชีต

    ภาคนิพนธ์ เพิ่ม 06/11/2010

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

    ภาคนิพนธ์ เพิ่ม 06/14/2010

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

    ภาคนิพนธ์ เพิ่ม 02/23/2012

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

    ภาคนิพนธ์ เพิ่ม 03/19/2012

    โครงสร้าง การจัดประเภท และข้อกำหนดในการใช้งานคอมไพเลอร์ การออกแบบและการใช้งานส่วนการวิเคราะห์ของคอมไพเลอร์ C++ วิธีการใช้การวิเคราะห์คำศัพท์ อัลกอริทึมของ parser หลักการใช้งานซอฟต์แวร์

    ภาคนิพนธ์ เพิ่ม 01/26/2013

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

    ภาคนิพนธ์ เพิ่ม 07/02/2554

    วิธีการวิเคราะห์ทางไวยากรณ์ การพัฒนาโครงสร้างของตัวแปลการศึกษาในภาษาโปรแกรมพื้นฐาน Object Pascal ในสภาพแวดล้อมของการเขียนโปรแกรมเชิงภาพเชิงวัตถุ Borland DELPHI 6.0 โดยใช้ระบบปฏิบัติการ Windows XP

    ภาคนิพนธ์ เพิ่ม 05/12/2013

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

คอมพิวเตอร์แต่ละเครื่องมีภาษาโปรแกรมของตนเอง - ภาษาคำสั่งหรือภาษาเครื่อง - และสามารถรันโปรแกรมที่เขียนด้วยภาษานั้นเท่านั้น โดยหลักการแล้วการใช้ภาษาเครื่องสามารถอธิบายอัลกอริทึมใด ๆ ได้ แต่ต้นทุนการเขียนโปรแกรมจะสูงมาก นี่เป็นเพราะความจริงที่ว่าภาษาเครื่องอนุญาตให้คุณอธิบายและประมวลผลเฉพาะโครงสร้างข้อมูลดั้งเดิม - บิต, ไบต์, คำ การเขียนโปรแกรมด้วยรหัสเครื่องจำเป็นต้องมีรายละเอียดของโปรแกรมที่มากเกินไป และมีให้สำหรับโปรแกรมเมอร์ที่รู้จักการออกแบบและการทำงานของคอมพิวเตอร์เป็นอย่างดีเท่านั้น เพื่อเอาชนะความยากลำบากนี้และอนุญาตให้ใช้ภาษาระดับสูง (Fortran, PL / 1, Pascal, C, Ada และอื่น ๆ ) ด้วยโครงสร้างข้อมูลที่พัฒนาขึ้นและวิธีการประมวลผลโดยไม่ขึ้นกับภาษาของคอมพิวเตอร์เครื่องใดเครื่องหนึ่ง

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

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

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

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

หากใช้ภาษากลางเป็นภาษาวัตถุ ก็เป็นไปได้สองตัวเลือกสำหรับการสร้างตัวแปล

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

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

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

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

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

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

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


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

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

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

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

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

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

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

ข้าว. 1.1. รูปแบบการทำงานที่เรียบง่ายของนักแปล

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

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

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

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

เป้าหมายและวัตถุประสงค์ของระเบียบวินัย

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

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

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

วัตถุประสงค์ของระเบียบวินัย: เพื่อให้ความรู้เกี่ยวกับพื้นฐานของทฤษฎีภาษาและไวยากรณ์ที่เป็นทางการ, ทฤษฎีของออโตมาตา, วิธีการพัฒนานักแปล

เพื่อให้บรรลุเป้าหมายนี้ในหลักสูตรการสอนระเบียบวินัย งานต่อไปนี้จะได้รับการแก้ไข:

  1. ในระหว่างหลักสูตรการบรรยาย จะพิจารณาหลักการทั่วไปขององค์กรของกระบวนการแปลและโครงสร้างของนักแปล มีการศึกษาพื้นฐานของทฤษฎีการสร้างตัวแปล
  2. ในห้องปฏิบัติการและระหว่าง งานอิสระมีการรวมความรู้ทางทฤษฎีที่ได้รับในทางปฏิบัติ: นักแปลสำหรับภาษาโปรแกรมอย่างง่ายกำลังได้รับการพัฒนา

แนวคิดพื้นฐานและคำจำกัดความ

คำจำกัดความที่พิจารณาส่วนใหญ่ยืมมาจาก [ARNFTS อังกฤษ-รัสเซีย-เยอรมัน-ฝรั่งเศส พจนานุกรมคอมพิวเตอร์และการประมวลผลข้อมูล 4132 เงื่อนไข ภายใต้. เอ็ด อ. โดรอดนิทซิน. ม.: 2521. 416 น.) ].

นักแปล - โปรแกรมบริการซึ่งแปลงซอร์สโปรแกรมที่มีให้ในภาษาโปรแกรมอินพุตเป็นโปรแกรมการทำงานที่มีให้ในภาษาอ็อบเจกต์.

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

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

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

คอมไพเลอร์ - เป็นโปรแกรมยูทิลิตี้ที่แปลเป็นภาษาเครื่องซึ่งเป็นโปรแกรมที่เขียนด้วยภาษาโปรแกรมต้นทาง. เช่นเดียวกับแอสเซมเบลอร์ คอมไพเลอร์จะแปลงโปรแกรมจากภาษาหนึ่งเป็นอีกภาษาหนึ่ง (ส่วนใหญ่มักจะเป็นภาษาของคอมพิวเตอร์เครื่องหนึ่งๆ) อย่างไรก็ตาม คำสั่งภาษาต้นทางแตกต่างกันอย่างมากในองค์กรและอำนาจจากคำสั่งภาษาเครื่อง มีภาษาที่แปลหนึ่งคำสั่งของภาษาต้นทางเป็น 7-10 คำสั่งเครื่อง อย่างไรก็ตาม ยังมีภาษาที่แต่ละคำสั่งสามารถสอดคล้องกับคำสั่งเครื่องตั้งแต่ 100 คำสั่งขึ้นไป (เช่น Prolog) นอกจากนี้ ในภาษาต้นทางมักใช้การพิมพ์ข้อมูลที่เข้มงวด ซึ่งดำเนินการผ่านคำอธิบายเบื้องต้น การเขียนโปรแกรมอาจไม่อาศัยการเข้ารหัสอัลกอริทึม แต่ใช้ความคิดอย่างรอบคอบเกี่ยวกับโครงสร้างข้อมูลหรือคลาส กระบวนการแปลจากภาษาดังกล่าวมักเรียกว่าการคอมไพล์ และภาษาต้นทางมักเรียกว่าภาษาโปรแกรมระดับสูง (หรือภาษาระดับสูง) การแยกภาษาการเขียนโปรแกรมออกจากระบบคำสั่งของคอมพิวเตอร์นำไปสู่การสร้างภาษาที่หลากหลายโดยอิสระโดยมุ่งเน้นที่การแก้ปัญหาเฉพาะ ภาษาที่ปรากฏสำหรับการคำนวณทางวิทยาศาสตร์ การคำนวณทางเศรษฐศาสตร์ การเข้าถึงฐานข้อมูล และอื่นๆ

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

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

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

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

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

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

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

มาโครโปรเซสเซอร์ยังใช้กับภาษาระดับสูง เพิ่มการทำงานของภาษาต่างๆ เช่น PL/1, C, C++ มาโครโปรเซสเซอร์ใช้กันอย่างแพร่หลายใน C และ C++ ทำให้ง่ายต่อการเขียนโปรแกรม ตัวอย่างของการใช้มาโครโปรเซสเซอร์อย่างแพร่หลายคือไลบรารีคลาส Microsoft Foundation Classes (MFC) จะใช้แมปข้อความและอื่นๆ ผ่านแมโครแทรก วัตถุโปรแกรม. ในเวลาเดียวกัน มาโครโปรเซสเซอร์จะเพิ่มประสิทธิภาพในการเขียนโปรแกรมโดยไม่เปลี่ยนไวยากรณ์และความหมายของภาษา

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

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

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

คุณสมบัติทั่วไปของภาษาโปรแกรมและตัวแปล

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

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

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

ความหมายของภาษาการเขียนโปรแกรมแตกต่างกันไปในวงกว้างมาก พวกเขาไม่เพียง แต่แตกต่างกันในการดำเนินการเฉพาะของการดำเนินงานแต่ละรายการเท่านั้น แต่ยังรวมถึงกระบวนทัศน์การเขียนโปรแกรมที่กำหนดความแตกต่างพื้นฐานในวิธีการพัฒนาโปรแกรม ลักษณะเฉพาะของการดำเนินงานอาจเกี่ยวข้องกับทั้งโครงสร้างของข้อมูลที่ประมวลผลและกฎสำหรับการประมวลผลประเภทข้อมูลเดียวกัน ภาษาต่างๆ เช่น PL/1 และ APL รองรับการทำงานของเมทริกซ์และเวกเตอร์ ภาษาส่วนใหญ่ทำงานกับสเกลาร์เป็นหลัก โดยมีขั้นตอนและฟังก์ชันที่เขียนโดยโปรแกรมเมอร์เพื่อจัดการกับอาร์เรย์ แต่ถึงแม้จะดำเนินการเพิ่มจำนวนเต็มสองจำนวน ภาษาเช่น C และ Pascal ก็สามารถทำงานแตกต่างกันได้

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

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

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

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

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

อย่างเป็นทางการ โปรแกรม X ที่ถูกต้องแต่ละรายการคือสตริงของสัญลักษณ์จากตัวอักษร A บางตัวที่แปลงเป็นสตริง Y ที่สอดคล้องกัน ประกอบด้วยสัญลักษณ์ของตัวอักษร B

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

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

เรียกความสัมพันธ์ระหว่างโครงสร้างโปรแกรมกับภาษาโปรแกรม การทำแผนที่วากยสัมพันธ์.

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

ในภาษาโปรแกรมส่วนใหญ่ นิพจน์นี้กำหนดลำดับชั้นของอ็อบเจกต์โปรแกรมที่สามารถแสดงเป็นแผนผัง (รูปที่ 1.1.):

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

<выражение> ::= <слагаемое> | <выражение> + <слагаемое>

<слагаемое> ::= <множитель> | <слагаемое> * <множитель>

<множитель> ::= <буква> | (<выражение>)

<буква>

บันทึก. เครื่องหมาย "::=" อ่านว่า "มันคือ" แถบแนวตั้ง "|" อ่านว่า "หรือ"

หากกฎถูกเขียนแตกต่างกัน โครงสร้างลำดับชั้น. ดังตัวอย่าง สามารถกำหนดวิธีการเขียนกฎได้ดังนี้

<выражение> ::= <операнд> | <выражение> + < операнд > | <выражение> * < операнд >

<операнд> ::= <буква> | (<выражение>)

<буква>::= ก | ข | ค | ง | ฉัน | ฉ | ก | ชั่วโมง | ฉัน | เจ | ก | ล | ม. | n | o | พี | คิว | r | ส | เสื้อ | คุณ | วี | ว | x | y | ซี

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


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

กระบวนการค้นหาโครงสร้างวากยสัมพันธ์ของโปรแกรมที่กำหนดเรียกว่า การแยกวิเคราะห์.

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

โครงสร้างวากยสัมพันธ์อธิบายโดยกฎ:

<выражение> ::= <буква> | <операнд> <операнд> <операция>

< операнд > ::= < буква > | < выражение >

< операция > ::= + | *

<буква>::= ก | ข | ค | ง | ฉัน | ฉ | ก | ชั่วโมง | ฉัน | เจ | ก | ล | ม. | n | o | พี | คิว | r | ส | เสื้อ | คุณ | วี | ว | x | y | ซี

ต้นไม้ลำดับชั้นที่กำหนดโครงสร้างวากยสัมพันธ์จะแสดงในรูปที่ 1.3.

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

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

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

โครงสร้างตัวแปลทั่วไป

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

พิจารณาความคล้ายคลึงกันของคอมไพเลอร์และล่าม ลองพิจารณาเฟสที่มีอยู่ในคอมไพเลอร์ มันไฮไลท์:

  1. ขั้นตอนของการวิเคราะห์คำศัพท์
  2. ขั้นตอนการแยกวิเคราะห์ประกอบด้วย:
  • การรู้จำโครงสร้างวากยสัมพันธ์
  • การแยกวิเคราะห์ความหมาย, ในระหว่างที่ทำงานกับตาราง, การสร้างตัวแทนความหมายระดับกลางหรือ แบบจำลองวัตถุภาษา.
  • ขั้นตอนการสร้างรหัสซึ่งดำเนินการ:
    • การวิเคราะห์ความหมายของส่วนประกอบของการเป็นตัวแทนระดับกลางหรือแบบจำลองวัตถุของภาษา
    • การแปลตัวแทนระดับกลางหรือโมเดลวัตถุเป็นรหัสวัตถุ

    นอกเหนือจากขั้นตอนหลักของกระบวนการแปลแล้ว ยังเป็นไปได้ที่ขั้นตอนเพิ่มเติม:

      2a ขั้นตอนการวิจัยและการเพิ่มประสิทธิภาพของการเป็นตัวแทนระดับกลาง ประกอบด้วย:
    2ก.1. การวิเคราะห์ความถูกต้องของการเป็นตัวแทนระดับกลาง
    2ก.2. การเพิ่มประสิทธิภาพการเป็นตัวแทนระดับกลาง
      3ก. ขั้นตอนการเพิ่มประสิทธิภาพรหัสวัตถุ

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

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

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

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

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

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

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

    ดังนั้น parser จึงเป็นบล็อกนักแปลที่ค่อนข้างซับซ้อน ดังนั้นจึงสามารถแบ่งออกเป็นองค์ประกอบต่อไปนี้:

    • ตัวจำแนก;
    • บล็อกของการวิเคราะห์เชิงความหมาย
    • โมเดลวัตถุหรือการเป็นตัวแทนระดับกลาง ประกอบด้วยตารางชื่อและโครงสร้างวากยสัมพันธ์

    โครงสร้างทั่วไปของ parser แสดงในรูปที่ 1.6.

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

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

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

    ตัวเลือกการโต้ตอบสำหรับบล็อกนักแปล

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

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

    จากตัวเลือกหลักสองตัวเลือก คุณยังสามารถสร้างชุดค่าผสมต่างๆ

    องค์กร Multipass ของการโต้ตอบของบล็อกนักแปล

    ความแตกต่างของการโต้ตอบบล็อกโดยใช้คอมไพเลอร์เป็นตัวอย่างแสดงในรูปที่ 1.7


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

    ข้อดีของวิธีนี้ ได้แก่ :

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

    ข้อด้อยที่ควรพิจารณา

    1. การมีอยู่ของข้อมูลระดับกลางจำนวนมากจากที่ ช่วงเวลานี้ใช้เวลาเพียงเล็กน้อยเท่านั้น
    2. ความเร็วในการแปลช้าลงเนื่องจากการดำเนินการตามลำดับของเฟสและการใช้อุปกรณ์จัดเก็บข้อมูลภายนอกเพื่อประหยัด RAM

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

    การจัดระเบียบปฏิสัมพันธ์ของบล็อกนักแปลแบบผ่านครั้งเดียว

    หนึ่งในตัวเลือกสำหรับการโต้ตอบของบล็อกคอมไพเลอร์กับองค์กรแบบ single-pass แสดงอยู่ในรูปที่ 1.8.

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

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

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

    บ่อยครั้งที่ตัวแปลแบบผ่านเดียวใช้รูปแบบการควบคุมที่แตกต่างกันซึ่งตัวแยกวิเคราะห์จะมีบทบาทเป็นบล็อกหลัก (รูปที่ 1.9)

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

    ข้อดีของรูปแบบ one-pass ได้แก่ การไม่มีข้อมูลระดับกลางจำนวนมาก ความเร็วสูงการประมวลผลเนื่องจากการรวมกันของเฟสในกระบวนการเดียวและขาดการเข้าถึงอุปกรณ์จัดเก็บข้อมูลภายนอก

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

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

    การโต้ตอบแบบรวมของบล็อคนักแปล

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

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

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


    นอกจากโครงร่างที่เกี่ยวข้องกับการแทนที่ตัวสร้างโค้ดด้วยโปรแกรมจำลองแล้ว ยังมีตัวแปลที่อนุญาตให้ใช้ร่วมกันได้ หนึ่งในแผนการเหล่านี้แสดงในรูปที่ 1.13.

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

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

    ควบคุมคำถามและงาน

    1. ตั้งชื่อความแตกต่าง:
      • ล่ามคอมไพเลอร์;
      • คอมไพเลอร์จากแอสเซมเบลอร์
      • ตัวแปลงรหัสจากตัวแปล
      • ตัวจำลองจากล่าม
      • ไวยากรณ์จากความหมาย
    1. บอกเราเกี่ยวกับการพัฒนาล่าสุดของภาษาโปรแกรมที่คุณรู้จัก ให้ลักษณะสำคัญของภาษาเหล่านี้
    2. ยกตัวอย่างที่ชัดเจนของการใช้วิธีแปลในส่วนที่ไม่เกี่ยวข้องกับภาษาโปรแกรม
    3. ยกตัวอย่างเฉพาะของภาษาโปรแกรมคอมไพล์
    4. ยกตัวอย่างเฉพาะของภาษาโปรแกรมตีความ
    5. ยกตัวอย่างเฉพาะของภาษาโปรแกรมที่มีทั้งคอมไพเลอร์และล่าม
    6. ข้อดีและข้อเสียหลักของคอมไพเลอร์
    7. ข้อดีและข้อเสียหลักของล่าม
    8. อธิบายความแตกต่างหลักในไวยากรณ์ของภาษาโปรแกรมสองภาษาที่คุณรู้จัก
    9. อธิบายความแตกต่างหลักในความหมายของภาษาโปรแกรมสองภาษาที่คุณรู้จัก
    10. ระบุขั้นตอนหลักของกระบวนการแปลและวัตถุประสงค์
    11. ตั้งชื่อคุณสมบัติเฉพาะของการแปลแบบรอบเดียว
    12. ตั้งชื่อคุณสมบัติเฉพาะของการแปลหลายพาส
    13. ยกตัวอย่างการผสมผสานที่เป็นไปได้ของการแปลแบบรอบเดียวและหลายรอบ บอกเกี่ยวกับ ใช้งานได้จริงแผนการเหล่านี้