수색…
간단한 규칙
렉서 규칙은 토큰 유형을 정의합니다. 그들의 이름은 파서 규칙과 구별하기 위해 대문자로 시작해야합니다.
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
aaa
는IDENTIFIER
유형입니다.IDENTIFIER
규칙 만이 토큰과 일치 할 수 있으며 모호성은 없습니다.
foo
는'foo'
유형입니다.파서 규칙
randomParserRule
은 암시적인'foo'
토큰 유형을 도입하는데, 이는IDENTIFIER
규칙보다 우선 순위가 높습니다.
bar
는BAR
유형입니다.이 텍스트는
IDENTIFIER
규칙 이전 에 정의 된BAR
규칙과 일치하므로 우선합니다.
baz
는IDENTIFIER
유형입니다.이 텍스트는
BAZ
규칙과 일치하지만IDENTIFIER
규칙과도 일치합니다. 후자는BAR
전에 정의 된대로 선택됩니다.문법이 주어지면,
BAZ
는 일치시킬 수 없으며 ,IDENTIFIER
규칙은BAZ
가 일치시킬 수있는 모든 것을 이미 다루고 있습니다.
barz
는IDENTIFIER
유형입니다.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() }?;
시맨틱 조건부는 성능상의 이유로 가능한 한 규칙의 끝에서 정의되어야합니다.