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 typenIDENTIFIER
Endast
IDENTIFIER
regeln kan matcha detta symbol, det finns ingen tvetydighet.
foo
är av typen'foo'
randomParserRule
introducerar den implicita'foo'
-token typen, som är prioriterad överIDENTIFIER
regeln.
bar
är av typenBAR
Denna text matchar
BAR
regeln, som definieras föreIDENTIFIER
regeln och har därför företräde.
baz
är av typenIDENTIFIER
Den här texten matchar
BAZ
regeln, men den matchar ocksåIDENTIFIER
regeln. Den senare väljs som den definieras föreBAR
.Med tanke på grammatiken kommer
BAZ
aldrig att kunna matcha, eftersomIDENTIFIER
regeln redan täcker allt somBAZ
kan matcha.
barz
är av typenIDENTIFIER
BAR
regeln kan matcha deIDENTIFIER
första tecknen i den här strängen (bar
), menIDENTIFIER
regeln matchar 4 tecken. EftersomIDENTIFIER
matchar 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.