문제

"맥주"와 일치하고 싶지만 사례 민감도에 신경 쓰지 않는다고 가정 해 봅시다.

현재 나는 토큰을 ( 'b'| 'b' 'e'| 'e' 'e'| 'e' 'r'| 'r'로 정의하고 있지만 실제로는 많고 실제로는 그렇지 않습니다. 'Verily thisaverisalongtokenindeedocyyesitis'를 처리하고 싶습니다.

Antlr Wiki 그것을 할 수 없다고 제안하는 것 같습니다 (antlr에서) ...하지만 누군가가 영리한 속임수가 있는지 궁금했습니다 ...

도움이 되었습니까?

해결책

허용 가능한 식별자 문자에 대한 Lexer 토큰을 정의한 다음 구식 토큰을 일련의 일련의 토큰으로 구성하는 것은 어떻습니까?

beer: B E E R;

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

등.

다른 팁

허용 된 답변에 추가하고 싶습니다. 준비된 세트는 다음에서 찾을 수 있습니다. 케이스 insensitive 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에 나타납니다. 사례에 민감한 렉싱. 두 가지 접근 방식을 사용할 수 있습니다.

  1. @javadba의 답변에 설명 된 것
  2. 또는 코드에 문자 스트림을 추가하여 입력 스트림을 하위 또는 대문자로 변환합니다. 동일한 DOC 페이지에서 찾을 수있는 주요 언어의 예.

제 생각에는 첫 번째 접근 방식을 사용하고 모든 규칙을 설명하는 문법을 갖는 것이 좋습니다. 그러나 예를 들어 잘 알려진 문법을 사용하는 경우 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