تصف هذه المقالة تنفيذ Java لتحديد وظيفة لغة بسيطة استنادًا إلى نمط المترجم. شاركه للرجوع إليه ، على النحو التالي:
تعريف نمط
نمط المترجم المترجم: هو إعطاء تمثيل نحوي للغة وتحديد مترجم لتفسير الجمل باللغة. يصف نمط المترجم المترجم كيفية تفسير هذه العبارات باستخدام تصميم الأنماط بعد قواعد نحوية بسيطة.
أمثلة على الوضع الثاني
1 تحليل نمط
لقد صممنا لغة لتوضيح هذا النمط بأنفسنا
(1) اللغة حساسة للحالة (2) تبدأ اللغة بالبرنامج وتنتهي بنهاية (3) println تعني طباعة خط وكسره (4) الاستخدام لـ ... من ... إلى ... End يعني الحلقة
مثال محتوى اللغة على النحو التالي:
برنامج println ابدأ ... من أجل أنا من 90 إلى 100 println أنا نهاية println نهاية ... نهاية
معنى هذه الجملة هو: أولاً طباعة كسر الخط مع "ابدأ ..." ، ثم يدور عبر خط الفاصل مع "90" ، "91" ، ... "100" ، وأخيراً طباعة كسر الخط مع "End ...".
2 تشرح هذه اللغة بنية الشجرة
3 مخطط نشاط لمترجم اللغة
4 أمثلة رمز
4.1 إنشاء بيئة سياق - سياق
package com.demo.InterPreter.context ؛ import java.util.hashmap ؛ import java.util.iterator ؛ import java.util.map ؛ import java.util.stringTokenizer ؛/** * context environy * * author *//public class contex // command Command Private String CurrentToken ؛ // المستخدمة لتخزين المعلومات ديناميكيًا لمحتوى الخريطة النهائية الخاصة <string ، Object> map = new HashMap <String ، Object> () ؛ / ** * يقوم مُنشئ بتعيين محتوى التحليل * * param text */ السياق العام (نص السلسلة) {// استخدم المسافات لفصل النص المراد تحليله this.stringTokenizer = new StringTokenizer (text) ؛ } / *** تحليل النص* / السلسلة العامة next () {if (this.stringTokenizer.hasmoretokens ()) {currentToken = this.stringTokenizer.nextToken () ؛ } آخر {currentToken = null ؛ } إرجاع CurrentToken ؛ } / ** * تحديد ما إذا كان الأمر صحيحًا * * param command * regurn * / public boolean equalswithCommand (string command) {if (command == null ||! command.equals (this.currentToken)) {return false ؛ } إعادة صواب ؛ } / ** * احصل على محتوى الأمر الحالي * * regurn * / string public getCurrentToken () {return this.currentToken ؛ } / ** * احصل على محتوى العقدة * * @RETURN * / السلسلة العامة getToKenContent (نص سلسلة) {String str = text ؛ إذا كان (str! = null) {// استبدل المحتوى المتغير ديناميكيًا في الخريطة وإرجاع ITerator <string> // استبدل المحتوى المتغير ديناميكيًا في الخريطة وإرجاع iterator <string> iterator = this.map.keyset (). iterator () ؛ بينما (iterator.hasnext ()) {string key = iterator.next () ؛ Object obj = map.get (مفتاح) ؛ str = str.replaceall (key ، obj.toString ()) ؛ }} return str ؛ } public void put (مفتاح السلسلة ، قيمة الكائن) {this.map.put (المفتاح ، القيمة) ؛ } public void clear (string key) {this.map.remove (key) ؛ }}4.2 واجهة التعبير - Iexpressions
package com.demo.InterPreter.express ؛ استيراد com.demo.InterPreter.Context.Context ؛/** * * واجهة التعبير * * Author * */واجهة عامة iexpressions {/** * parsing * * param context */public void context) ؛ / ** * طريقة التنفيذ * * Param Context */ public void تفسير () ؛}4.3 التعبير الرئيسي - programexpression
package com.demo.InterPreter.express ؛ استيراد com.demo.InterPreter.Context.Context ؛/** * تعبير البرنامج * * Author * */Pressure Class ProgramexPression ينفذ iexpressions {// بيئة السياق السياق النهائي السياق ؛ // Current Comment Private Final Static String Command = "Program" ؛ // قم بتخزين التعبيرات التالية التعبير التعبيرات الخاصة iexpressions ؛ / ** * يمرر المنشئ المحتوى ليتم تحليله في * * param text */ programexpression العامة (نص السلسلة) {this.context = new Context (text) ؛ this.parse (this.context) ؛ } Override public void parse (سياق السياق) {// احصل على عقدة الأمر الأول this.context.next () ؛ } / *** طريقة شرح التنفيذ* / Override public void تفسير () {// تحديد ما إذا كان يبدأ بالبرنامج إذا (! this.context.equalswithCommand (command)) {system.out.println ("" + command + "'' '' '' في البداية!") ؛ } آخر {// ابدأ هذا. context.next () مع البرنامج ؛ this.expressions = new listexpression () ؛ this.expressions.parse (this.context) ؛ // ListExpression Expression يبدأ تحليل هذا .expressions.InterPret () ؛ }}}4.4 قائمة التعبير - listexpression
package com.demo.InterPreter.express ؛ استيراد java.util.arraylist ؛ استيراد java.util.tiletator ؛ استيراد com.demo.interpreter.context.context ؛/** * قائمة التعبير * * Author * */فئة عامة تندم على iexpressions {context context ؛ arraylist النهائي الخاص <Iexpressions> list = new ArrayList <Iexpressions> () ؛ / ** * يمرر المنشئ السياق ليتم تحليله في * * param context */ public void parse (سياق السياق) {this.context = context ؛ // في تعبير تحليل ListExpression ، حلقة لتفسير كل كلمة في العبارة حتى يخرج تعبير المنهي أو استثناء بينما (صحيح) {if (this.context.getCurrentToken () == null) {// الحصول على العقدة الحالية. إذا كان NULL ، فهذا يعني أن التعبير النهائي مفقود system.out.println ("Error: The Expersion Missing 'End'!") ؛ استراحة؛ } آخر إذا (this.context.equalswithCommand ("end")) {this.context.next () ؛ // التحليل عادة ما ينتهي ؛ } آخر {// إنشاء التعبير التعبير IExpressions = commandexpersion جديد (this.context) ؛ // إضافة إلى list.add (تعبيرات) ؛ }}} / *** تنفيذ طريقة التفسير* / Override public void تفسير () {// حلقة شرح كل تعبير في القائمة لتنفيذ ITerator <Iexpressions> iterator = list.iterator () ؛ بينما (iterator.hasnext ()) {(iterator.next ()). تفسير () ؛ }}}4.5 تعبير الأوامر - commandexpersion
package com.demo.InterPreter.express ؛ استيراد com.demo.InterPreter.Context.Context ؛/** * التعبير عن الأمر * * Author * */commandexpersion public commandes iexpressions {سياق السياق النهائي الخاص ؛ تعبيرات iexpressions الخاصة ؛ / ** * طريقة البناء تمرر السياق ليتم تحليله في * * * param context */ public commandexperssion (سياق السياق) {this.context = context ؛ this.parse (this.context) ؛ } public void parse (Context Context) {// الحكم على فئة الأوامر الحالية ، تميز فقط عن الأمر الأصلي إذا (this.context.equalswithCommand ("for") {// إنشاء للتعبير عن تعبيرات التحليل = forexpression جديد (this.context) ؛ } else {// إنشاء تعبير أمر أصلي لتعبيرات تحليل المحتوى = new primitivitexpression (this.context) ؛ }} / *** محتوى التحليل* / Override public void تفسير () {// parsing content this.expressions.InterPret () ؛ }}4.6 تعبير حلقة - فرس العمل
package com.demo.InterPreter.express ؛ استيراد com.demo.InterPreter.Context.Context ؛/** * للتعبير * * Author * */فئة فصول عامة عامة تنفذ iexpressions {سياق السياق النهائي الخاص ؛ // قم بتخزين مفتاح الفهرس الحالي Value Private String Variable ؛ // قم بتخزين موضع بدء Loop Private int start_index ؛ // تخزين الموضع النهائي للحلقة الخاصة int end_index ؛ تعبيرات iexpressions الخاصة ؛ / ** * يمرر المنشئ السياق ليتم تحليله في السياق * * param */ forexpression العامة (سياق السياق) {this.context = context ؛ this.parse (this.context) ؛ } / *** تحليل التعبير* / Override public void parse (سياق السياق) {// أولاً احصل على العقدة الحالية this.context.next () ؛ بينما (صواب) {// ugne the node if (this.context.equalswithCommand ("from")) {// قم بتعيين سلسلة محتوى index start nextstr = this.context.next () ؛ حاول {this.start_index = integer.parseint (nextstr) ؛ } catch (استثناء e) {system.out .println ("خطأ: بعد" من "خطأ التعبير" ، يرجى التحقق من تنسيق التعبير صحيح! ") ؛ استراحة؛ } // الحصول على العقدة التالية this.context.next () ؛ } آخر إذا (this.context.equalswithCommand ("to")) {// قم بتعيين سلسلة محتوى end index nextstr = this.context.next () ؛ حاول {this.end_index = integer.parseint (nextstr) ؛ } catch (استثناء e) {system.out .println ("خطأ: بعد" إلى "خطأ التعبير موجود! يرجى التحقق من تنسيق التعبير صحيح!") ؛ } this.context.next () ؛ استراحة؛ } آخر {// قم بتعيين محتوى متغير الفهرس الحالي إذا (this.variable == null) {this.variable = this.context.getCurrentToken () ؛ } // الحصول على العقدة التالية this.context.next () ؛ }} // إنشاء قائمة تعبير this.expressions = new listexpression () ؛ this.expressions.parse (this.context) ؛ } / *** قم بتنفيذ طريقة التفسير* / Override public void تفسير () {// إنشاء تعبير أمر لـ (int x = this.start_index ؛ x <= this.end_index ؛ x ++) {// قم بتعيين المحتوى المتغير this.context.put ("+this.varable ، x) ؛ // تنفيذ طريقة التفسير this.expressions.Interpret () ؛ } // قم بإزالة المحتوى المتغير المؤقت المستخدم this.context.clear ("" + this.varable) ؛ }}4.7 التعبيرات الأساسية - PrimitiveExpression
package com.demo.InterPreter.express ؛ استيراد com.demo.InterPreter.Context.Context ؛/** * الأكثر تعبيرًا أساسيًا * * Author * */الطبقة العامة PrimitiveExpression ينفذ iexpressions {سياق السياق الخاص ؛ // اسم العقدة سلسلة خاصة Tokenname ؛ // نص محتوى النص الخاص ؛ / ** * يمرر المنشئ السياق ليتم تحليله في السياق * * param */ publicivitexpression (سياق السياق) {this.parse (context) ؛ } Override public void parse (سياق السياق) {this.context = context ؛ this.tokenName = this.context.getCurrentToken () ؛ this.context.next () ؛ if ("println" .equals (this.tokenName)) {this.text = this.context.getCurrentToken () ؛ this.context.next () ؛ }} / *** طريقة شرح التنفيذ* / Override public void تفسير () {// أولاً احصل على محتوى العقدة الحالي إذا ("println" .equals (tokenname)) {// الحصول على معلومات المحتوى // طباعة المحتوى system.out.println (this.context.gettokencontent (this.text)) ؛ }}}4.8 دع مترجم اللغة يبدأ العمل - العميل
package com.demo.InterPreter ؛ import com.demo.interpreter.express.iexpressions ؛ import com.demo.interpreter.express.programexpression ؛/** * application main * * @agring argan أنا من 90 إلى 100 println أنا نهاية println نهاية ... نهاية "؛ system.out.println ("str:" + str) ؛ // إنشاء تعبيرات التعبير IExpressions البرنامج = جديد programexpression (Str) ؛ // شرح تنفيذ التعبيرات. }}5 نتائج التشغيل
STR: برنامج println ابدأ ... من 90 إلى 100 println أنا نهاية println نهاية ... نهاية
يبدأ...
90
91
92
93
94
95
96
97
98
99
100
نهاية...
ثلاثة مبادئ تصميم
1 مبدأ "Open-Close"
2 مبدأ التغيير المغلق
أربع مناسبات الاستخدام
(1) يحدث نوع معين من المشكلة بتردد عالي ، وتتغير قواعد العمل بشكل متكرر ، وتحدث مواقف مماثلة بشكل متكرر.
(2) قواعد العمل ليست معقدة للغاية ومرهقة ، ومن الأسهل تجريد القواعد النحوية.
(3) الكفاءة ليست عاملاً رئيسياً في أنظمة البرمجيات.
مخطط فئة فئة ثابت
لمزيد من المحتوى المتعلق بـ Java ، يمكن للقراء المهتمين بهذا الموقع عرض الموضوعات: "مقدمة والبرمجة التعليمية المتقدمة حول البرمجة الموجهة إلى Java" ، و "البرنامج التعليمي حول بنية بيانات Java" و "خوارزمية" و "ملخص مهارات تشغيل Java" ، و "ملخص مهارات تشغيل Java" و "ملخصات Java Cate".
آمل أن يكون هذا المقال مفيدًا لبرمجة Java للجميع.