شيء آخر معلق
يُعدّ شرط "else" غير المُعلّق مشكلةً في برمجة مُولّدات المُحلّلات النحوية ، حيث يُمكن أن يُؤدّي وجود شرط "else" اختياري في عبارة " if–then(–else)" إلى غموض العبارات الشرطية المُتداخلة. وبصورةٍ رسمية، فإنّ قواعد اللغة المرجعية الخالية من السياق غامضة ، أي أنّ هناك أكثر من شجرة تحليل نحوي صحيحة .
وصف
في العديد من لغات البرمجة ، يمكن كتابة التعليمات البرمجية التي يتم تنفيذها بشكل مشروط بصيغتين: صيغة if-then، أو صيغة if-then-else. (عبارة else اختيارية).
إذا كان a فإن s، وإذا كان b فإن s1، وإلا فإن s2
يصبح التفسير الغامض ممكناً عند وجود عبارات متداخلة؛ وتحديداً عندما يحل شكل if-then-else محل العبارة sداخل بنية if-then المذكورة أعلاه:
إذا كان أ، فإن ب، فإن س1، وإلا فإن س2
في هذا المثال، s1يتم تنفيذ الشرط إذا وفقط إذا aكان الشرط الأول صحيحًا والشرطb الثاني صحيحًا. ولكن ماذا عن الشرط الثالث s2؟ قد يتأكد شخص ما من أن الشرط s2الأول يُنفذ عندما aيكون الشرط الثاني خاطئًا (بإضافة شرط " else" إلى الشرط الأول )، بينما قد يتأكد شخص آخر من أن الشرط الثاني s2يُنفذ فقط عندما aيكون الشرط الأول صحيحًا والشرطb الثاني خاطئًا (بإضافة شرط " else " إلى الشرط الثاني ) . بعبارة أخرى، يمكن تفسير العبارة السابقة على أنها مكافئة لأي من العبارتين التاليتين الواضحتين:
إذا كان a، فإن { إذا كان b، فإن s1 } وإلا فإن s2 إذا كان a، فإن { إذا كان b، فإن s1 وإلا فإن s2 }تعود مشكلة "الشرط المعلق" إلى لغة ALGOL 60 ، [ 1 ] وقد حلتها اللغات اللاحقة بطرق مختلفة. في محللات LR ، يُعد الشرط المعلق مثالًا نموذجيًا على تعارض الإزاحة والاختزال .
أمثلة
فيما يلي أمثلة ملموسة.
ج
في لغة C ، تنص القواعد النحوية جزئياً على ما يلي:
البيان = ... | بيان الاختيار بيان الاختيار = ... | عبارة IF (تعبير) | عبارة IF (تعبير) عبارة ELSE
وبالتالي، وبدون قواعد إضافية، فإن البيان
إذا ( أ ) إذا ( ب ) s ؛ وإلا s2 ؛يمكن تحليلها بشكل غامض كما لو كانت إما:
إذا ( أ ) { إذا ( ب ) s ؛ وإلا s2 ؛ }أو:
إذا ( أ ) { إذا ( ب ) s ؛ } وإلا s2 ؛يوضح معيار C أن elseالكتلة مرتبطة بأقرب كتلة if. [ 2 ] لذلك، يتم اختيار الشجرة الأولى.
أساليب لتجنب المشكلة
تجنب الغموض مع الحفاظ على بناء الجملة
تظهر هذه المشكلة غالبًا في بناء المترجمات ، وخاصةً في التحليل غير المعتمد على الماسح الضوئي . يتمثل العرف المتبع عند التعامل مع عبارة else المعلقة في ربطها بعبارة if المجاورة، [ 3 ] مما يسمح بقواعد نحوية خالية من السياق لا لبس فيها، على وجه الخصوص. تتبع لغات البرمجة مثل باسكال، [ 4 ] وسي، [ 2 ] وجافا [ 5 ] هذا العرف، لذا لا يوجد أي غموض في دلالات اللغة ، على الرغم من أن استخدام مولد محلل نحوي قد يؤدي إلى قواعد نحوية غامضة . في هذه الحالات، يتم تحقيق التجميع البديل بواسطة كتل صريحة، كما هو الحال begin...endفي باسكال [ 6 ] وسي {...}.
اعتمادًا على أسلوب بناء المترجم، يمكن اتخاذ إجراءات تصحيحية مختلفة لتجنب الغموض:
- إذا تم إنتاج المحلل اللغوي بواسطة مولد محللات SLR أو LR(1) أو LALR LR ، فغالبًا ما يعتمد المبرمج على ميزة المحلل المُولّد التي تُفضّل الإزاحة على الاختزال عند وجود تعارض. [ 3 ] بدلاً من ذلك، يمكن إعادة كتابة القواعد النحوية لإزالة التعارض، على حساب زيادة حجم القواعد النحوية (انظر أدناه ).
- إذا كان المحلل اللغوي مكتوبًا يدويًا، فيمكن للمبرمج استخدام قواعد نحوية غير مبهمة وخالية من السياق. أو بدلاً من ذلك، يمكن الاعتماد على قواعد نحوية غير خالية من السياق أو قواعد نحوية للتعبير التحليلي .
تجنب الغموض عن طريق تغيير الصيغة
يمكن حل المشكلة أيضاً بتوضيح العلاقة بين عبارة else وعبارة if الخاصة بها، ضمن الصيغة. وهذا يساعد عادةً على تجنب الأخطاء البشرية. [ 7 ]
الحلول الممكنة هي:
- تتضمن هذه اللغات رمز "end if" الذي يحدد نهاية بنية if. ومن أمثلة هذه اللغات: ALGOL 68 ، وAda ، وEiffel ، و PL/SQL ، و Visual Basic ، و Modula-2 ، و AppleScript .
- يُمنع أن تكون العبارة التي تلي كلمة "then" عبارة "if" بحد ذاتها (مع ذلك، قد تكون زوجًا من أقواس العبارات التي تحتوي فقط على شرط if-then). تتبع بعض تطبيقات لغة ALGOL 60 هذا النهج. [ 8 ]
- يتطلب استخدام الأقواس المعقوفة (الأقواس) عندما تأتي عبارة "else" بعد عبارة "if". [ 9 ]
- يتطلب ذلك أن يقترن كل شرط "if" بشرط "else".
- يستخدم S-algol كلمات مفتاحية مختلفة لعبارات "if" ذات البديل الواحد وذات
if e do sالبديلينif e1 then e2 else e3. [ 10 ] - يتطلب استخدام الأقواس بشكل غير مشروط، كما هو الحال في لغتي Swift و Rust . وهذا صحيح فعلياً في لغة Python لأن قواعد المسافة البادئة فيها تحدد كل كتلة، وليس فقط تلك الموجودة في عبارات "if".
تجنب التعارض في محللات LR
يمكن إعادة كتابة المثال أعلاه بالطريقة التالية لإزالة الغموض :
البيان: فتح_البيان | بيان مغلق ؛ open_statement: IF '(' expression ')' statement | إذا كانت العبارة '(' صحيحة، ')' مغلقة، وإلا فهي مفتوحة ؛ عبارة مغلقة: عبارة غير شرطية | إذا كانت العبارة '(' صحيحة)'، فسيتم إغلاق العبارة، وإلا فسيتم إغلاقها. ؛ non_if_statement: ... ؛ قد يتعين أيضًا تكرار أي قواعد نحوية أخرى متعلقة بالعبارات بهذه الطريقة إذا كانت قد تنتهي بشكل مباشر أو غير مباشر بحرف statementأو selection-statementرمز غير طرفي.
ومع ذلك، نقدم قواعد نحوية تتضمن كلاً من عبارات if و while.
البيان: فتح_البيان | بيان مغلق ؛ open_statement: IF '(' expression ')' statement | إذا كانت العبارة '(' صحيحة، ')' مغلقة، وإلا فهي مفتوحة | WHILE '(' expression ')' open_statement ؛ العبارة المغلقة: العبارة البسيطة | إذا كانت العبارة '(' صحيحة)'، فسيتم إغلاق العبارة، وإلا فسيتم إغلاقها. | WHILE '(' expression ')' closed_statement ؛ simple_statement: ... ؛ وأخيراً، نقدم القواعد النحوية التي تمنع عبارات IF الغامضة.
البيان: فتح_البيان | بيان مغلق ؛ open_statement: IF '(' expression ')' statement | إذا كانت العبارة '(' صحيحة، ')' مغلقة، وإلا فهي مفتوحة | WHILE '(' expression ')' open_statement ؛ العبارة المغلقة: العبارة البسيطة | إذا كانت العبارة '(' صحيحة)'، فسيتم إغلاق العبارة، وإلا فسيتم إغلاقها. | WHILE '(' expression ')' closed_statement ؛ simple_statement: ... ؛ if (a) if (b) c else dباستخدام هذه القواعد النحوية، لا يمكن تحليل العبارة إلا بطريقة واحدة، لأن التفسير الآخر ( if (a) {if (b) c} else d) ينتج على النحو التالي
إفادة بيان مفتوح إذا كانت العبارة '(' صحيحة، ')' مغلقة، وإلا فهي مفتوحة. 'if' '(' 'a' ')' closed_statement 'else' 'd' ثم يفشل التحليل عند محاولة المطابقة closed_statementمع "if (b) c". وتفشل محاولة أخرى closed_statementبنفس الطريقة. أما التحليل الآخر، if (a) {if (b) c else d}) فينجح.
إفادة بيان مفتوح عبارة IF '(' تعبير ')' IF '(' expression ')' closed_statement IF '(' a ')' (IF '(' expression ')' closed_statement ELSE closed_statement) IF '(' a ')' (IF '(' b ')' c ELSE 'd') انظر أيضاً
مراجع
- ↑ أبراهامز، ب. و. (1966). "حل نهائي لمشكلة "الحالة المعلقة" في لغة ALGOL 60 واللغات ذات الصلة" . مجلة اتصالات رابطة الحوسبة الآلية . 9 (9): 679-682 . doi : 10.1145/365813.365821 . S2CID 6777841 .
- 1 2 ISO 9899 :1999 (C): 6.8.4.1(3): "يتم ربط كلمة else بأقرب كلمة سابقة معجميًا إذا كان ذلك مسموحًا به في بناء الجملة."، متاح في WG14 N1256 ، ص 134
- 1 2 "5.2 تعارضات Shift/Reduce" . Bison 3.8.1 . GNU . تم الاسترجاع في 2021-08-07 .
- ↑ ISO 7185:1990 (Pascal) 6.8.3.4: لا يجوز أن يتبع عبارة if بدون جزء else مباشرةً الرمز else.
- ↑ "مواصفات لغة جافا، إصدار جافا SE 9، 14.5. العبارات" .
- ↑ ديل، نيل ب.؛ ويمز، تشيب (نوفمبر 1996). "العناصر المعلقة الأخرى". مقدمة في لغة باسكال والتصميم الهيكلي . جونز وبارتليت للتعليم. ص 160-161 . ISBN 9780763703974.
- ↑ غموض عبارة else المعلقة: القواعد النحوية غير الخالية من السياق مبهمة دلاليًا
- ↑ 4.5.1 العبارات الشرطية — بناء الجملة في P. Nauer (محرر)، التقرير المنقح عن لغة الخوارزميات ALGOL 60 ، CACM 6,1، 1963، الصفحات 1-17
- ↑ غموض عبارة else المعلقة: يجب استخدام الأقواس عندما تتبع عبارة else عبارة if
- ↑ ديفي، أنتوني جيه تي؛ رونالد موريسون (1981)، برايان ميك (محرر)، الترجمة التنازلية المتكررة ، سلسلة إليس هوروود في الحواسيب وتطبيقاتها، تشيتشستر، غرب ساسكس: إليس هوروود، ص 20، ISBN 0-470-27270-8
- الغموض
- برمجة الحاسوب
- البنى الشرطية
- التحليل
