2013-04-19 1 views
3

Я хочу совместить выражение с пробелом как единый токен. Ниже приведены мои правила лексера:ANTLR: совпадение жетонов с пробелами

HOUR : (INTEGER) ('hour'|'hours') ; 
MINUTE : (INTEGER) ('min'|'minute'|'minutes') ; 
INTEGER : '0' 'x' (HEXDIGIT)+ | (DIGIT)+ ; 
fragment DIGIT : '0'..'9'; 
fragment HEXDIGIT : 'a'..'f' | 'A'..'F' | DIGIT; 
WS : ('\t' | ' ' | '\r' | '\n'| '\u000C')+ {skip()}; 

Если я использую '12hour', я получаю ЧАС маркер. Но я использую '12 часов', получите INTEGER и 'hour'. Что я могу сделать, чтобы lexer возвращал целые «12 часов» в качестве одного токена HOUR?

ответ

2

Если я использую «12 часов», я получаю токен HOUR. Но я использую «12 часов», получаю INTEGER и «час».

Да, это ожидаемое поведение. Это связано с тем, что WS пропускаются только из правил парсера.

Что я могу сделать, чтобы lexer вернул целое «12 часов» в качестве одного токена HOUR?

Либо включать космические символы в вашем HOUR правила:

// Don't use `WS` in this token, or `skip()` will be 
// invoked and this token will also be skipped! 
HOUR : (INTEGER) SPACE* ('hour'|'hours') ; 

WS : SPACE+ {skip();}; 

fragment SPACE : '\t' | ' ' | '\r' | '\n'| '\u000C'; 

Или IMO предпочтительный способ, создать правило разбора для такой вещи:

hour : INTEGER HOUR; 

HOUR : 'hour' | 'hours' ; 
INTEGER : '0' 'x' (HEXDIGIT)+ | (DIGIT)+;