หนังสือของ Dr. Yan Hong เรื่อง "JAVA and Patterns" เริ่มต้นด้วยคำอธิบายเกี่ยวกับรูปแบบล่าม:
รูปแบบล่ามเป็นรูปแบบพฤติกรรมสำหรับชั้นเรียน เมื่อใช้ภาษา รูปแบบล่ามจะกำหนดการเป็นตัวแทนของไวยากรณ์และจัดให้มีล่าม ลูกค้าสามารถใช้ล่ามนี้เพื่อแปลประโยคในภาษานี้ได้
โครงสร้างของโหมดล่าม
ลองใช้ระบบแผนผังเป็นตัวอย่างเพื่อหารือเกี่ยวกับโครงสร้างของโหมดล่าม แผนภาพโครงสร้างระบบมีดังนี้:
บทบาทที่เกี่ยวข้องกับรูปแบบมีดังนี้:
(1) บทบาทการแสดงออกทางนามธรรม (การแสดงออก): ประกาศอินเทอร์เฟซเชิงนามธรรมที่บทบาทการแสดงออกที่เป็นรูปธรรมทั้งหมดจำเป็นต้องนำไปใช้ อินเทอร์เฟซนี้ส่วนใหญ่เป็นวิธีการตีความ () เรียกว่าการดำเนินการตีความ
(2) บทบาท Terminal Expression: ใช้อินเทอร์เฟซที่จำเป็นสำหรับบทบาทนิพจน์นามธรรม ซึ่งส่วนใหญ่เป็นวิธีการ ตีความ () แต่ละสัญลักษณ์เทอร์มินัลในไวยากรณ์มีนิพจน์เทอร์มินัลเฉพาะที่สอดคล้องกับมัน ตัวอย่างเช่น มีสูตรง่ายๆ R=R1+R2 โดยที่ R1 และ R2 เป็นสัญลักษณ์เทอร์มินัล และล่ามที่สอดคล้องกันที่แยกวิเคราะห์ R1 และ R2 คือนิพจน์เทอร์มินัล
(3) บทบาทนิพจน์ที่ไม่ใช่เทอร์มินัล: แต่ละกฎในไวยากรณ์จำเป็นต้องมีนิพจน์ที่ไม่ใช่เทอร์มินัลที่เฉพาะเจาะจง โดยทั่วไปแล้วนิพจน์ที่ไม่ใช่เทอร์มินัลจะเป็นตัวดำเนินการหรือคำหลักอื่น ๆ ในไวยากรณ์ เช่น สูตร ใน R=R1+R2 "+" คือสัญลักษณ์ที่ไม่ใช่เทอร์มินัล และล่ามที่แยกวิเคราะห์ "+" คือนิพจน์สัญลักษณ์ที่ไม่ใช่เทอร์มินัล
(4) บทบาทบริบท: โดยทั่วไปงานของบทบาทนี้คือการจัดเก็บค่าเฉพาะที่สอดคล้องกับสัญลักษณ์เทอร์มินัลแต่ละตัวในไวยากรณ์ ตัวอย่างเช่น R=R1+R2 เรากำหนดค่า 100 ให้กับ R1 และค่าของ 200 ถึง R2 ข้อมูลนี้จำเป็นต้องถูกจัดเก็บไว้ในบทบาทสภาพแวดล้อม ในหลายกรณี การใช้ Map เพื่อทำหน้าที่เป็นบทบาทด้านสิ่งแวดล้อมก็เพียงพอแล้ว
เพื่อแสดงให้เห็นถึงการใช้งานโหมดล่าม นี่คือไวยากรณ์ที่ง่ายที่สุดและการใช้งานโหมดล่ามที่สอดคล้องกัน ซึ่งก็คือการจำลองการดำเนินการและการประเมินผลของนิพจน์บูลีนในภาษา Java
สัญลักษณ์เทอร์มินัลในภาษานี้คือตัวแปรบูลีน ซึ่งก็คือค่าคงที่จริงและเท็จ นิพจน์ที่ไม่ใช่เทอร์มินัลประกอบด้วยนิพจน์บูลีน เช่น ตัวดำเนินการ and, or and not ไวยากรณ์ง่ายๆ นี้มีดังนี้:
คัดลอกรหัสรหัสดังต่อไปนี้:
นิพจน์ ::= ค่าคงที่ |. หรือ |
และ ::= นิพจน์ 'และ' นิพจน์
หรือ ::= นิพจน์ 'หรือ' นิพจน์
ไม่ใช่ ::= นิพจน์ 'ไม่'
ตัวแปร ::= ตัวระบุใด ๆ
ค่าคงที่ ::= 'จริง' | .
แผนผังโครงสร้างของโหมดล่ามมีดังนี้:
ซอร์สโค้ด
บทบาทการแสดงออกทางนามธรรม
คัดลอกรหัสรหัสดังต่อไปนี้:
นิพจน์คลาสนามธรรมสาธารณะ {
-
* ขึ้นอยู่กับสภาพแวดล้อม วิธีการนี้จะตีความการแสดงออกใดๆ ที่กำหนด
-
การตีความบูลีนนามธรรมสาธารณะ (บริบท ctx);
-
* ตรวจสอบว่านิพจน์ทั้งสองมีโครงสร้างเหมือนกันหรือไม่
-
บูลีนนามธรรมสาธารณะเท่ากับ (Object obj);
-
* ส่งกลับรหัสแฮชของนิพจน์
-
บทคัดย่อสาธารณะ int hashCode();
-
* แปลงนิพจน์ให้เป็นสตริง
-
สตริงนามธรรมสาธารณะ toString();
-
วัตถุค่าคงที่แสดงถึงค่าคงที่บูลีน
คัดลอกรหัสรหัสดังต่อไปนี้:
ค่าคงที่คลาสสาธารณะขยาย Expression {
ค่าบูลีนส่วนตัว
ค่าคงที่สาธารณะ (ค่าบูลีน) {
this.value = ค่า;
-
@แทนที่
บูลีนสาธารณะเท่ากับ (Object obj) {
if(obj != null && obj อินสแตนซ์ของค่าคงที่){
กลับ this.value == ((คงที่)obj).value;
-
กลับเท็จ;
-
@แทนที่
hashCode int สาธารณะ () {
กลับ this.toString().hashCode();
-
@แทนที่
การตีความบูลีนสาธารณะ (บริบท ctx) {
ค่าส่งคืน;
-
@แทนที่
สตริงสาธารณะ toString() {
กลับบูลีนใหม่ (ค่า) .toString ();
-
-
วัตถุตัวแปรแสดงถึงตัวแปรที่มีชื่อ รหัสดังต่อไปนี้:
ตัวแปรคลาสสาธารณะขยายนิพจน์ {
ชื่อสตริงส่วนตัว
ตัวแปรสาธารณะ (ชื่อสตริง) {
this.name = ชื่อ;
-
@แทนที่
บูลีนสาธารณะเท่ากับ (Object obj) {
if(obj != null && obj อินสแตนซ์ของตัวแปร)
-
กลับ this.name.equals(
((ตัวแปร)obj).ชื่อ);
-
กลับเท็จ;
-
@แทนที่
hashCode int สาธารณะ () {
กลับ this.toString().hashCode();
-
@แทนที่
สตริงสาธารณะ toString() {
ชื่อผู้ส่งคืน;
-
@แทนที่
การตีความบูลีนสาธารณะ (บริบท ctx) {
กลับ ctx.lookup (นี้);
-
-
คลาส And แสดงถึงการดำเนินการเชิงตรรกะ "AND" ซึ่งแสดงถึงการดำเนินการในการสร้างนิพจน์บูลีนใหม่จากนิพจน์บูลีน 2 นิพจน์ผ่านการดำเนินการเชิงตรรกะ "AND"
คัดลอกรหัสรหัสดังต่อไปนี้:
คลาสสาธารณะ และขยาย Expression {
นิพจน์ส่วนตัว ซ้าย, ขวา;
สาธารณะ และ (นิพจน์ทางซ้าย, นิพจน์ทางขวา){
นี่.ซ้าย = ซ้าย;
นี่.ขวา = ขวา;
-
@แทนที่
บูลีนสาธารณะเท่ากับ (Object obj) {
ถ้า (obj != null && obj อินสแตนซ์ของ And)
-
กลับ left.equals(((และ)obj).left) &&
right.equals(((และ)obj).right);
-
กลับเท็จ;
-
@แทนที่
hashCode int สาธารณะ () {
กลับ this.toString().hashCode();
-
@แทนที่
การตีความบูลีนสาธารณะ (บริบท ctx) {
กลับ left.ตีความ (ctx) && right.ตีความ (ctx);
-
@แทนที่
สตริงสาธารณะ toString() {
กลับ "(" + left.toString() + "และ" + right.toString() + ")";
-
-
คลาส Or แสดงถึงการดำเนินการเชิงตรรกะ "OR" ซึ่งแสดงถึงการดำเนินการของการกำหนดนิพจน์บูลีนใหม่จากนิพจน์บูลีนสองตัวผ่านการดำเนินการ "OR" แบบลอจิคัล
คัดลอกรหัสรหัสดังต่อไปนี้:
คลาสสาธารณะหรือขยาย Expression {
นิพจน์ส่วนตัว ซ้าย, ขวา;
สาธารณะหรือ (นิพจน์ไปทางซ้าย, นิพจน์ทางขวา){
นี่.ซ้าย = ซ้าย;
นี่.ขวา = ขวา;
-
@แทนที่
บูลีนสาธารณะเท่ากับ (Object obj) {
ถ้า (obj != null && obj อินสแตนซ์ของหรือ)
-
กลับ this.left.equals(((หรือ)obj).left) && this.right.equals(((หรือ)obj).right);
-
กลับเท็จ;
-
@แทนที่
hashCode int สาธารณะ () {
กลับ this.toString().hashCode();
-
@แทนที่
การตีความบูลีนสาธารณะ (บริบท ctx) {
กลับทางซ้าย.ตีความ(ctx) ||. ขวา.ตีความ(ctx);
-
@แทนที่
สตริงสาธารณะ toString() {
กลับ "(" + left.toString() + " หรือ " + right.toString() + ")";
-
-
คลาส Not แสดงถึงการดำเนินการ "ไม่" แบบลอจิคัล ซึ่งแสดงถึงการดำเนินการให้นิพจน์บูลีนใหม่จากนิพจน์บูลีนผ่านการดำเนินการ "ไม่" แบบลอจิคัล คัดลอกโค้ดดังต่อไปนี้:
คลาสสาธารณะไม่ขยายนิพจน์ {
ประสบการณ์นิพจน์ส่วนตัว;
สาธารณะไม่ (ประสบการณ์การแสดงออก) {
this.exp = ประสบการณ์;
-
@แทนที่
บูลีนสาธารณะเท่ากับ (Object obj) {
ถ้า (obj != null && obj อินสแตนซ์ของ Not)
-
กลับประสบการณ์เท่ากับ (
((ไม่ใช่)obj).exp);
-
กลับเท็จ;
-
@แทนที่
hashCode int สาธารณะ () {
กลับ this.toString().hashCode();
-
@แทนที่
การตีความบูลีนสาธารณะ (บริบท ctx) {
กลับ !exp.ตีความ(ctx);
-
@แทนที่
สตริงสาธารณะ toString() {
กลับ "(ไม่ใช่" + exp.toString() + ")";
-
-
คลาสบริบทกำหนดการแมปจากตัวแปรไปยังค่าบูลีน
คัดลอกรหัสรหัสดังต่อไปนี้:
บริบทของชั้นเรียนสาธารณะ {
แผนที่ส่วนตัว <ตัวแปร, บูลีน> แผนที่ = ใหม่ HashMap <ตัวแปร, บูลีน> ();
การกำหนดโมฆะสาธารณะ (ตัวแปร var ค่าบูลีน) {
map.put(var, บูลีนใหม่ (ค่า));
-
การค้นหาบูลีนสาธารณะ (ตัวแปร var) พ่น IllegalArgumentException {
ค่าบูลีน = map.get(var);
ถ้า(ค่า == null){
โยน IllegalArgumentException ใหม่ ();
-
ส่งกลับค่า.booleanValue();
-
-
คลาสลูกค้า
คัดลอกรหัสรหัสดังต่อไปนี้:
ลูกค้าคลาสสาธารณะ {
โมฆะสาธารณะคงหลัก (สตริง [] args) {
บริบท ctx = บริบทใหม่ ();
ตัวแปร x = ตัวแปรใหม่("x");
ตัวแปร y = ตัวแปรใหม่("y");
ค่าคงที่ c = ค่าคงที่ใหม่ (จริง);
ctx.มอบหมาย(x, เท็จ);
ctx.มอบหมาย(y, จริง);
Expression exp = ใหม่ Or(new And(c,x) , new And(y,new Not(x)));
System.out.println("x=" + x.ตีความ(ctx));
System.out.println("y=" + y.ตีความ(ctx));
System.out.println(exp.toString() + "=" + exp.ตีความ(ctx));
-
-
ผลการวิ่งมีดังนี้: