الرمز المميز فارغ عند مطابقة القواعد على الرغم من مطابقة القاعدة
-
21-12-2019 - |
سؤال
لذلك قاعدتي هي
/* Addition and subtraction have the lowest precedence. */
additionExp returns [double value]
: m1=multiplyExp {$value = $m1.value;}
( op=AddOp m2=multiplyExp )* {
if($op != null){ // test if matched
if($op.text == "+" ){
$value += $m2.value;
}else{
$value -= $m2.value;
}
}
}
;
AddOp : '+' | '-' ;
اختباري هو 3 + 4
لكن op.text يُرجع دائمًا NULL ولا يُرجع حرفًا أبدًا.
هل يعرف أحد كيف يمكنني اختبار قيمة AddOp؟
في المثال من إجراءات وسمات ANTLR4 يجب أن تعمل:
stat: ID '=' INT ';'
{
if ( !$block::symbols.contains($ID.text) ) {
System.err.println("undefined variable: "+$ID.text);
}
}
| block
;
المحلول
هل أنت متأكد $op.text
دائما null
؟يبدو أن المقارنة الخاصة بك للتحقق منها $op.text=="+"
بدلا من التحقق من ذلك null
.
أبدأ دائمًا هذه الإجابات باقتراح ترحيل كل كود الإجراء الخاص بك إلى المستمعين و/أو الزوار عند استخدام ANTLR 4.سيؤدي ذلك إلى تنظيف القواعد النحوية الخاصة بك وتبسيط عملية الصيانة طويلة المدى للتعليمات البرمجية الخاصة بك إلى حد كبير.
ربما هذه هي المشكلة الأساسية هنا: مقارنة
String
يجب تنفيذ الكائنات في Java باستخدامequals
:"+".equals($op.text)
.لاحظ أنني استخدمت هذا الترتيب لضمان عدم حصولك على ملفNullPointerException
, ، حتى لو$op.text
يكونnull
.أوصي بإزالة
op=
التسمية والمرجعية$AddOp
بدلاً من.عند التبديل إلى استخدام المستمعين والزوار، ستؤدي إزالة التسمية الصريحة إلى تقليل حجم شجرة التحليل بشكل طفيف.
(ذو صلة فقط بالمستخدمين المتقدمين) في بعض حالات الحافة التي تتضمن أخطاء في بناء الجملة، قد لا يتم تعيين التسميات بينما لا يزال الكائن موجودًا في شجرة التحليل.على وجه الخصوص، يمكن أن يحدث هذا عندما يتم تعيين تسمية لمرجع القاعدة (ملفك
op
يتم تعيين التسمية لمرجع رمز مميز)، ويظهر خطأ داخل القاعدة المسماة.إذا قمت بالإشارة إلى كائن السياق عبر الطرق التي يتم إنشاؤها تلقائيًا في المستمع/الزائر، فستكون المثيلات متاحة حتى عندما لم يتم تعيين التصنيفات، مما يحسن قدرتك على الإبلاغ عن تفاصيل بعض الأخطاء.