سؤال

لدي القواعد 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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top