수색…


간단한 규칙

렉서 규칙은 토큰 유형을 정의합니다. 그들의 이름은 파서 규칙과 구별하기 위해 대문자로 시작해야합니다.

INTEGER: [0-9]+;
IDENTIFIER: [a-zA-Z_] [a-zA-Z_0-9]*;

OPEN_PAREN: '(';
CLOSE_PAREN: ')';

기본 구문 :

통사론 의미
A 렉서 규칙 또는 조각 A 와 일치
AB 경기 A 다음에 B
(A|B) A 또는 B 중 하나와 일치
'text' 리터럴 "텍스트" 일치
A? 일치 0 또는 1 시간 A
A* 일치 0 번 이상 A
A+ A 번 이상 A 매치
[A-Z0-9] 정의 된 범위 (이 예에서는 AZ 또는 0-9 사이)에서 한 문자를 일치시킵니다.
'a'..'z' 문자 범위의 대체 구문
~[AZ] 범위의 부정 - 범위에 없는 단일 문자와 일치
. 한 문자와 일치

파편

단편은 렉서 규칙의 재사용 가능한 부분으로 독자적으로는 일치 할 수 없으며 렉서 규칙에서 참조해야합니다.

INTEGER: DIGIT+
       | '0' [Xx] HEX_DIGIT+
       ;

fragment DIGIT: [0-9];
fragment HEX_DIGIT: [0-9A-Fa-f];

암시 적 렉서 규칙

파서 규칙에서 '{' 와 같은 토큰을 사용하면 명시 적 규칙이 없으면 암시 적 렉서 규칙이 만들어집니다.

즉, 렉서 규칙이있는 경우 :

OPEN_BRACE: '{';

다음 두 파서 규칙은 동일합니다.

parserRule: '{';
parserRule: OPEN_BRACE;

그러나 OPEN_BRACE 렉서 규칙이 정의되어 있지 않으면 묵시적 익명 규칙이 생성됩니다. 이 경우 암시적인 규칙은 다른 규칙 보다 먼저 정의 된 것처럼 정의 됩니다 . 다른 규칙보다 우선 순위가 높습니다.

우선 순위 규칙

여러 개의 렉서 규칙은 동일한 입력 텍스트와 일치 할 수 있습니다. 이 경우 토큰 유형은 다음과 같이 선택됩니다.

  • 먼저, 가장 긴 입력과 일치하는 렉서 규칙을 선택하십시오
  • 텍스트가 암시 적으로 정의 된 토큰 (예 : '{' )과 일치하면 암시 적 규칙을 사용하십시오
  • 여러 개의 렉서 규칙이 동일한 입력 길이와 일치하면 정의 순서에 따라 첫 번째 규칙을 선택하십시오

다음의 결합 된 문법 :

grammar LexerPriorityRulesExample;

// Parser rules

randomParserRule: 'foo'; // Implicitly declared token type
    
// Lexer rules
    
BAR: 'bar';
IDENTIFIER: [A-Za-z]+;
BAZ: 'baz';

WS: [ \t\r\n]+ -> skip;

주어진 다음과 같은 입력 :

aaa foo bar baz barz

렉서에서 다음과 같은 토큰 시퀀스를 생성합니다 :

IDENTIFIER 'foo' BAR IDENTIFIER IDENTIFIER
  • aaaIDENTIFIER 유형입니다.

    IDENTIFIER 규칙 만이 토큰과 일치 할 수 있으며 모호성은 없습니다.

  • foo'foo' 유형입니다.

    파서 규칙 randomParserRule 은 암시적인 'foo' 토큰 유형을 도입하는데, 이는 IDENTIFIER 규칙보다 우선 순위가 높습니다.

  • barBAR 유형입니다.

    이 텍스트는 IDENTIFIER 규칙 이전 에 정의 된 BAR 규칙과 일치하므로 우선합니다.

  • bazIDENTIFIER 유형입니다.

    이 텍스트는 BAZ 규칙과 일치하지만 IDENTIFIER 규칙과도 일치합니다. 후자는 BAR 전에 정의 된대로 선택됩니다.

    문법이 주어지면, BAZ 는 일치시킬 수 없으며 , IDENTIFIER 규칙은 BAZ 가 일치시킬 수있는 모든 것을 이미 다루고 있습니다.

  • barzIDENTIFIER 유형입니다.

    BAR 규칙은이 문자열 ( bar )의 처음 3 자와 일치 할 수 있지만 IDENTIFIER 규칙은 4 자와 일치합니다. IDENTIFIER 는 더 긴 하위 문자열과 일치하므로 BAR 보다 BAR 합니다.

일반적으로,보다 일반적인 규칙을 만들기 전에 특정 규칙을 정의해야합니다. 룰이 이전에 정의 된 룰에 의해 이미 커버 된 입력과 만 일치 할 수 있다면 결코 사용 되지 않을 것입니다.

'foo' 와 같이 암시 적으로 정의 된 규칙은 다른 모든 렉서 규칙 보다 먼저 정의 된 것처럼 동작합니다.

Lexer 명령

렉서 규칙은 연관된 명령을 가질 수 있습니다 :

WHITESPACE: [ \r\n] -> skip;

명령은 규칙의 끝에 -> 뒤에 정의됩니다.

  • skip : 일치하는 텍스트를 건너 skip 토큰이 방출되지 않습니다.
  • channel(n) : 다른 채널에서 토큰을 내 보냅니다.
  • type(n) : 방출 된 토큰 유형을 변경합니다.
  • mode(n) , pushMode(n) , popMode , more : 렉서 모드를 제어합니다.

활동 및 의미 론적 술어

렉서 액션은 { ... } 로 둘러싸인 타겟 언어의 임의 코드 블록으로, 일치하는 동안 실행됩니다.

IDENTIFIER: [A-Z]+ { log("matched rule"); };

의미 론적 술어는 { ... }? 로 둘러싸인 목표 언어의 임의의 코드 블록입니다 }? 이는 부울 값으로 평가됩니다. 반환 값이 false이면 렉서 규칙을 건너 뜁니다.

IDENTIFIER: [A-Z]+ { identifierIsValid() }?;

시맨틱 조건부는 성능상의 이유로 가능한 한 규칙의 끝에서 정의되어야합니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow