2012-03-07 9 views
5

Znam "+", "?" i '*'. Ale co, jeśli chcę, żeby coś powtarza się, powiedzmy, 5 razy? Na przykład, jeśli identyfikator musi być ciągiem liczb szesnastkowych o długości 5?jak zdefiniować regułę powtarzania wzoru określoną liczbę razy używając gramatyki antlr

Mówiąc dokładniej, zastanawiam się nad zdefiniowaniem ogólnej reguły leksykalnej o nieograniczonej długości, a następnie, w czasie analizy, policz, ile razy się to powtórzyło, jeśli wynosi 5, następnie zmień nazwę na inny typ tokena , ale jak mogę to zrobić? Czy jest jakiś łatwy sposób?

Odpowiedz

4

w czasie analizowania policz ile czasu się powtórzyło, jeśli wynosi 5, zmień nazwę na inny typ tokena, ale jak mogę to zrobić? Czy jest jakiś łatwy sposób?

Tak, można to zrobić z ujednoznaczniania semantycznej orzecznik (explanation):

grammar T; 

parse 
: (short_num | long_num)+ EOF 
; 

short_num 
: {input.LT(1).getText().length() == 5}? NUM 
; 

long_num 
: {input.LT(1).getText().length() == 8}? NUM 
; 

NUM 
: '0'..'9'+ 
; 

SP 
: ' ' {skip();} 
; 

która będzie analizować wejście 12345 12345678 następująco:

enter image description here

ale ty może także zmienić typ tokena w lexer na podstawie właściwości dopasowanego tekstu Coś takiego:

grammar T; 

parse 
: (SHORT | LONG)+ EOF 
; 

NUM 
: '0'..'9'+ 
    { 
    if(getText().length() == 5) $type = SHORT; 
    if(getText().length() == 8) $type = LONG; 
    // when the length is other than 5 or 8, the type of the token will stay NUM 
    } 
; 

SP 
: ' ' {skip();} 
; 

fragment SHORT : ; 
fragment LONG : ; 

który spowoduje, że samo wejście do być analizowany tak:

enter image description here

+0

Dzięki, spróbowałem drugiej metody. Dokładnie to, czego szukam. – safarisoul

1

Musisz podać mu 5 razy, na przykład:

ZIPCODE: '0'..'9' '0'..'9' '0'..'9' '0'..'9' '0'..'9'; 

Alternatywnie, można użyć stwierdzenia prawidłowości semantycznej orzecznik:

DIGIT: '0'..'9'; 
zipcode 
@init { int N = 0; } 
    : (DIGIT { N++; })+ { N <= 5 }? 
    ; 

Patrz: What is a 'semantic predicate' in ANTLR?

+0

Cześć, to działa w gramatyce Parser. Czy można to zrobić w gramatyce Lexera? – safarisoul

+0

Dobra, mam teraz gramatykę Lexera. Ale mogę mieć tylko jedną taką zasadę. Czy to możliwe, jeśli chcę nazwać taki żeton długości 5 jako KRÓTKI, a jednocześnie nazwać taki żeton długości 8 jako DŁUGI? Roszczenie Antlr "Poniższych definicji tokenów nigdy nie można dopasować". – safarisoul

+0

Mam na myśli, w ten sposób, za każdym razem, gdy {}? ocenione jako fałszywe, te znaki zostaną zignorowane, ale chcę sprawdzić lexer dla innych potencjalnych dopasowań. – safarisoul

Powiązane problemy