يبدأ كتاب الدكتور يان هونغ "JAVA والأنماط" بوصف نمط المترجم الفوري:
نمط المترجم هو نمط سلوكي للفصول الدراسية. بالنظر إلى اللغة، يحدد نمط المترجم تمثيلًا لقواعدها النحوية ويوفر مترجمًا. يمكن للعملاء استخدام هذا المترجم لترجمة الجمل بهذه اللغة.
هيكل وضع المترجم
لنأخذ نظامًا تخطيطيًا كمثال لمناقشة بنية وضع المترجم الفوري. مخطط هيكل النظام هو كما يلي:
الأدوار المشاركة في النمط هي كما يلي:
(1) دور التعبير المجرد (التعبير): قم بتعريف واجهة مجردة تحتاج جميع أدوار التعبير الملموسة إلى تنفيذها. هذه الواجهة هي في الأساس طريقة تفسير () تسمى عملية التفسير.
(2) دور التعبير الطرفي: ينفذ الواجهة التي يتطلبها دور التعبير المجرد، بشكل أساسي طريقة التفسير () ؛ كل رمز طرفي في القواعد له تعبير طرفي محدد يتوافق معه. على سبيل المثال، هناك صيغة بسيطة R=R1+R2، حيث يكون R1 وR2 رمزين طرفيين، والمترجم المقابل الذي يوزع R1 وR2 هو تعبير طرفي.
(3) دور التعبير غير الطرفي: تتطلب كل قاعدة في القواعد تعبيرًا غير طرفي محدد. وعادةً ما تكون التعبيرات غير الطرفية عبارة عن عوامل تشغيل أو كلمات رئيسية أخرى في القواعد، مثل الصيغ في R=R1+R2، ويعتبر "+" رمزًا غير طرفي ، والمترجم الذي يوزع "+" هو تعبير رمز غير طرفي.
(4) دور السياق: مهمة هذا الدور بشكل عام هي تخزين القيم المحددة المقابلة لكل رمز طرفي في القواعد، على سبيل المثال، R=R1+R2، نقوم بتعيين قيمة 100 لـ R1 وقيمة 200 إلى R2. يجب تخزين هذه المعلومات في دور البيئة. في كثير من الحالات، يكفي أن نستخدم الخريطة لتكون بمثابة دور البيئة.
من أجل توضيح تنفيذ وضع المترجم الفوري، إليك أبسط القواعد والتنفيذ المقابل لوضع المترجم الفوري، وهو محاكاة تشغيل وتقييم التعبيرات المنطقية في لغة Java.
الرموز الطرفية في هذه اللغة هي متغيرات منطقية، أي الثوابت صحيحة وخاطئة. تتضمن التعبيرات غير الطرفية تعبيرات منطقية مثل عوامل التشغيل و، أو لا. هذه القواعد النحوية البسيطة هي كما يلي:
انسخ رمز الكود كما يلي:
التعبير::= ثابت |
و ::= التعبير 'AND' التعبير
أو ::= التعبير 'OR' التعبير
ليس ::= تعبير "NOT".
المتغير ::= أي معرف
ثابت ::= "صحيح" |.
الرسم التخطيطي لوضع المترجم الفوري هو كما يلي:
كود المصدر
دور التعبير المجرد
انسخ رمز الكود كما يلي:
تعبير فئة مجردة عامة {
/**
* مع مراعاة البيئة، تفسر هذه الطريقة أي تعبير معين
*/
تفسير منطقي مجرد عام (Context ctx)؛
/**
* التحقق مما إذا كان هناك تعبيران متماثلان من الناحية الهيكلية
*/
الملخص المنطقي العام يساوي (Object obj)؛
/**
* إرجاع رمز التجزئة للتعبير
*/
الملخص العام int hashCode();
/**
* تحويل التعبير إلى سلسلة
*/
سلسلة مجردة عامة toString () ؛
}
يمثل الكائن الثابت ثابتًا منطقيًا
انسخ رمز الكود كما يلي:
الطبقة العامة ثابت يمتد التعبير {
قيمة منطقية خاصة؛
ثابت عام (قيمة منطقية) {
this.value = value;
}
@تجاوز
منطقية عامة يساوي (كائن كائن) {
if(obj != null && obj مثيل للثابت){
return this.value == ((Constant)obj).value;
}
عودة كاذبة.
}
@تجاوز
public int hashCode() {
إرجاع this.toString().hashCode();
}
@تجاوز
تفسير منطقي عام (السياق ctx) {
قيمة الإرجاع؛
}
@تجاوز
سلسلة عامة إلى سلسلة () {
إرجاع منطقية جديدة (قيمة).toString ()؛
}
}
يمثل الكائن المتغير متغيرًا مسمىًا، ويكون الكود كما يلي:
متغير الطبقة العامة يمتد التعبير {
اسم سلسلة خاصة؛
المتغير العام (اسم السلسلة) {
this.name = name;
}
@تجاوز
منطقية عامة يساوي (كائن كائن) {
إذا (obj!= null && مثيل obj للمتغير)
{
إرجاع هذا.name.equals(
((متغير)obj).name);
}
عودة كاذبة.
}
@تجاوز
public int hashCode() {
إرجاع this.toString().hashCode();
}
@تجاوز
سلسلة عامة إلى سلسلة () {
اسم الإرجاع؛
}
@تجاوز
تفسير منطقي عام (السياق ctx) {
إرجاع ctx.lookup(this);
}
}
تمثل الفئة And العملية المنطقية "AND"، والتي تمثل عملية إعطاء تعبير منطقي جديد من تعبيرين منطقيين من خلال العملية المنطقية "AND".
انسخ رمز الكود كما يلي:
الطبقة العامة ويمتد التعبير {
التعبير الخاص يسار، يمين؛
عام و(التعبير الأيسر، التعبير الأيمن){
this.left = left;
this.right = right;
}
@تجاوز
منطقية عامة يساوي (كائن كائن) {
إذا (obj != null && obj مثيل And)
{
إرجاع left.equals(((و)obj).left) &&
right.equals(((و)obj).right);
}
عودة كاذبة.
}
@تجاوز
كود التجزئة العام () {
إرجاع this.toString().hashCode();
}
@تجاوز
تفسير منطقي عام (السياق ctx) {
إرجاع left.interpret(ctx) && right.interpret(ctx);
}
@تجاوز
سلسلة عامة إلى سلسلة () {
return "(" + left.toString() + " AND " + right.toString() + ")";
}
}
تمثل الفئة Or عملية "OR" المنطقية، والتي تمثل عملية إعطاء تعبير منطقي جديد من تعبيرين منطقيين من خلال عملية "OR" المنطقية.
انسخ رمز الكود كما يلي:
فئة عامة أو يمتد التعبير {
التعبير الخاص يسار، يمين؛
عام أو (التعبير الأيسر، التعبير الأيمن) {
this.left = left;
this.right = right;
}
@تجاوز
منطقية عامة يساوي (كائن كائن) {
إذا (obj != null && obj مثيل Or)
{
إرجاع this.left.equals(((Or)obj).left) && this.right.equals(((Or)obj).right);
}
عودة كاذبة.
}
@تجاوز
كود التجزئة العام () {
إرجاع this.toString().hashCode();
}
@تجاوز
تفسير منطقي عام (السياق ctx) {
إرجاع left.interpret(ctx) ||.
}
@تجاوز
سلسلة عامة إلى سلسلة () {
return "(" + left.toString() + " OR " + right.toString() + ")";
}
}
تمثل الفئة Not عملية "not" المنطقية، والتي تمثل عملية إعطاء تعبير منطقي جديد من تعبير منطقي من خلال عملية "not" المنطقية، انسخ الكود كما يلي:
الطبقة العامة لا تمتد التعبير {
التعبير الخاص إكسب؛
عام ليس (تعبير إكسب) {
this.exp = exp;
}
@تجاوز
منطقية عامة يساوي (كائن كائن) {
إذا (obj != null && obj مثيل Not)
{
إرجاع الخبرة يساوي (
((ليس)obj).exp);
}
عودة كاذبة.
}
@تجاوز
كود التجزئة العام () {
إرجاع this.toString().hashCode();
}
@تجاوز
تفسير منطقي عام (السياق ctx) {
return !exp.interpret(ctx);
}
@تجاوز
سلسلة عامة إلى سلسلة () {
return "(Not" + exp.toString() + ")";
}
}
تحدد فئة السياق التعيين من المتغيرات إلى القيم المنطقية
انسخ رمز الكود كما يلي:
سياق الطبقة العامة {
خريطة خاصة <Variable,Boolean> Map = new HashMap<Variable,Boolean>();
تعيين الفراغ العام (متغير فار، قيمة منطقية) {
Map.put(var, new Boolean(value));
}
البحث المنطقي العام (Variable var) يلقي IllegalArgumentException{
القيمة المنطقية = Map.get(var);
إذا (القيمة == فارغة){
رمي IllegalArgumentException () الجديد ؛
}
قيمة الإرجاع.booleanValue();
}
}
فئة العميل
انسخ رمز الكود كما يلي:
عميل الطبقة العامة {
public static void main(String[] args) {
السياق ctx = سياق جديد ()؛
المتغير x = المتغير الجديد("x");
المتغير y = new Variable("y");
ثابت ج = ثابت جديد (صحيح)؛
ctx.assis(x, false);
ctx.assis(y, true);
Expression exp = new Or(new And(c,x) , new And(y,new Not(x)));
System.out.println("x=" + x.interpret(ctx));
System.out.println("y=" + y.interpret(ctx));
System.out.println(exp.toString() + "=" + exp.interpret(ctx));
}
}
نتائج التشغيل هي كما يلي: