كيفية تتناسب مع سلسلة، ولكن على حدة معتدلة؟

StackOverflow https://stackoverflow.com/questions/1844562

  •  12-09-2019
  •  | 
  •  

سؤال

دعنا نقول أنني أريد مطابقة "البيرة"، لكن لا يهتم بحساسية الحالة.

حاليا أنا أعرف رمز رمزي ليكون ('B' | 'B' E '| "E" | "E" | "E" | "R") ولكن لدي الكثير من هذه الأشياء ولا حقا تريد التعامل مع "verilythisisaverylongtokenindealyesyes".

antlr ويكي يبدو أن تشير إلى أنه لا يمكن القيام به (في Antlr) ... لكنني تساءلت فقط إذا كان أي شخص لديه بعض الحيل الذكية ...

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

المحلول

ماذا عن تحديد رمزية Lexer لكل حرف معرف مسموح به، ثم قم ببناء الرمز المميز للمحلل كسلسلة من هؤلاء؟

beer: B E E R;

A : 'A'|'a';
B: 'B'|'b';

إلخ.

نصائح أخرى

أود أن أضيف إلى الإجابة المقبولة: يمكن العثور على مجموعة جاهزة الحالات غير حساس لبنات بناء Antlr, ، والجزء ذو الصلة المدرجة أدناه للراحة

fragment A:('a'|'A');
fragment B:('b'|'B');
fragment C:('c'|'C');
fragment D:('d'|'D');
fragment E:('e'|'E');
fragment F:('f'|'F');
fragment G:('g'|'G');
fragment H:('h'|'H');
fragment I:('i'|'I');
fragment J:('j'|'J');
fragment K:('k'|'K');
fragment L:('l'|'L');
fragment M:('m'|'M');
fragment N:('n'|'N');
fragment O:('o'|'O');
fragment P:('p'|'P');
fragment Q:('q'|'Q');
fragment R:('r'|'R');
fragment S:('s'|'S');
fragment T:('t'|'T');
fragment U:('u'|'U');
fragment V:('v'|'V');
fragment W:('w'|'W');
fragment X:('x'|'X');
fragment Y:('y'|'Y');
fragment Z:('z'|'Z');

لذلك مثال على ذلك

   HELLOWORLD : H E L L O W O R L D;

تحديد الرموز غير الحساسة للحالة مع

BEER: [Bb] [Ee] [Ee] [Rr];

ظهرت صفحة الوثائق الجديدة في antlr github repo: LEXING غير حساس. وبعد يمكنك استخدام نهجين:

  1. الواحد الموصوف في إجابة @ جافادبا
  2. أو إضافة مجرى الحرف إلى التعليمات البرمجية الخاصة بك، مما سيحول دفق الإدخال إلى حالة أقل أو أعلى. أمثلة للغات الرئيسية التي يمكنك العثور عليها في نفس صفحة الوثيقة.

رأيي، من الأفضل استخدام النهج الأول والحصول على القواعد التي تصف جميع القواعد. ولكن إذا كنت تستخدم قواعد قواعد معروفة، على سبيل المثال من النحو المكتوبة ل Antlr V4, ، ثم النهج الثاني قد يكون أكثر ملاءمة.

الحل الذي استخدمته في C #: استخدام رمز ASCII لتحويل الحرف إلى حالة أصغر.

class CaseInsensitiveStream : Antlr4.Runtime.AntlrInputStream {
  public CaseInsensitiveStream(string sExpr)
     : base(sExpr) {
  }
  public override int La(int index) {
     if(index == 0) return 0;
     if(index < 0) index++;
     int pdx = p + index - 1;
     if(pdx < 0 || pdx >= n) return TokenConstants.Eof;
     var x1 = data[pdx];
     return (x1 >= 65 && x1 <= 90) ? (97 + x1 - 65) : x1;
  }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top