Символы, совпадающие с несколькими правилами Lexer в ANTLR - PullRequest
6 голосов
/ 24 сентября 2011

Я определил несколько правил лексера, которые потенциально соответствуют одной и той же последовательности символов. Например:

LBRACE:  '{' ;
RBRACE: '}' ;
LPARENT: '(' ;
RPARENT: ')' ;
LBRACKET: '[' ;
RBRACKET: ']' ;
SEMICOLON: ';' ;
ASTERISK: '*'  ;
AMPERSAND: '&'  ;

IGNORED_SYMBOLS:   ('!' | '#' | '%' | '^' | '-' | '+' | '=' | 
                    '\\'| '|' | ':' | '"' | '\''| '<' | '>' | ',' | '.' |'?' | '/'  ) ;


// WS comments*****************************
WS: (' '|'\n'| '\r'|'\t'|'\f' )+ {$channel=HIDDEN;};
ML_COMMENT: '/*' .* '*/' {$channel=HIDDEN;};
SL_COMMENT: '//' .* '\r'? '\n' {$channel=HIDDEN;};

STRING_LITERAL:  '"' (STR_ESC | ~( '"' ))* '"'; 
fragment STR_ESC:  '\\'  '"'  ; 

CHAR_LITERAL :  '\'' (CH_ESC | ~( '\'' )) '\''  ;  
fragment CH_ESC :  '\\' '\''; 

Мои IGNORED_SYMBOLS и ASTERISK соответствуют /, "и * соответственно. Так как они помещены (непреднамеренно) перед моим комментарием и правилами строкового литерала, которые также соответствуют / * и", я ожидаю, что комментарий и правила строкового литерала будут отключены ( непреднамеренно). Но, что удивительно, правила ML_COMMENT, SL_COMMENT и STRING_LITERAL по-прежнему работают правильно.

Это несколько сбивает с толку. Разве это не /, является ли оно частью / * или просто автономным /, всегда будет совпадать и потребляться IGNORED_SYMBOLS в первую очередь, прежде чем у него будет какой-либо шанс быть найденным ML_COMMENT?

Как лексер решает, какие правила применять, если символы соответствуют более чем одному правилу?

1 Ответ

6 голосов
/ 25 сентября 2011

Как лексер решает, какие правила применять, если символы соответствуют более чем одному правилу?

Правила лексера совпадают сверху вниз.Если два (или более) правила совпадают с одинаковым количеством символов, то, которое определено первым, имеет приоритет над тем, которое позже определено в грамматике.Если правило соответствует N количеству символов, а более позднее правило соответствует тем же N символам плюс 1 или более символов, тогда более позднее правило сопоставляется (жадное соответствие).

Возьмем, к примеру, следующие правила:

DO : 'do';
ID : 'a'..'z'+;

Вход "do", очевидно, будет соответствовать правилу DO.

И ввод, такой как: "done" будет жадно совпадать с ID.Он не токенизирован как 2 токена: [DO:"do"], за которым следует [ID:"ne"].

...