คำจำกัดความ: ให้ภาษากำหนดตัวแทนของไวยากรณ์และกำหนดล่ามที่ใช้การเป็นตัวแทนเพื่อตีความประโยคในภาษา
ประเภท: รูปแบบพฤติกรรม
แผนภาพชั้นเรียน:
โหมดล่ามเป็นโหมดที่ค่อนข้างใช้งานไม่ค่อยและฉันไม่เคยใช้โหมดนี้มาก่อน มาดูโหมดล่าม
โครงสร้างของโหมดล่าม
บทคัดย่อล่าม: ประกาศอินเทอร์เฟซนามธรรม (หรือคลาสนามธรรม) ซึ่งจะต้องใช้การแสดงออกที่เป็นรูปธรรมทั้งหมด อินเทอร์เฟซส่วนใหญ่เป็นวิธีการตีความ () ที่เรียกว่าการดำเนินการคำอธิบาย งานการตีความที่เฉพาะเจาะจงนั้นเสร็จสมบูรณ์โดยคลาสการใช้งานที่หลากหลายและล่ามที่เฉพาะเจาะจงจะเสร็จสมบูรณ์โดย Terminator Interpreter Terminalexpression และ Nonterminal Interpreter Nonterminalexpression ตามลำดับ
การแสดงออกของ Terminator: ใช้การดำเนินการตีความที่เกี่ยวข้องกับองค์ประกอบในไวยากรณ์ โดยปกติแล้วจะมีการแสดงออกของเทอร์มิเนเตอร์เพียงอย่างเดียวในรูปแบบล่าม แต่มีหลายอินสแตนซ์ที่สอดคล้องกับเทอร์มินัลที่แตกต่างกัน ครึ่งหนึ่งของเทอร์มิเนเตอร์เป็นหน่วยปฏิบัติการในไวยากรณ์ ตัวอย่างเช่นมีสูตรง่าย ๆ R = R1+R2 โดยที่ R1 และ R2 เป็นเทอร์มินัลและล่ามที่สอดคล้องกันที่แยก R1 และ R2 เป็นเทอร์มิเนเตอร์
การแสดงออกที่ไม่ใช่ขั้ว: แต่ละกฎในไวยากรณ์สอดคล้องกับนิพจน์ที่ไม่ใช่ขั้ว การแสดงออกที่ไม่ใช่เทอร์มินัลเป็นตัวดำเนินการหรือคำหลักอื่น ๆ ในไวยากรณ์ ตัวอย่างเช่นในสูตร R = R1 + R2, + เป็นอักขระที่ไม่ใช่เทอร์มินัลและล่ามของการแยกวิเคราะห์ + เป็นอักขระที่ไม่ใช่เทอร์มินัล การแสดงออกที่ไม่ใช่เทอร์มินัลเพิ่มขึ้นตามความซับซ้อนของตรรกะและในหลักการแต่ละกฎไวยากรณ์แต่ละกฎสอดคล้องกับการแสดงออกที่ไม่ใช่ขั้ว
บทบาทสภาพแวดล้อม: งานของบทบาทนี้โดยทั่วไปจะใช้ในการจัดเก็บค่าเฉพาะที่สอดคล้องกับแต่ละเทอร์มิเนเตอร์ในไวยากรณ์เช่น R = R1+R2 เรากำหนด 100 ถึง R1 และ 200 ถึง R2 ข้อมูลนี้จะต้องเก็บไว้ในบทบาทสิ่งแวดล้อม ในหลายกรณีเราใช้แผนที่เพื่อทำหน้าที่เป็นบทบาทสภาพแวดล้อมก็เพียงพอแล้ว
ตัวอย่าง
มายกตัวอย่างการเพิ่มการลบการคูณและการหาร แนวคิดการใช้งานมาจากตัวอย่างใน "Java and Pattern" ฟังก์ชั่นของแต่ละบทบาทจะถูกนำไปใช้ตามข้อกำหนดที่กล่าวถึงข้างต้น
// บริบท (สภาพแวดล้อม) บทบาทการใช้ HASHMAP เพื่อจัดเก็บค่าตัวเลขที่สอดคล้องกับบริบทคลาสของตัวแปร {MAP Private ValueMap = ใหม่ HashMap (); โมฆะสาธารณะ addValue (ตัวแปร x, int y) {จำนวนเต็ม yi = จำนวนเต็มใหม่ (y); ValueMap.put (x, yi); } public int lookupValue (ตัวแปร x) {int i = ((จำนวนเต็ม) valueMap.get (x)). intvalue (); กลับฉัน; }} // บทบาทการแสดงออกทางนามธรรมคุณยังสามารถใช้อินเทอร์เฟซเพื่อใช้การแสดงออกของคลาสนามธรรม {การตีความ int นามธรรมสาธารณะ (บริบท con); } // ค่าคงที่ระดับการแสดงออกของระดับการแสดงออกของเทอร์มิเนเตอร์ขยายการแสดงออก {private int i; ค่าคงที่สาธารณะ (int i) {this.i = i; } public int ตีความ (บริบท con) {return i; }} ตัวแปรคลาสขยายนิพจน์ {public int ตีความ (บริบท con) {// นี่คือวัตถุตัวแปรที่เรียกวิธีการตีความการส่งคืน con.lookupvalue (นี่); }} // ระดับบทบาทนิพจน์ nonterminator เพิ่มขยายการแสดงออก {นิพจน์ส่วนตัวซ้ายขวา; ที่อยู่สาธารณะ (นิพจน์ซ้าย, นิพจน์ขวา) {this.left = ซ้าย; this.right = ขวา; } public int ตีความ (บริบท con) {return left.interpret (con) + right.interpret (con); }} การลบคลาสขยายนิพจน์ {นิพจน์ส่วนตัวซ้ายขวา; ลบสาธารณะ (นิพจน์ซ้าย, นิพจน์ขวา) {this.left = ซ้าย; this.right = ขวา; } public int ตีความ (บริบท con) {return left.interpret (con) - right.interpret (con); }} คลาสคูณขยายนิพจน์ {นิพจน์ส่วนตัวซ้ายขวา; สาธารณะคูณ (นิพจน์ซ้าย, นิพจน์ขวา) {this.left = ซ้าย; this.right = ขวา; } การตีความ int สาธารณะ (Context Con) {return left.interpret (con) * right.interpret (con); }} การแบ่งชั้นเรียนขยายการแสดงออก {นิพจน์ส่วนตัวซ้ายขวา; การแบ่งสาธารณะ (การแสดงออกซ้าย, นิพจน์ขวา) {this.left = ซ้าย; this.right = ขวา; } public int ตีความ (บริบท con) {ลอง {return left.interpret (con) / right.interpret (con); } catch (arithmeticexception ae) {system.out.println ("divorc คือ 0!"); กลับ -11111; }}} // ทดสอบโปรแกรมคำนวณ (a*b)/(a-b+2) การทดสอบคลาสสาธารณะ {นิพจน์คงที่ส่วนตัวเช่น; บริบทแบบคงที่ส่วนตัว โมฆะคงที่สาธารณะหลัก (สตริง [] args) {con = บริบทใหม่ (); // ตั้งค่าตัวแปรและค่าคงที่ตัวแปร A = ตัวแปรใหม่ (); ตัวแปร b = ตัวแปรใหม่ (); ค่าคงที่ c = ค่าคงที่ใหม่ (2); // กำหนดตัวแปร con.addvalue (a, 5); Con.addvalue (B, 7); // การดำเนินการเราวิเคราะห์โครงสร้างของประโยคตัวเองสร้าง ex = ส่วนใหม่ (ใหม่ทวีคูณ (a, b), เพิ่มใหม่ (ลบใหม่ (a, b), c)); System.out.println ("ผลการดำเนินการคือ:"+ex.interpret (con)); - ข้อดีและข้อเสียของโหมดล่าม
ล่ามเป็นเครื่องมือวิเคราะห์ไวยากรณ์อย่างง่าย ข้อได้เปรียบที่สำคัญที่สุดคือการขยายความสามารถ การปรับเปลี่ยนกฎไวยากรณ์ต้องมีการแก้ไขอักขระที่ไม่ใช่ขั้วที่สอดคล้องกันเท่านั้น หากคุณขยายไวยากรณ์คุณจะต้องเพิ่มอักขระที่ไม่ใช่ขั้วเท่านั้น
อย่างไรก็ตามรูปแบบล่ามจะทำให้ชั้นเรียนขยายและแต่ละไวยากรณ์จำเป็นต้องสร้างนิพจน์ที่ไม่ใช่เทอร์มินัล เมื่อกฎไวยากรณ์ค่อนข้างซับซ้อนอาจมีการสร้างไฟล์คลาสจำนวนมากซึ่งนำปัญหามาสู่การบำรุงรักษามากมาย ในเวลาเดียวกันเนื่องจากมีการใช้วิธีการโทรแบบเรียกซ้ำแต่ละนิพจน์ที่ไม่ใช่เทอร์มินัลจะให้ความสำคัญกับการแสดงออกที่เกี่ยวข้องกับตัวเอง แต่ละนิพจน์จำเป็นต้องรู้ผลลัพธ์สุดท้ายและจะต้องเรียกซ้ำ ไม่ว่าจะเป็นภาษาเชิงวัตถุหรือภาษาที่มุ่งเน้นกระบวนการการเรียกซ้ำเป็นวิธีที่ไม่แนะนำ เนื่องจากการใช้ลูปและการเรียกซ้ำจำนวนมากประสิทธิภาพจึงเป็นปัญหาที่ไม่สามารถเพิกเฉยได้ โดยเฉพาะอย่างยิ่งเมื่อใช้ในการตีความไวยากรณ์ที่ซับซ้อนและยาวนานความยาวประสิทธิภาพจะทนไม่ได้
สถานการณ์ที่ใช้งานได้สำหรับโหมดล่าม
โหมดล่ามสามารถใช้ในกรณีต่อไปนี้:
มีกฎไวยากรณ์อย่างง่ายเช่นคำสั่ง SQL หากเราต้องการทำการแปลง RM ตามคำสั่ง SQL เราสามารถใช้รูปแบบล่ามเพื่อตีความคำสั่ง
ปัญหาซ้ำ ๆ บางอย่างเช่นการดำเนินการทั้งสี่ของการเพิ่มการลบการคูณและการหาร แต่สูตรแตกต่างกันทุกครั้ง บางครั้งมันคือ+bc*d บางครั้งมันเป็น*b+cd ฯลฯ สูตรมีการเปลี่ยนแปลงตลอดเวลา แต่พวกเขาทั้งหมดเชื่อมต่อกันด้วยตัวละครที่ไม่ใช่ขั้วสี่ตัวที่เพิ่มการลบการคูณและการหาร ในเวลานี้เราสามารถใช้โหมดล่าม
สิ่งที่ควรทราบ
โหมดล่ามเป็นโหมดที่ใช้งานไม่ค่อยใช้จริง ๆ เพราะมันลำบากเกินกว่าที่จะรักษาไว้ได้ ลองนึกภาพว่าหากล่ามที่ไม่ใช่ขั้วไม่คุ้นเคยกับกฎของไวยากรณ์ล่วงหน้าหรือไวยากรณ์นั้นง่ายเป็นพิเศษมันจะยากที่จะเข้าใจตรรกะของมัน โหมดล่ามไม่ค่อยใช้ในการพัฒนาระบบจริงเพราะอาจทำให้เกิดปัญหาเช่นประสิทธิภาพประสิทธิภาพและการบำรุงรักษา