كيف تكون * مترجم - اصنع مترجم مع جافا سكريبت

*نعم فعلا! يجب أن تكون مترجم. إنه رائع.

تم نشر هذا المنشور بموجب ترخيص CC BY-NC-SA 4.0. اسمحوا لي أن أعرف إذا كنت تترجم إلى لغات أخرى حتى أتمكن من إضافة إلى القائمة.

  • النسخة اليابانية من قبلي هنا
  • النسخة الصينية المبسطة بواسطةsqrtthree هنا
  • النسخة الكورية بواسطة @ whello64 ​​هنا
  • النسخة الاسبانية بواسطةrodkings هنا
  • Verizon البرتغالية بواسطةCarolinaPascale وCaiqueMitsuoka و @ felipesoares6_

الأحد الرائع في بوشويك ، بروكلين. لقد وجدت كتابًا بعنوان "Design by Numbers" للمخرج جون مايدا في محل بيع الكتب المحلي. في ذلك ، كان تعليم لغة DBN خطوة بخطوة - لغة تم إعدادها في أواخر التسعينيات في MIT Media Lab ، المصممة لتقديم مفاهيم برمجة الكمبيوتر بطريقة مرئية.

نموذج رمز DNB من http://dbn.media.mit.edu/introduction.html

اعتقدت أن إخراج SVG من DBN وتشغيله في المتصفح سيكون مشروعًا مثيرًا للاهتمام في عام 2016 بدلاً من تثبيت بيئة جافا لتنفيذ شفرة مصدر DBN الأصلية.

أحسب أنني سأحتاج إلى كتابة مترجم DBN إلى SVG ، لذلك بدأ البحث عن مترجم. يبدو "صنع برنامج التحويل البرمجي" مثل الكثير من علوم الكمبيوتر ... لكنني لم أتنقل مطلقًا إلى عقد في مقابلة الترميز ، فهل يمكنني إنشاء برنامج ترجمة؟

مترجم خيالي ، حيث يتم معاقبة رمز. إذا كانت الشفرة سيئة ، يتم التقاطها في رسالة الخطأ إلى الأبد.

دعونا نحاول أن أكون مترجمًا أولاً

المحول البرمجي عبارة عن آلية تأخذ قطعة من التعليمات البرمجية وتحولها إلى شيء آخر. دعنا نجمع كود DBN البسيط في رسم مادي.

هناك 3 أوامر في رمز DBN هذا ، "Paper" يحدد لون الورق ، "Pen" يحدد لون القلم ، و "Line" يرسم خطًا. 100 في معلمة اللون تعني 100٪ أسود أو rgb (0٪ ، 0٪ ، 0٪) في CSS. تكون الصورة المنتجة في DBN دائمًا بتدرج الرمادي. في DBN ، يكون الورق دائمًا 100 × 100 ، ويكون عرض الخط دائمًا 1 ، ويتم تعريف الخط بإحداثيات س ص لنقطة البداية ونقطة النهاية من الزاوية السفلية اليسرى.

دعونا نحاول أن أكون مترجمًا بنفسي. توقف هنا ، وانتزاع ورقة وقلم وحاول تجميع التعليمات البرمجية التالية كرسم.

ورقة 0
القلم 100
الخط 0 50 100 50

هل رسمت خطًا أسود في المنتصف من الجانب الأيسر إلى الجانب الأيمن؟ تهانينا! أنت فقط أصبحت مترجم.

نتيجة جمعت

كيف يعمل المترجم؟

دعونا ننظر إلى ما حدث للتو في رأسنا كمترجم.

1. التحليل المعجمى (الرمز المميز)

أول شيء فعلناه هو فصل كل الكلمات الرئيسية (تسمى الرموز) بمسافة بيضاء. بينما نفصل الكلمات ، قمنا أيضًا بتخصيص أنواع بدائية لكل رمز ، مثل "الكلمة" أو "الرقم".

تحليل معجمي

2. تحليل (التحليل النحوي)

بمجرد فصل نص من النص إلى رموز ، مررنا بكل منها وحاولنا إيجاد علاقة بين الرموز.
في هذه الحالة ، نقوم بتجميع الأرقام المرتبطة بكلمة الأوامر الرئيسية. من خلال القيام بذلك ، نبدأ في رؤية بنية الكود.

توزيع

3. التحول

بمجرد قيامنا بتحليل بناء الجملة عن طريق التحليل ، قمنا بتحويل الهيكل إلى شيء مناسب للنتيجة النهائية. في هذه الحالة ، سنقوم برسم صورة ، لذلك سنقوم بتحويلها إلى تعليم تدريجي للبشر.

تحويل

4. كود الجيل

أخيرًا ، نجعل نتيجة مجمعة ، رسمًا. في هذه المرحلة ، نتبع فقط الإرشادات التي قدمناها في الخطوة السابقة للرسم.

رمز الجيل

وهذا ما يفعله المترجم!

الرسم الذي توصلنا إليه هو النتيجة المترجمة (مثل ملف exe عند ترجمة رمز C). يمكننا تمرير هذا الرسم إلى أي شخص أو أي جهاز (الماسح الضوئي ، الكاميرا ، إلخ) إلى "تشغيله" وسيشاهد الجميع (أو الجهاز) خطًا أسود في المنتصف.

لنصنع مترجم

الآن بعد أن عرفنا كيف يعمل المترجمون ، دعنا نجعل واحدة في JavaScript. يأخذ هذا المترجم رمز DBN ويحولهم إلى رمز SVG.

1. وظيفة ليكسر

تمامًا كما يمكننا تقسيم الجملة الإنجليزية "لدي قلم" إلى [I ، لدي ، a ، قلم] ، يقوم المحلل اللغوي بتقسيم سلسلة التعليمات البرمجية إلى أجزاء صغيرة ذات معنى (الرموز). في DBN ، يتم تعيين كل رمز مميز بواسطة مسافات بيضاء ، وتصنف على أنها "كلمة" أو "رقم".

المدخلات: "ورقة 100"
انتاج:[
  {type: "word"، value: "Paper"}، {type: "number"، value: 100}
]

2. وظيفة محلل

يقوم المحلل بالانتقال عبر كل الرموز المميزة والعثور على المعلومات النحوية وإنشاء كائن يسمى AST (شجرة سياق الملخص). يمكنك التفكير في AST كخريطة لرمزنا - طريقة لفهم كيفية هيكلة جزء من الكود.

يوجد في الكود لدينا نوعان من بناء الجملة "NumberLiteral" و "CallExpression". NumberLiteral يعني أن القيمة هي رقم. يتم استخدامه كوسائط لـ CallExpression.

إدخال: [
  {type: "word"، value: "Paper"}، {type: "number"، value: 100}
]
انتاج: {
  "النوع": "الرسم" ،
  "الجسم": [{
    "النوع": "CallExpression" ،
    "الاسم": "ورقة" ،
    "الوسائط": [{"type": "NumberLiteral"، "value": "100"}]
  }]
}

3. وظيفة المحولات

يعد AST الذي أنشأناه في الخطوة السابقة جيدًا في وصف ما يحدث في الشفرة ، لكن ليس من المفيد إنشاء ملف SVG منه.
فمثلا. "الورق" هو ​​مفهوم موجود فقط في نموذج DBN. في SVG ، قد نستخدم عنصر لتمثيل ورقة. تقوم وظيفة Transformer بتحويل AST إلى AST آخر يسهل استخدام SVG.

إدخال: {
  "النوع": "الرسم" ،
  "الجسم": [{
    "النوع": "CallExpression" ،
    "الاسم": "ورقة" ،
    "الوسائط": [{"type": "NumberLiteral"، "value": "100"}]
  }]
}
انتاج: {
  "علامة": "svg" ،
  "attr": {
    "العرض": 100 ،
    "الارتفاع": 100 ،
    "viewBox": "0 0 100 100" ،
    "xmlns": "http://www.w3.org/2000/svg" ،
    "الإصدار": "1.1"
  }،
  "الجسم": [{
    "علامة": "rect" ،
    "attr": {
      "س": 0 ،
      "ص": 0 ،
      "العرض": 100 ،
      "الارتفاع": 100 ،
      "ملء": "rgb (0٪ ، 0٪ ، 0٪)"
    }
  }]
}

4. وظيفة مولد

كخطوة أخيرة من هذا المترجم ، تقوم دالة المولد بإنشاء كود SVG استنادًا إلى AST الجديد الذي قمنا به في الخطوة السابقة.

إدخال: {
  "علامة": "svg" ،
  "attr": {
    "العرض": 100 ،
    "الارتفاع": 100 ،
    "viewBox": "0 0 100 100" ،
    "xmlns": "http://www.w3.org/2000/svg" ،
    "الإصدار": "1.1"
  }،
  "الجسم": [{
    "علامة": "rect" ،
    "attr": {
      "س": 0 ،
      "ص": 0 ،
      "العرض": 100 ،
      "الارتفاع": 100 ،
      "ملء": "rgb (0٪ ، 0٪ ، 0٪)"
    }
  }]
}
انتاج:

  
  

5. ضعها معًا كمترجم

دعنا نطلق على هذا المترجم "برنامج التحويل البرمجي sbn" (SVG بواسطة برنامج التحويل البرمجي للأرقام).
نقوم بإنشاء كائن sbn باستخدام أساليب lexer ومحلل ومحول ومنشئ. ثم أضف طريقة "ترجمة" لاستدعاء جميع الطرق الأربعة في السلسلة.

يمكننا الآن تمرير سلسلة التعليمات البرمجية إلى طريقة الترجمة وإخراج SVG.

لقد أجريت عرضًا تفاعليًا يوضح لك نتائج كل الخطوات في هذا المترجم. تم نشر رمز برنامج التحويل البرمجي sbn على جيثب. أقوم بإضافة المزيد من الميزات إلى المترجم في الوقت الحالي. إذا كنت تريد التحقق من المترجم الأساسي الذي قمنا بإعداده في هذا المنشور ، يرجى مراجعة فرع بسيط.

https://kosamari.github.io/sbn/

ألا يجب على المترجم استخدام العودية والعبور وما إلى ذلك؟

نعم ، هذه كلها تقنيات رائعة لإنشاء مترجم ، لكن هذا لا يعني أن عليك اتباع هذا النهج أولاً.

لقد بدأت بجعل برنامج التحويل البرمجي لمجموعة فرعية صغيرة من لغة برمجة DBN ، مجموعة ميزات صغيرة محدودة للغاية. منذ ذلك الحين ، قمت بتوسيع النطاق والتخطيط الآن لإضافة ميزات مثل المتغير وكود الشفرة والحلقات إلى هذا المترجم. سيكون من الجيد استخدام هذه التقنية في هذه المرحلة ، ولكن لم يكن الشرط للبدء.

مترجم الكتابة رائع

ماذا يمكنك أن تفعل بجعل المترجم الخاص بك؟ ربما قد ترغب في إنشاء لغة جديدة تشبه JavaScript باللغة الإسبانية ... ماذا عن برنامج español؟

// ES (برنامج español)
función () {
  سي (verdadero) {
    عودة «ola هولا!»
  }
}

هناك أشخاص صنعوا لغة البرمجة في رموز تعبيرية (Emojicode) وفي صورة ملونة (لغة برمجة Piet). الاحتمالات لا حصر لها!

الدروس المستفادة من صنع مترجم

كانت عملية التحويل البرمجي ممتعة ، لكن الأهم من ذلك أنها علمتني الكثير عن تطوير البرامج. إليك بعض الأشياء التي تعلمتها أثناء عمل برنامج التحويل البرمجي الخاص بي.

كيف أتخيل المترجم بعد صنع نفسي

1. لا بأس أن يكون لديك أشياء غير مألوفة.

تمامًا مثل محلل المعجم لدينا ، لا تحتاج إلى معرفة كل شيء من البداية. إذا كنت لا تفهم حقًا رمزًا أو تقنية ، فلا بأس أن تقول "هناك شيء ، أعرف ذلك كثيرًا" ، ثم قم بنقله إلى الخطوة التالية. لا تضغط عليه ، سوف تصل إلى هناك في النهاية.

2. لا تكون رعشة مع رسالة خطأ سيئة.

دور Parser هو اتباع القاعدة والتحقق مما إذا كانت الأشياء مكتوبة وفقًا لتلك القواعد. لذلك ، مرات عديدة ، يحدث خطأ. عندما يحدث ذلك ، حاول إرسال رسائل مفيدة ومرحبة. من السهل أن تقول "إنه لا يعمل بهذه الطريقة" (مثل "رمز غير قانوني" أو "غير معروف ليس خطأ" في جافا سكريبت) ولكن حاول أن تخبر المستخدمين عما يجب أن يحدث قدر المستطاع.

وهذا ينطبق أيضا على التواصل الفريق. عندما يكون شخص ما عالقًا بسؤال ، بدلاً من قول "نعم هذا غير ناجح" ، ربما يمكنك البدء في قول "أود استخدام الكلمات الرئيسية من Google مثل ___ و ___" أو "أوصي بقراءة هذه الصفحة على الوثائق." يجب أن يقوموا بالعمل من أجلهم ، لكن يمكنك بالتأكيد مساعدتهم على أداء العمل بشكل أفضل وأسرع من خلال توفير المزيد من المساعدة.

العلم هو لغة البرمجة التي تتبنى هذه الطريقة. وضعوا "ربما تريد تجربة هذا؟" في رسالة الخطأ الخاصة بهم.

3. السياق هو كل شيء

أخيرًا ، تمامًا مثلما قام المحول لدينا بتحويل نوع AST إلى نوع آخر أكثر ملاءمة للنتيجة النهائية ، فكل شيء له سياق محدد.

لا توجد طريقة واحدة مثالية للقيام بالأشياء. لذلك لا تفعل الأشياء فقط لأنها شائعة أو قمت بها من قبل ، فكر في السياق أولاً. قد تكون الأشياء التي تعمل لمستخدم ما كارثة لمستخدم آخر.

أيضا ، نقدر العمل الذي تقوم به هذه المحولات. قد تعرف محولات جيدة في فريقك - شخص جيد حقًا في سد الفجوات. قد لا تنشئ تلك الأعمال التي يقوم بها المحولون رمزًا مباشرًا ، لكنه عمل مهم في إنتاج منتجات عالية الجودة.

أتمنى أن تكون قد استمتعت بهذا المنشور وآمل أن أقنعك بمدى روعة أن تكون بناءً ومترجمًا!

هذا مقتطف من الحديث الذي ألقيته في JSConf Colombia 2016 في ميديلين ، كولومبيا. إذا كنت تريد أن تعرف عن الحديث ، تحقق من الشرائح هنا.