20

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

目前我正在将一个标记定义为 ('b'|'B' 'e'|'E' 'e'|'E' 'r'|'R') 但我有很多这样的标记,但实际上并没有想要处理'verilythisisaverylongtokenindeedomyyesitis'。

antlr wiki似乎暗示它不能完成(在 antlr 中)......但我只是想知道是否有人有一些聪明的技巧......

4

6 回答 6

37

我想补充一下已接受的答案:可以在不区分大小写的 antlr building blocks找到现成的集合,为方便起见,相关部分包括在下面

fragment A:[aA];
fragment B:[bB];
fragment C:[cC];
fragment D:[dD];
fragment E:[eE];
fragment F:[fF];
fragment G:[gG];
fragment H:[hH];
fragment I:[iI];
fragment J:[jJ];
fragment K:[kK];
fragment L:[lL];
fragment M:[mM];
fragment N:[nN];
fragment O:[oO];
fragment P:[pP];
fragment Q:[qQ];
fragment R:[rR];
fragment S:[sS];
fragment T:[tT];
fragment U:[uU];
fragment V:[vV];
fragment W:[wW];
fragment X:[xX];
fragment Y:[yY];
fragment Z:[zZ];

所以一个例子是

   HELLOWORLD : H E L L O W O R L D;
于 2014-03-04T00:06:04.483 回答
17

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

beer: B E E R;

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

等等

于 2009-12-04T03:10:52.140 回答
4

定义不区分大小写的标记

BEER: [Bb] [Ee] [Ee] [Rr];
于 2014-03-19T00:16:14.973 回答
1

ANTLR GitHub 存储库中出现了新的文档页面:Case-Insensitive Lexing。您可以使用两种方法:

  1. @javadba 的回答中描述的那个
  2. 或者在您的代码中添加一个字符流,这会将输入流转换为小写或大写。您可以在同一文档页面上找到主要语言的示例。

我认为,最好使用第一种方法并拥有描述所有规则的语法。但是,如果您使用众所周知的语法,例如为 ANTLR v4 编写的语法,那么第二种方法可能更合适。

于 2018-01-25T23:40:34.160 回答
1

ANTLR 刚刚添加了一个不区分大小写的选项

options { caseInsensitive = true; }

https://github.com/antlr/antlr4/commit/7bc825776357a0e6e7fc399bb0841d570a7e824b

旧链接现已断开,这些应继续有效。

于 2021-12-26T01:29:16.037 回答
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;
  }
}
于 2016-10-06T20:26:35.970 回答