أسبقية المشغل أو قاعدة Munch القصوى تأتي أولاً للمشغلين الأحاديين
-
21-12-2019 - |
سؤال
هنا لدي القطعة التالية من الكود:
int a,b,x;
a=b=1;
x=a+++b;
الآن قيمة x
سيكون 2 كما a
هو الكائن الأول تمت زيادة المشاركة ومن ثم يتم إضافتها إلى b
.
فيما يلي رمز البايت المترجم:
0 iconst_1
1 dup
2 istore_2 [b]
3 istore_1 [a]
4 iload_1 [a]
5 iinc 1 1 [a]
8 iload_2 [b]
9 iadd
10 istore_3 [x]
لذلك فإن التعبير سيكون معادلاً لـ x = (a++) + b
.
الآن التعبير الآخر x=a++++b
, ، لن يتم تجميعها بسبب قاعدة مونش القصوى.سوف تأتي x = (a++) ++ b
وبالتالي خطأ في التجميع.
هو السلوك أعلاه ل x=a+++b
بسبب أسبقية المشغل ++ أو بسبب قاعدة مونش القصوى?
المحلول
نقلا عن الترجمات المعجمية:
يتم استخدام أطول ترجمة ممكنة في كل خطوة ، حتى لو لم تصنع النتيجة في نهاية المطاف برنامجًا صحيحًا في حين أن ترجمة معجمية أخرى ستقوم بذلك.
وهكذا، أحرف الإدخال أ-ب تم ترميزها (§3.5) مثل أ, --, ب، وهو ليس جزءًا من أي برنامج صحيح نحويًا ، على الرغم من الرمز المميز أ, -, -, ب يمكن أن يكون جزءًا من برنامج صحيح نحويًا.
وهذا من شأنه أن يفسر السبب
x=a+++b
يتم تحليلها كما
x=(a++)+b
على الجانب الآخر، a++++b
تم ترميزه كـ أ++, ++, ب مما يسبب خطأ.
نصائح أخرى
الحد الأقصى هو قاعدة يتم استخدامها في المعجم، وأسبقية عامل التشغيل في المحلل اللغوي، ويتم تشغيل المعجم من الناحية المفاهيمية قبل المحلل اللغوي.لذلك، x=a+++b
يتم تحويله إلى x=(a++)+b
بسبب قاعدة Munch القصوى، وليس أسبقية عامل التشغيل:
عندما يرى ليكسر a+++b
سوف يحول هذا إلى رموز مميزة [identifier a
] [زائد مزدوج] [زائد] [المعرف b
].يعود رمز [double plus] إلى الحد الأقصى (خذ أطول تطابق، و ++
اطول من +
).يمكن للمحلل بعد ذلك تحويل هذا فقط إلى (a++)+b بغض النظر عن أسبقية عامل التشغيل.
يتم التعرف على العامل الأحادي "++" فقط عندما يكون هناك متغير على يسار "++".عندما تكتب a+++b، فإن علامة الزائد الثالثة هي العامل الثنائي "add"، بينما العامل الأول (++) هو "متغير الزيادة بمقدار 1".عندما تكتب "a++++"، تفشل الأشياء لأن هذا يشبه الكتابة a<unary increment variable by 1> <add> <add>
وهناك حجة مفقودة للمشغل الأول.لم يتم التعرف على الزوج الثاني من علامات الجمع باعتباره "متغير زيادة" لأن (a++) ليس متغيرًا.
ومن المثير للاهتمام الآن أن مترجم Java يتطلب حاليًا مساحة بيضاء للتعرف عليه بشكل صحيح
z = a++ + ++b; // this works
z = a+++++b; // this fails
باعتباري كاتبًا قديمًا للمترجمات، أتوقع أن يتم تقييم كلا البنيتين من الناحية النحوية على أنهما نفس الشيء (مع التعرف على العاملين الأحاديين ++ و++)