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 typen IDENTIFIER

    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 över IDENTIFIER regeln.

  • bar är av typen BAR

    Denna text matchar BAR regeln, som definieras före IDENTIFIER regeln och har därför företräde.

  • baz är av typen IDENTIFIER

    Den här texten matchar BAZ regeln, men den matchar också IDENTIFIER regeln. Den senare väljs som den definieras före BAR .

    Med tanke på grammatiken kommer BAZ aldrig att kunna matcha, eftersom IDENTIFIER regeln redan täcker allt som BAZ kan matcha.

  • barz är av typen IDENTIFIER

    BAR regeln kan matcha de IDENTIFIER första tecknen i den här strängen ( bar ), men IDENTIFIER regeln matchar 4 tecken. Eftersom IDENTIFIER matchar en längre substring väljs den över BAR .

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.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow