Como encontrar uma string, mas caso insensível?
Pergunta
Vamos dizer que eu quero corresponder "cerveja", mas não se preocupam com maiúsculas e minúsculas.
Atualmente eu estou definindo um token para ser ( 'b' | 'B' 'e' | 'E' 'e' | 'E' 'r' | 'R'), mas eu tenho um monte de tal e don 't realmente quer alça 'verilythisisaverylongtokenindeedomyyesitis'.
O antlr wiki parece sugerir que ele não pode ser feito (em antlr) ... mas eu só queria saber se alguém tinha alguns truques inteligentes ...
Solução
Como cerca de definir um lexer token para cada personagem identificador permitido, em seguida, construir o analisador de token como uma série desses?
beer: B E E R;
A : 'A'|'a';
B: 'B'|'b';
etc.
Outras dicas
Eu gostaria de adicionar à resposta aceita: um conjunto made pronto pode ser encontrada no blocos de construção insensível caso antlr , ea parte relevante incluída abaixo por conveniência
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');
Assim, um exemplo é
HELLOWORLD : H E L L O W O R L D;
Definir case-insensitive fichas com
BEER: [Bb] [Ee] [Ee] [Rr];
Nova página de documentação já apareceu em ANTLR repositório no GitHub: case-Insensitive Lexing . Você pode usar duas abordagens:
- A descrito no @ de javadba resposta ??li>
- Ou adicionar um fluxo de caracteres ao seu código, que vai transformar um fluxo de entrada para abaixar ou maiúsculas. Exemplos para os principais idiomas que você pode encontrar na mesma página doc.
A minha opinião, é melhor usar a primeira abordagem e têm a gramática que descreve todas as regras. Mas se você usar a gramática bem conhecido, por exemplo, de gramáticas escritas para ANTLR v4 , então segunda abordagem pode ser mais apropriado.
A solução que eu usei em C #:. Use o código ASCII para caracteres mudança para caso menor
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;
}
}