Как сопоставить строку, но без учета регистра? - PullRequest
17 голосов
/ 04 декабря 2009

Допустим, я хочу сопоставить «пиво», но не заботиться о чувствительности к регистру.

В настоящее время я определяю токен как ('b' | 'B' 'e' | 'E' 'e' | 'E' 'r' | 'R'), но у меня много таких и на самом деле не хочу справляться с «истинно этой болезнью».

Antlr wiki , похоже, говорит о том, что это невозможно сделать (в antlr) ... но я просто удивился, если у кого-нибудь есть какие-нибудь умные трюки ...

Ответы [ 5 ]

26 голосов
/ 04 марта 2014

Я хотел бы добавить к принятому ответу: готовый набор можно найти в строительных блоках, не учитывающих регистр , и соответствующую часть, включенную ниже для удобства

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;
15 голосов
/ 04 декабря 2009

Как насчет определения токена лексера для каждого допустимого идентификатора символа, а затем построения токена синтаксического анализатора как серии из них?

beer: B E E R;

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

и т.д.

2 голосов
/ 19 марта 2014

Определите нечувствительные к регистру токены с помощью

BEER: [Bb] [Ee] [Ee] [Rr];
1 голос
/ 26 января 2018

В репозитории ANTLR GitHub появилась новая страница документации: Лексинг без учета регистра . Вы можете использовать два подхода:

  1. Тот, который описан в ответе @ javadba
  2. Или добавьте символьный поток в ваш код, который преобразует входной поток в нижний или верхний регистр. Примеры основных языков вы можете найти на той же странице документации.

Мое мнение, лучше использовать первый подход и иметь грамматику, которая описывает все правила. Но если вы используете хорошо известную грамматику, например из Грамматики, написанной для ANTLR v4 , тогда второй подход может быть более подходящим.

0 голосов
/ 06 октября 2016

Решение, которое я использовал в 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;
  }
}
...