سؤال

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

ExpressionTerm := "asd"
LogicalExpression :=
    ExpressionTerm |
    LogicalExpression "AND" LogicalExpression |
    LogicalExpression "OR" LogicalExpression

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

وأضاف: لتوضيح - "ASD" هو ببساطة سلسلة حرفية "ASD". لذلك أتوقع أن يتم تحليل التعبيرات التالية من قبل هذا القواعد:

asd
asd AND asd
asd AND asd OR asd
asd OR asd AND asd OR asd

وأضاف 2: نسيت أن أقول، جذر القواعد هو LogicalExpression.

وأضاف 3: آه، حصلت عليه! الغموض لأن التعبير مثل

asd AND asd OR asd

يمكن تفسيرها بطريقتين مختلفتين:

(asd AND asd) OR asd
asd AND (asd OR asd)

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

LogicalExpression := "asd" | LogicalExpression "OR" LogicalExpression

في هذه الحالة أريد هذا:

asd OR asd OR asd

أن تحلل هذا:

(asd OR asd) OR asd

ما هي الطريقة غير الغامضة للقيام بذلك؟

وأضاف 4: فهمتك!

LogicalExpression1 := LogicalExpression1 "OR" LogicalExpression2 | LogicalExpression2
LogicalExpression2 := LogicalExpression2 "AND" LogicalExpression3 | LogicalExpression3
LogicalExpression3 := "NOT" LogicalExpression4 | LogicalExpression4
LogicalExpression4 := "asd" | "(" LogicalExpression1 ")"

يؤدي هذا إلى تبييض جميع التعبيرات المنطقية، مع أسبقية المشغل غير الواحدة وغير> أو. يمكن استبدال "ASD" بالتعبير المقصود بشروطك.

هل كانت مفيدة؟

المحلول

قواعد القواعد الخاصة بك غامضة، إذا كنت تستخدم نظرة واحدة فقط. للتوضيح، ما هو "ASD"؟ هل هو تعبيرية أو مصطلح أطول. هذا هو التحول - قلل من الصراع. أظن أن تقليل النزاع هنا أيضا.

ستوفر معظم مولدات (1) / LALR (1) طريقة للتعامل مع الصراع من الصراع من قبل مشغلي الأسبقية. سيعمل معظمها أيضا على أطول تسلسل في وجود تعارض للحد من التحول، لذلك يمكن تجاهلها أكثر من غالبا ما يتم تجاهلها (بعد بعض التدقيق). (في هذه الحالة، ربما تحتاج إلى نقل المصطلح الفردي إلى الأسفل لتتصرف بشكل صحيح).

نصائح أخرى

التعارض في التحول يعني أن القواعد الخاصة بك غامضة. مع القاعدة العودية الخاصة بك يمكن تفسير الرمز المميز "ASD" كجزء من إما ExpressionTerm أو LogicalExpression والتحلل لا يمكن أن يقرر ذلك. بحاجة إلى قاعدة إضافية لكسر التعادل.

تحول تقليل النزاعات هي واحدة من الأشياء الأكثر صعوبة في الحصول على عقلك عندما يتعلق الأمر المحللين. أسهل طريقة لتوضيح الصراع في هذا الرمز الزائدي:

if (a) then
   if (b) then
     printf('a + b');
   else
     print('this could be a + !b or !a');

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

بدلا من ذلك، يمكنك استخدام محلل LL (K) أو LL (*). لا تحتوي هذه الأنواع من المحللين على التحول / الحد من الغموض. اعتمادا على طلبك قد يكون من الأسهل أو أكثر صعوبة من محلل Lalr (1).

القواعد غامضة في LL(1) أو LALR(1) منذ رمز ASD يمكن استبدالها ExpressionTerm و أيضا LogicalExpression تتسطح قواعد النحوية لحل التحول / الحد من النزاعات

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top