البرمجة الموجهة نحو المكدس

البرمجة الموجهة نحو المكدس هي نموذج برمجي يعتمد على مكدس واحد أو أكثر لمعالجة البيانات و/أو تمرير المعاملات. تتطلب بنيات البرمجة في لغات البرمجة الأخرى تعديلًا لاستخدامها في نظام موجه نحو المكدس. [ 1 ] تعمل معظم لغات البرمجة الموجهة نحو المكدس بنظام التدوين اللاحق أو التدوين البولندي العكسي : حيث تُدرج وسائط أو معاملات الأمر قبل الأمر نفسه. على سبيل المثال، يُكتب التدوين اللاحق بدلًا2 3 multiply من التدوين السابق أو البولنديmultiply 2 3 ، أو التدوين الوسطي . تتوافق لغات البرمجة Forth و Factor و RPL و PostScript ولغة تصميم BibTeX [ 2 ] والعديد من لغات التجميع مع هذا النموذج.2 multiply 3

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

الخوارزميات القائمة على المكدس

تُعدّ لغة PostScript مثالاً على لغة برمجة تعتمد على بنية المكدس اللاحقة. مثال على تعبير في هذه اللغة هو 2 3 mul(حيث يُمثّل 'mul' أمر عملية الضرب). يتطلب حساب هذا التعبير فهم كيفية عمل بنية المكدس.

يمكن تمثيل اتجاه الرصّ بتشبيه سير ناقل. عند نهاية السير الناقل (نقطة الإدخال )، توضع ألواح تحمل العلامات من 1 إلى 2 2بالتسلسل . يمكن أخذ اللوح الموجود في نهاية السير (نقطة الإدخال )، ولكن لا يمكن الوصول إلى الألواح الأخرى إلا بعد إزالة اللوح الموجود في النهاية. لا يمكن تخزين الألواح إلا في رصّ، ولا يمكن إضافة أو إزالة أي منها إلا من أعلى الرصّ، وليس من المنتصف أو الأسفل. يمكن توفير ألواح فارغة (وعلامة)، ويمكن التخلص من الألواح نهائيًا.3mul2

خذ طبقًا 2وضعه على الرزمة، ثم خذ طبقًا آخر 3وضعه على الرزمة. بعد ذلك، خذ mulالطبق. هذه تعليمات للتنفيذ. ثم، خذ الطبقين العلويين من الرزمة، واضرب قيمتيهما ( 2و 3)، واكتب النتيجة ( 6) على طبق جديد. تخلص من الطبقين القديمين ( 2و 3) والطبق mul، وضع الطبق الجديد على الرزمة. عندما لا يتبقى أي أطباق على الناقل، ستظهر نتيجة العملية الحسابية ( 6) على الطبق الموجود أعلى الرزمة.

هذه عملية حسابية بسيطة للغاية. ماذا لو احتجنا إلى عملية حسابية أكثر تعقيدًا، مثل ؟ إذا كُتبت أولًا بصيغة لاحقة، أي ، فيمكن إجراء العملية الحسابية بنفس الطريقة تمامًا والحصول على النتيجة الصحيحة. تُوضح خطوات العملية الحسابية في الجدول أدناه. يُظهر كل عمود عنصر إدخال (اللوحة في نهاية الناقل)، ومحتويات الرزمة بعد معالجة هذا الإدخال.(2 + 3) × 11 + 12 3 add 11 mul 1 add

مدخل23يضيف11مول1يضيف
كومة23 2511 5551 5556

بعد معالجة جميع المدخلات، تحتوي المكدسة على 56، وهو الجواب.

من هذا، يمكن استنتاج ما يلي: لغة البرمجة القائمة على المكدس لا تملك إلا طريقة واحدة للتعامل مع البيانات، وهي سحب جزء من البيانات من أعلى المكدس (عملية تُسمى pop ping)، وإعادة البيانات إلى أعلى المكدس (عملية تُسمى push ing). أي تعبير يمكن كتابته بالطريقة التقليدية ، أو بلغة برمجة أخرى، يمكن كتابته بصيغة لاحقة (أو سابقة) وبالتالي يكون قابلاً للتفسير بواسطة لغة موجهة نحو المكدس.

التلاعب بالمكدس

بما أن المكدس هو الوسيلة الأساسية لمعالجة البيانات في لغات البرمجة الموجهة نحو المكدس، فإن هذه اللغات غالبًا ما توفر أنواعًا من عوامل معالجة المكدس. من بين هذه العوامل الشائعة: `<b>` dupلتكرار العنصر الموجود أعلى المكدس، exchو`<b swap>` لتبديل العناصر في أعلى المكدس (حيث يصبح الأول ثانيًا والثاني أولًا)، rollو`<b>` لتبديل العناصر بشكل دوري في المكدس أو في جزء منه، popو`<b drop>` لحذف العنصر الموجود أعلى المكدس (حيث يكون `<b>` ضمنيًا)، وغيرها. تُعد هذه العوامل أساسية في دراسة الإجراءات.

مخططات تأثير التراكم

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

(قبل -- بعد )

على سبيل المثال، يتم وصف عوامل تشغيل مكدس Forth الأساسية:

dup ( a -- aa ) drop ( a -- ) swap ( ab -- ba ) over ( ab -- aba ) rot ( abc -- bca )

الوظيفة fibالموضحة أدناه هي:

fib ( n -- n' )

يُعادل هذا المصطلح الشروط المسبقة والشروط اللاحقة في منطق هوار . ويمكن الإشارة إلى كلا التعليقين أيضاً على أنهما تأكيدات ، وإن لم يكن ذلك بالضرورة في سياق اللغات القائمة على المكدس.

مجموعات PostScript

تحتوي لغة PostScript وبعض لغات البرمجة الأخرى على مجموعات منفصلة لأغراض أخرى.

المتغيرات والقواميس

تم تحليل تقييم التعبيرات المختلفة مسبقًا. يُعدّ تطبيق المتغيرات أمرًا بالغ الأهمية لأي لغة برمجة، ولكنه يكتسب أهمية خاصة في اللغات الموجهة نحو المكدس، نظرًا لوجود طريقة واحدة فقط للتفاعل مع البيانات.

تتضمن طريقة تنفيذ المتغيرات في لغات البرمجة الموجهة نحو المكدس، مثل PostScript، عادةً مكدسًا منفصلاً ومتخصصًا يحتوي على قواميس من أزواج المفاتيح والقيم . لإنشاء متغير، يجب أولاً إنشاء مفتاح (اسم المتغير)، ثم ربط قيمة به. في PostScript، يُسبق اسم كائن البيانات بـ `<name>`، لذا فإن `<name>` هو /كائن /xبيانات اسم يمكن ربطه، على سبيل المثال، بالرقم `<n>` 42. defineالأمر هو `<name>` def، لذا فإن `<name>` هو `<name>`.

/x 42 def

يرتبط بالاسم xبالرقم الموجود 42في القاموس أعلى المكدس. يوجد فرق بينهما /xxفالأول هو كائن بيانات يمثل اسمًا، ويشير xإلى ما هو مُعرَّف تحت /x.

إجراءات

في لغات البرمجة القائمة على بنية المكدس، يُعامل الإجراء ككائن بيانات مستقل. أما في لغة PostScript، فيُشار إلى الإجراءات بين علامتي < {و </ }>.

على سبيل المثال، في صيغة PostScript،

{ dup mul }

يمثل إجراءً مجهولاً لتكرار ما هو موجود في أعلى المكدس ثم ضرب النتيجة - وهو إجراء تربيع.

بما أن الإجراءات تُعامل ككائنات بيانات بسيطة، فإنه يمكن تعريف أسماء تتضمن إجراءات. وعند استرجاعها، يتم تنفيذها مباشرةً.

توفر القواميس وسيلة للتحكم في نطاق التعريفات، بالإضافة إلى تخزين التعريفات.

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

تشريح بعض الإجراءات النموذجية

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

لفحص برنامج أعداد فيبوناتشي في لغة بوست سكريبت:

/fib { dup dup 1 eq exch 0 eq or not { dup 1 sub fib exch 2 sub fib add } if } def

يُستخدم تعريف تكراري على المكدس. تأخذ دالة أعداد فيبوناتشي وسيطًا واحدًا. أولًا، يتم اختباره لمعرفة ما إذا كان يساوي 1 أو 0.

تحليل كل خطوة من الخطوات الرئيسية للبرنامج، مع مراعاة بنية المكدس، بافتراض حساب ما يلي fib(4) :

 عدد الأكوام: 4 مكرر المكدس: 4 4 مكرر المكدس: 4 4 4 1 مكافئ المكدس: 4 4 خطأ صرافة المكدس: 4 خطأ 4 0 مكافئ المكدس: 4 خطأ خطأ أو المكدس: 4 خطأ لا المكدس: 4 صحيح

بما أن التعبير يُقيّم إلى صحيح، يتم تقييم الإجراء الداخلي.

 عدد الأكوام: 4 مكرر المكدس: 4 4 1 فرعي المكدس: 4 3 فيبوناتشي
(استدعاء متكرر هنا)
 المكدس: 4 F(3) صرافة المكدس: F(3) 4 2 فرعي المكدس: F(3) 2 فيبوناتشي
(استدعاء متكرر هنا)
 المكدس: F(3) F(2) يضيف المكدس: F(3)+F(2)

وهي النتيجة المتوقعة.

لا تستخدم هذه العملية متغيرات مُسماة، بل تعتمد كليًا على المكدس. يمكن إنشاء متغيرات مُسماة باستخدام /a exch defالبنية. على سبيل المثال،{/n exch def n n mul}

هي عملية تربيع بمتغير مُسمى n. بافتراض أن /sq {/n exch def n n mul} defو 3 sqيتم استدعاء ، يتم تحليل العملية sqبالطريقة التالية:

 المكدس: 3 /ن صرافة المكدس: /n 3 تعريف المكدس: فارغ (تم تعريفه) ن المكدس: 3 ن المكدس: 3 3 مول المكدس: 9

وهي النتيجة المتوقعة.

التحكم والتدفق

بما أن هناك إجراءات مجهولة المصدر، يمكن أن ينشأ التحكم في التدفق بشكل طبيعي. تتطلب عبارة if-then-else ثلاثة عناصر من البيانات : شرط، وإجراء يُنفذ إذا كان الشرط صحيحًا، وآخر يُنفذ إذا كان الشرط خاطئًا. في لغة PostScript على سبيل المثال،

2 3 gt { (2 أكبر من 3) = } { (2 ليس أكبر من 3) = } ifelse

يؤدي وظيفة مماثلة تقريبًا في لغة C:

إذا كان ( 2 > 3 ) { اطبع ( "2 أكبر من ثلاثة \n " ); } وإلا { اطبع ( "2 ليس أكبر من ثلاثة \n " ); }

تتشابه عمليات التكرار وغيرها من البنى.

تحليل نموذج اللغة

يُتيح النموذج البسيط المُقدّم في لغة البرمجة الموجهة نحو المكدس تفسير التعبيرات والبرامج بسهولة وتقييمها نظريًا بسرعة أكبر، إذ لا حاجة لتحليل بناء الجملة، بل يكفي التحليل المعجمي . تُسهّل طريقة كتابة هذه البرامج تفسيرها بواسطة الآلات، ولذلك يُعدّ PostScript مناسبًا جدًا للطابعات. مع ذلك، قد تُشكّل الطريقة المصطنعة نوعًا ما لكتابة برامج PostScript عائقًا مبدئيًا أمام فهم لغات البرمجة الموجهة نحو المكدس مثل PostScript.

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

انظر أيضاً

مراجع

  1. لورفيج، ت. (2015). نماذج البرمجة القائمة على المكدس. مفاهيم لغات البرمجة - CoPL'15، 33.
  2. أورين باتاشنيك، تصميم أنماط BibTeX (ملف PDF)