Buku Dr. Yan Hong "JAVA and Patterns" dimulai dengan deskripsi pola Interpreter:
Pola juru bahasa adalah pola perilaku untuk kelas. Mengingat suatu bahasa, pola juru bahasa mendefinisikan representasi tata bahasanya dan menyediakan juru bahasa. Klien dapat menggunakan juru bahasa ini untuk menafsirkan kalimat dalam bahasa ini.
Struktur mode penerjemah
Mari kita ambil sistem skema sebagai contoh untuk membahas struktur mode penerjemah. Diagram struktur sistemnya adalah sebagai berikut:
Peran yang terlibat dalam pola tersebut adalah sebagai berikut:
(1) Peran ekspresi abstrak (Ekspresi): Deklarasikan antarmuka abstrak yang perlu diimplementasikan oleh semua peran ekspresi konkret. Antarmuka ini pada dasarnya adalah metode interpret(), yang disebut operasi interpretasi.
(2) Peran Ekspresi Terminal: mengimplementasikan antarmuka yang diperlukan oleh peran ekspresi abstrak, terutama metode interpret(); setiap simbol terminal dalam tata bahasa memiliki ekspresi terminal spesifik yang sesuai dengannya. Misalnya, ada rumus sederhana R=R1+R2, di mana R1 dan R2 adalah simbol terminal, dan penerjemah terkait yang mem-parsing R1 dan R2 adalah ekspresi terminal.
(3) Peran Ekspresi Nonterminal: Setiap aturan dalam tata bahasa memerlukan ekspresi nonterminal tertentu. Ekspresi nonterminal umumnya berupa operator atau kata kunci lain dalam tata bahasa, seperti rumus. Dalam R=R1+R2, "+" adalah simbol non-terminal , dan penerjemah yang mem-parsing "+" adalah ekspresi simbol non-terminal.
(4) Peran konteks: Tugas peran ini umumnya adalah menyimpan nilai spesifik yang sesuai dengan setiap simbol terminal dalam tata bahasa. Misalnya, R=R1+R2, kami menetapkan nilai 100 ke R1 dan nilai 200 hingga R2. Informasi ini perlu disimpan dalam peran lingkungan. Dalam banyak kasus, kita cukup menggunakan Map untuk bertindak sebagai peran lingkungan.
Untuk mengilustrasikan implementasi mode interpreter, berikut adalah tata bahasa paling sederhana dan implementasi mode interpreter yang sesuai, yaitu untuk mensimulasikan operasi dan evaluasi ekspresi Boolean dalam bahasa Java.
Simbol terminal dalam bahasa ini adalah variabel Boolean, yaitu konstanta benar dan salah. Ekspresi non-terminal mencakup ekspresi Boolean seperti operator dan, atau dan tidak. Tata bahasa sederhananya adalah sebagai berikut:
Copy kode kodenya sebagai berikut:
Ekspresi ::= Konstanta |.Variabel |
Dan ::= Ekspresi 'DAN'
Atau ::= Ekspresi 'ATAU'
Bukan ::= Ekspresi 'TIDAK'
Variabel ::= pengenal apa pun
Konstan ::= 'benar' |. 'salah'
Diagram struktur mode juru bahasa adalah sebagai berikut:
kode sumber
peran ekspresi abstrak
Copy kode kodenya sebagai berikut:
Ekspresi kelas abstrak publik {
/**
* Tergantung pada lingkungan, metode ini menafsirkan ekspresi apa pun
*/
interpretasi boolean abstrak publik (Konteks ctx);
/**
* Periksa apakah dua ekspresi secara struktural sama
*/
boolean abstrak publik sama dengan(Obj objek);
/**
* Mengembalikan kode hash dari ekspresi
*/
abstrak publik int kode hash();
/**
* Ubah ekspresi menjadi string
*/
String abstrak publik toString();
}
Objek Konstan mewakili konstanta Boolean
Copy kode kodenya sebagai berikut:
public class Konstanta memperluas Ekspresi{
nilai boolean pribadi;
Konstanta publik(nilai boolean){
this.nilai = nilai;
}
@Mengesampingkan
boolean publik sama dengan(Obj objek) {
if(obj != null && obj instance dari Konstanta){
kembalikan this.value == ((Constant)obj).value;
}
kembali salah;
}
@Mengesampingkan
kode hash int publik() {
kembalikan ini.toString().hashCode();
}
@Mengesampingkan
interpretasi boolean publik(Konteks ctx) {
nilai kembalian;
}
@Mengesampingkan
String publik keString() {
kembalikan Boolean(nilai).toString();
}
}
Objek Variabel mewakili variabel bernama. Kodenya adalah sebagai berikut:
Variabel kelas publik memperluas Ekspresi {
nama String pribadi;
Variabel publik(Nama string){
ini.nama = nama;
}
@Mengesampingkan
boolean publik sama dengan(Obj objek) {
if(obj != null && obj instance dari Variabel)
{
kembalikan ini.nama.sama dengan(
((Variabel)obj).nama);
}
kembali salah;
}
@Mengesampingkan
kode hash int publik() {
kembalikan ini.toString().hashCode();
}
@Mengesampingkan
String publik keString() {
nama kembali;
}
@Mengesampingkan
interpretasi boolean publik(Konteks ctx) {
kembalikan ctx.lookup(ini);
}
}
Kelas And mewakili operasi logika "DAN", yang mewakili operasi pemberian ekspresi Boolean baru dari dua ekspresi Boolean melalui operasi logika "DAN".
Copy kode kodenya sebagai berikut:
kelas publik Dan memperluas Ekspresi {
Ekspresi pribadi kiri, kanan;
public And(Ekspresi kiri, Ekspresi kanan){
ini.kiri = kiri;
ini.kanan = kanan;
}
@Mengesampingkan
boolean publik sama dengan(Obj objek) {
if(obj != null && objek instanceof Dan)
{
kembali ke kiri.sama dengan(((Dan)obj).kiri) &&
kanan.sama dengan(((Dan)obj).kanan);
}
kembali salah;
}
@Mengesampingkan
kode hash int publik() {
kembalikan ini.toString().hashCode();
}
@Mengesampingkan
interpretasi boolean publik(Konteks ctx) {
kembali ke kiri.interpret(ctx) && kanan.interpret(ctx);
}
@Mengesampingkan
String publik keString() {
return "(" + kiri.toString() + " DAN " + kanan.toString() + ")";
}
}
Kelas Or mewakili operasi logika "OR", yang mewakili operasi pemberian ekspresi Boolean baru dari dua ekspresi Boolean melalui operasi logika "OR".
Copy kode kodenya sebagai berikut:
kelas publik Atau memperluas Ekspresi {
Ekspresi pribadi kiri, kanan;
public Or(Ekspresi kiri, Ekspresi kanan){
ini.kiri = kiri;
ini.kanan = kanan;
}
@Mengesampingkan
boolean publik sama dengan(Obj objek) {
if(obj != null && obj contoh Atau)
{
kembalikan this.left.equals(((Or)obj).left) && this.right.equals(((Or)obj).right);
}
kembali salah;
}
@Mengesampingkan
kode hash int publik() {
kembalikan ini.toString().hashCode();
}
@Mengesampingkan
interpretasi boolean publik(Konteks ctx) {
kembali ke kiri.interpret(ctx) ||.kanan.interpret(ctx);
}
@Mengesampingkan
String publik keString() {
return "(" + kiri.toString() + " ATAU " + kanan.toString() + ")";
}
}
Kelas Not mewakili operasi logika "tidak", yang mewakili operasi pemberian ekspresi Boolean baru dari ekspresi Boolean melalui operasi logika "tidak". Salin kode sebagai berikut:
kelas publik Tidak memperluas Ekspresi {
ekspresi pribadi exp;
publik Not(Ekspresi exp){
ini.exp = exp;
}
@Mengesampingkan
boolean publik sama dengan(Obj objek) {
if(obj != null && obj contoh Tidak)
{
kembalikan exp.sama dengan(
((Tidak)obj).exp);
}
kembali salah;
}
@Mengesampingkan
kode hash int publik() {
kembalikan ini.toString().hashCode();
}
@Mengesampingkan
interpretasi boolean publik(Konteks ctx) {
kembali !exp.interpret(ctx);
}
@Mengesampingkan
String publik keString() {
return "(Bukan " + exp.toString() + ")";
}
}
Kelas Context mendefinisikan pemetaan dari variabel ke nilai Boolean
Copy kode kodenya sebagai berikut:
Konteks kelas publik {
peta pribadi<Variable,Boolean> map = HashMap<Variable,Boolean>();
penetapan kekosongan publik(Variabel var, nilai boolean){
map.put(var, Boolean baru(nilai));
}
pencarian boolean publik (Variabel var) memunculkan IllegalArgumentException{
Nilai Boolean = map.get(var);
jika(nilai == nol){
melempar IllegalArgumentException();
}
mengembalikan nilai.booleanValue();
}
}
Kelas klien
Copy kode kodenya sebagai berikut:
Klien kelas publik {
public static void main(String[] args) {
Konteks ctx = Konteks baru();
Variabel x = Variabel baru("x");
Variabel y = Variabel baru("y");
Konstanta c = Konstanta baru(benar);
ctx.assign(x, salah);
ctx.assign(y, benar);
Ekspresi exp = new Or(new And(c,x) , new And(y,new Not(x)));
Sistem.keluar.println("x=" + x.interpret(ctx));
Sistem.keluar.println("y=" + y.interpret(ctx));
Sistem.keluar.println(exp.toString() + "=" + exp.interpret(ctx));
}
}
Hasil yang berjalan adalah sebagai berikut: