ما هي وظیفة المفسر (Compiler)؟

المفسر (Compiler)

تم إنشاء لغات البرمجة للسماح للمطورين بكتابة كود مصدر يمكن قراءته من قبل الإنسان. ومع ذلك، تعمل أجهزة الكمبيوتر مع كود الآلة (Machine code)، والذي يصعب على الناس كتابته أو قرائته. وبالتالي، يقوم المفسر (Compiler) بترجمة الكود المصدري للغة البرمجة إلى كود آلة مخصص لجهاز معين. سنحلل في هذه المقالة، مراحل عملية التجميع. بعد ذلك، سنرى الاختلافات بين المجمع و المفسر. أخيرًا، سنقدم أمثلة على بعض مُفسري لغات البرمجة الحديثة.

مراحل التفسیر

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

تتكون عملية التفسير من عدة مراحل:

  • التحليل المعجمي (Lexical analysis)
  • تحليل النحو (Syntax analysis)
  • التحليل الدلالي (Semantic analysis)
  • إنشاء کود وسيط (Intermediate code generation) 
  • التقويه (Optimization)
  • توليد الکود (Code generation)

سنناقش في هذا القسم، كل المراحل بالتفصيل.

التحليل المعجمي (lexical analysis)

التحليل المعجمي هو المرحلة الأولى من عملية التفسير. خلال هذه المرحلة، يقوم المفسر بتقسيم السورس كود إلى أجزاء تسمى المعجمات (lexemes) المعجم هو نفسه عضو من نظام المعجمی (lexical systen) للغة معينة. دعونا نحلل مثالًا بسيطًا:

String greeting = "hello";

في البيان أعلاه، لدينا خمسة معاجم:

  1. String
  2. Greeting
  3. 3.      =
  4. 4.      “hello”
  5. 5.      ;

بعد تقسيم الكود إلى lexemes، يتم إنشاء سلسلة من الرموز المميزة. تسلسل الرموز هو المنتج النهائي للتحليل المعجمي. (lexical analysis) وبالتالي، غالبًا ما يُطلق على التحليل المعجمي أيضًا اسم الرمز المميز. الرمز المميز هو كائن يصف المعجم. يقدم معلومات حول الغرض من lexeme، كما إذا كانت كلمة رئيسية أو اسم متغير أو سلسلة حرفية. علاوة على ذلك، فإنه يخزن بيانات موقع السورس كود

التحليل السینتکس

أثناء تحليل بناء الجملة، يستخدم المفسر سلسلة من الرموز المميزة التي تم إنشاؤها في المرحلة الأولى. تُستخدم الرموز لإنشاء هيكل يسمى شجرة بناء الجملة المجردة (AST)، إذ هي شجرة تمثل الهيكل المنطقي للبرنامج.

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

باختصار، تحليل النحو مسؤول عن مهمتين:

  • يتحقق من شفرة المصدر لأي خطأ في بناء الجملة.
  • يولد شجرة بناء جملة لمجرد أن تستخدمها في المرحلة التالية.

التحليل الدلالي

 في هذه المرحلة، يستخدم المفسر شجرة بناء جملة مجردة لاكتشاف أي أخطاء دلالية، على سبيل المثال:

  • إسناد النوع الخطأ إلى متغير
  • التصريح عن متغيرات بنفس الاسم في نفس النطاق
  • استخدام متغير غير معلن
  • استخدام الكلمة الرئيسية للغة كاسم متغير

يمكن تقسيم التحليل الدلالي إلى ثلاث خطوات:

  1. فحص النوع _ يفحص تطابق النوع في عبارات التخصيص والعمليات الحسابية والوظائف واستدعاءات الطريقة.
  2. فحص التحكم في التدفق (Flow Check) _ يتحقق مما إذا تم استخدام هياكل التحكم في التدفق بشكل صحيح وما إذا تم الوصول إلى الفئات والكائنات بشكل صحيح.
  3. فحص الملصقات _ يتحقق من صحة استخدام الملصقات والمعرفات.

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

إنشاء كود وسيط

أثناء عملية الکمبایل، يمكن للمفسر إنشاء واحد أو أكثر من نماذج الکودات البرمجية الوسيطة.

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

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

  1. عالي المستوى (High-level) _ مشابه للغة المصدر. في هذا النموذج، يمكننا بسهولة تعزيز أداء الكود المصدري. ومع ذلك، فهو أقل تفضيلاً لتحسين أداء الجهاز المستهدف.
  2. منخفض المستوى (Low-level) _ قريب من كود الآلة.(Machine Code) إنه مفضل لإجراء تحسينات متعلقة بالآلة.

التقوية

في مرحلة التحسين، يستخدم المترجم مجموعة متنوعة من الطرق لتعزيز كفاءة الكود. بالتأكيد، يجب أن تتبع عملية التحسين ثلاث قواعد مهمة:

  1. لا يمكن للكود الناتج تغيير المعنى الأصلي للبرنامج.
  2. يجب أن يركز التحسين على استهلاك موارد أقل وتسريع تشغيل البرنامج.
  3. يجب ألا تؤثر عملية التحسين بشكل كبير على الوقت الإجمالي للتجميع.

دعونا نرى بعض الأمثلة على تقنيات التقوية:

  1. تضمين الوظيفة _ استبدال استدعاء الوظيفة بجسمه.
  2. حذف الكود الميت _ يتخلص المفسر من الكود الذي لم يتم تنفيذه أبدًا.
  3. الانصهار الحلقي _ تنفيذ العمليات، في حلقة واحدة، من الحلقات المجاورة التي لها نفس شروط التكرار.
  4. دمج التعليمات _ يتم دمج التعليمات التي تحقق عمليات مماثلة في الوقت نفسه؛ على سبيل المثال، x = x + 10 ؛ x=x-7 ؛ يمكن استبداله بـ x = x + 3 ؛

إنتاج الکود (النهائي)

أخيرًا، يحول المفسر الشفرة الوسيطة الذي قام بتقویتها إلى كود الآلة (Machine Code) المخصص للجهاز الهدف. يجب أن يكون للشفرة النهائية نفس معنى الكود المصدري وأن تكون فعالة من حيث الذاكرة واستخدام موارد وحدة المعالجة المركزية. علاوة على ذلك، يجب أن تكون عملية إنشاء الكود فعالة أيضًا.

مثال عملي

في المخطط الانسيابي أدناه، يمكننا أن نرى مثالاً على عملية الکمبایل بيان بسيط:

Compiler مقابل Interpreter

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

  1. يحلل (يوزع) شفرة المصدر وينفذها مباشرة.
  2. يحول شفرة المصدر عالية المستوى إلى كود وسيط وينفذها على الفور.
  3. ينفذ صراحةً التعليمات البرمجية المخزنة المفسرة مسبقًا والتي تم إنشاؤها بواسطة مفسر. في هذه الحالة، ينتمي المفسر إلى نظام الإنتربرتر.

مقارنة موجزة بين Compiler و Interpreter

InterpreterCompiler
ينفذ الكود مباشرة.يحول الكود لكنه لا ينفذه.
لا حاجة لمعرفة الآلة الهدف ،
لأن الإنتربرتر يقوم بتنفيذ الكود.
يتطلب تنفيذ المفسر الی معرفة الآلة الهدف.
يمكن تحليل نفس التعليمات عدة مرات.تتم تفسیر كل تعليمة مرة واحدة فقط.
Ruby، Lisp، PHP، PowerShell.Java، C ++، Swift، C #.

أمثله للمفسرات

جاواك (Javac)

في Java، يتم أولاً تجميع التعليمات البرمجية المصدر إلى الرمز الثانوي (Byte Code) بواسطة مفسر javac. بعد ذلك، يقوم Java Virtual Machine (JVM) بانتربرت الرمز الثانوي. لذلك، يعد javac مثالًا ممتازًا للمترجم الذي ينتمي إلى نظام المترجم الفوري. مثل هذا النظام يجعل Java محمولة ومتعددة المنصات.

علاوة على ذلك، هناك لغات أخرى مثل Kotlin أو Scala يتم تجميعها أيضًا إلى رمز ثانوي (byte code)، ولكنها تستخدم مجمعات فريدة. وبالتالي، يمكن لـ JVM تنفيذ التعليمات البرمجية التي تمت كتابتها في الأصل باستخدام تقنيات مختلفة.

مونو (Mono)

Mono عبارة عن مجموعة أدوات ، بما في ذلك مفسر لغة البرمجة C # ، لتنفيذ البرامج المخصصة لـ .NET Platform. تم إنشاؤه للسماح بتشغيل تطبيقات .NET على منصات مختلفة. علاوة على ذلك، كان أحد الأهداف المهمة هو منح المطورين الذين يعملون على Linux بيئة وأدوات أفضل للعمل مع منصة .NET.

مجموعة مفسر جنو

مجموعة تفسير GNU (GCC) عبارة عن مجموعة من المفسرات مفتوحة المصدر (Open Source) اللاتي تنتمي إلى مشروع GNU. يمكن أن تعمل هذه المفسرات على منصات مختلفة للأجهزة والبرامج. لذلك، يمكنهم إنشاء كود الآلة لمختلف البنى وأنظمة التشغيل.

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

  • C (gcc)
  • C++ (g++)
  • Objective-C (gobjc)
  • Fortran (g77 and GFortran)
  • Java (gcj)
  • Ada (gnat)

خاتمة

وصفنا في هذه المقالة، دور المفسر (Compiler). علاوة على ذلك، مررنا بجميع مراحل عملية التفسیر وبعد ذلك ناقشنا الاختلافات بين المفسر والانتربرتر. أخيرًا، ذكرنا بعض أمثلة المترجم في العالم الحقيقي.

المصدر

منشور ذات صلة
JSON Web Token 7 Minutes

JSON Web Token | الجزء 1

جاسم ناظري

تم استخدام JSON Web Token لإرسال المعلومات التي يمكن التحقق منها والموثوق بها عن طريق التوقيع الرقمي. وهو يتألف من كائن JSON مضغوط وآمن لعناوين URL ويتم توقيعه بشكل مشفر للتحقق من أصالته.

فریم ورك Strapi 2 Minutes

فریم ورك Strapi headless CMS

فردوس مزرعاوي

يمكننا القول أن الهدف الأساسي من استخدام فریم ورك Strapi headless CMS، هو تطوير Front end في المواقع التي ليس لدينا طريق للوصول إلى مبرمج Back end أو ليس لدينا Back end أساسا.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

السلة