ANTLR
Lexer regler i v4
Sök…
Enkla regler
Lexer-regler definierar tokentyper. Deras namn måste börja med en stor bokstav för att skilja dem från analyserregler.
INTEGER: [0-9]+;
IDENTIFIER: [a-zA-Z_] [a-zA-Z_0-9]*;
OPEN_PAREN: '(';
CLOSE_PAREN: ')';
Grundläggande syntax:
| Syntax | Menande |
|---|---|
A | Matcha lexerregel eller fragment med namnet A |
AB | Match A följt av B |
(A|B) | Matcha antingen A eller B |
'text' | Matcha bokstavlig "text" |
A? | Matcha A noll eller en gång |
A* | Matcha A noll eller flera gånger |
A+ | Match A en eller flera gånger |
[A-Z0-9] | Matcha ett tecken i de definierade områdena (i detta exempel mellan AZ eller 0-9) |
'a'..'z' | Alternativ syntax för ett teckenområde |
~[AZ] | Negation av ett intervall - matcha varje enskilt tecken som inte finns i intervallet |
. | Matcha alla karaktärer |
fragment
Fragment är återanvändbara delar av lexerreglerna som inte kan matcha på egen hand - de måste refereras från en lexerregel.
INTEGER: DIGIT+
| '0' [Xx] HEX_DIGIT+
;
fragment DIGIT: [0-9];
fragment HEX_DIGIT: [0-9A-Fa-f];
Implicita lexer-regler
När symboler som '{' används i en parserregel , skapas en implicit lexerregel för dem såvida det inte finns en uttrycklig regel.
Med andra ord, om du har en lexerregel:
OPEN_BRACE: '{';
Då är båda dessa parserregler likvärdiga:
parserRule: '{';
parserRule: OPEN_BRACE;
Men om OPEN_BRACE lexer-regeln inte definieras, skapas en implicit anonym regel. I så fall kommer den implicita regeln att definieras som om den definierades före de andra reglerna: den kommer att ha en högre prioritet än andra regler.
Prioritetsregler
Flera lexerregler kan matcha samma inmatningstext. I så fall kommer tokenstypen att väljas enligt följande:
- Välj först lexerregeln som matchar den längsta inmatningen
- Om texten matchar ett implicit definierat token (som
'{'), använd den implicita regeln - Om flera lexerregler matchar samma ingångslängd, välj den första , baserad på definitionsordning
Följande kombinerad grammatik:
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;
Följande input:
aaa foo bar baz barz
Kommer att producera följande toksekvens från lexern:
IDENTIFIER 'foo' BAR IDENTIFIER IDENTIFIER
aaaär av typenIDENTIFIEREndast
IDENTIFIERregeln kan matcha detta symbol, det finns ingen tvetydighet.
fooär av typen'foo'randomParserRuleintroducerar den implicita'foo'-token typen, som är prioriterad överIDENTIFIERregeln.
barär av typenBARDenna text matchar
BARregeln, som definieras föreIDENTIFIERregeln och har därför företräde.
bazär av typenIDENTIFIERDen här texten matchar
BAZregeln, men den matchar ocksåIDENTIFIERregeln. Den senare väljs som den definieras föreBAR.Med tanke på grammatiken kommer
BAZaldrig att kunna matcha, eftersomIDENTIFIERregeln redan täcker allt somBAZkan matcha.
barzär av typenIDENTIFIERBARregeln kan matcha deIDENTIFIERförsta tecknen i den här strängen (bar), menIDENTIFIERregeln matchar 4 tecken. EftersomIDENTIFIERmatchar en längre substring väljs den överBAR.
Som tumregel bör specifika regler definieras innan mer generiska regler. Om en regel bara kan matcha en ingång som redan täcks av en tidigare definierad regel kommer den aldrig att användas.
Implicit definierade regler som 'foo' fungerar som om de var definierade före alla andra lexer-regler.
Lexer-kommandon
En lexer-regel kan ha tillhörande kommandon :
WHITESPACE: [ \r\n] -> skip;
Kommandon definieras efter a -> i slutet av regeln.
-
skip: Hoppar över den matchade texten, ingen token kommer att släppas ut -
channel(n): Avger token på en annan kanal -
type(n): Ändrar den utsända tokentypen -
mode(n),pushMode(n),popMode,more: Kontrollerar lexer-lägen
Åtgärder och semantiska predikat
En lexer-åtgärd är ett block av godtycklig kod på målspråket omgiven av { ... } , som körs under matchning:
IDENTIFIER: [A-Z]+ { log("matched rule"); };
Ett semantiskt predikat är ett block av godtycklig kod på målspråket omgiven av { ... }? , som utvärderar till ett booleskt värde. Om det returnerade värdet är falskt hoppas över lexer-regeln.
IDENTIFIER: [A-Z]+ { identifierIsValid() }?;
Semantiska predikat bör definieras i slutet av regeln när det är möjligt av prestandaskäl.