Antlr Hidden Channel Whitespace مشكلة
-
18-09-2019 - |
سؤال
لدي القواعد antlr التالية:
grammar MyGrammar;
doc : intro planet;
intro : 'hi';
planet : 'world';
MLCOMMENT
: '/*' ( options {greedy=false;} : . )* '*/' { $channel = HIDDEN; };
WHITESPACE : (
(' ' | '\t' | '\f')+
|
// handle newlines
( '\r\n' // DOS/Windows
| '\r' // Macintosh
| '\n' // Unix
)
)
{ $channel = HIDDEN; };
في AntlrWorks 1.2.3 مترجم، المدخلات hi world
,hi/**/world
و hi /*A*/ world
العمل، كما هو متوقع.
ومع ذلك، فإن المدخلات hiworld
, ، أي لا ينبغي ذلك العمل، مقبول أيضا. كيف أفعل hiworld
يفشل؟ كيف أقوم بإجبار مساحة تبيس واحدة على الأقل (أو تعليق) بين "مرحبا" و "العالم"؟
لاحظ أنني استخدمت MLComment و Whitespace فقط في هذا المثال لتبسيطها، ولكن سيتم دعم أنواع أخرى من التعليقات.
المحلول
تحتاج إلى إنشاء رمز معرف عام. نظرا لأن Lexer يبني أطول رمزية يمكنها، فسيشهد الإدخال "Hiworld" ككلمة واحدة لأنها أطول من "مرحبا" أو "العالم" بنفسها. مثل هذه القاعدة قد تبدو:
ID : ('a'..'z' | 'A'..'Z')+;
كمثال، هذا هو بالضبط كيفية فصل المحللين لغات البرمجة عن "القيام" الكلمة الرئيسية من "Double" (نوع الكلمة الرئيسية، يبدأ ب "القيام") أو "تم" (اسم متغير).
نصائح أخرى
طريقة واحدة لجعل السلسلة hiworld
FAIL هو استخدام المسند الدليلي للتحقق من الصحة المضمونة للفشل، كما يلي:
doc: intro planet;
failure : 'hiworld' { false }?;
intro : 'hi';
planet : 'world';
// rest of grammar omitted