如何匹配字符串,但不区分大小写?

时间:2009-12-04 02:55:02

标签: antlr antlr3

假设我想匹配“啤酒”,但不关心区分大小写。

目前我正在定义一个令牌('b'|'B''e'|'E''e'|'E''r'|'R')但我有很多这样的东西我真的很想处理'verilythisisaverylongtokenindeedomyyesitis'。

antlr wiki seems to suggest that it can't be done(在antlr中)...但我只是想知道是否有人有一些聪明的伎俩......

5 个答案:

答案 0 :(得分:26)

我想补充一下接受的答案:可以在case insensitive antlr building blocks找到现成的套装,为方便起见,下面包含相关部分

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;

答案 1 :(得分:15)

如何为每个允许的标识符字符定义词法分析器标记,然后将解析器标记构造为一系列那些?

beer: B E E R;

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

答案 2 :(得分:2)

使用

定义不区分大小写的标记
BEER: [Bb] [Ee] [Ee] [Rr];

答案 3 :(得分:1)

新文档页面出现在ANTLR GitHub repo:Case-Insensitive Lexing中。您可以使用两种方法:

  1. @ javadba回答
  2. 中描述的那个
  3. 或者在代码中添加字符流,这会将输入流转换为大写或大写。您可以在同一个doc页面上找到主要语言的示例。
  4. 我认为,使用第一种方法并使用描述所有规则的语法会更好。但是如果你使用着名的语法,例如来自Grammars written for ANTLR v4,那么第二种方法可能更合适。

答案 4 :(得分:0)

我在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;
  }
}