Как мне решить лексическую неоднозначность между числами и датами в ANTLR 2? - PullRequest
0 голосов
/ 12 января 2009

У меня в лексере есть два типа токенов, определенных следующим образом:

NUMBERVALUE
    :    ( '0' .. '9' )+ ( '.' ( '0' .. '9' )+ )?
    ;

DATEVALUE
    :    ( '0' .. '9' ) ( '0' .. '9' ) ( '0' .. '9' ) ( '0' .. '9' ) '-' 
         ( '0' .. '9' ) ( '0' .. '9' ) '-' 
         ( '0' .. '9' ) ( '0' .. '9' )
    |    ( '0' .. '9' ) ( '0' .. '9' ) '-' 
         ( '0' .. '9' ) ( '0' .. '9' ) '-' 
         ( '0' .. '9' ) ( '0' .. '9' )
         ;

Я бы подумал, что, поскольку даты должны содержать дефис внутри первых пяти символов, тогда установки k = 5 в опциях лексера будет достаточно, чтобы лексер мог всегда отличать два. Тем не менее, я получаю это предупреждение при запуске antlr:

warning:lexical nondeterminism between rules NUMBERVALUE and DATEVALUE upon
    k==1:'0'..'9'
    k==2:'0'..'9'
    k==3:'0'..'9'
    k==4:'0'..'9'
    k==5:'0'..'9'

и синтаксический анализатор не распознает числа, содержащие более четырех цифр. Как мне решить лексическую двусмысленность?

1 Ответ

2 голосов
/ 12 января 2009

Мне кажется, что вы сталкиваетесь с ложным предупреждением из-за Линейный приблизительный прогноз . 1-й, 2-й, 3-й, 4-й и 5-й символ DATEVALUE могут быть цифрами, но не все одновременно.

Я бы попытался избавиться от альтернативы 2/4 цифры года. Для начала, вы не хотите нести ответственность за ошибку Y2.1K; во-вторых, это спасает вас от альтернативного синтаксиса DATEVALUE. Другое решение, которое я бы попробовал, - это использовать другую группировку:

DATEVALUE
:    ( '0' .. '9' ) ( '0' .. '9' ) (( '0' .. '9' ) ( '0' .. '9' ))? '-' 
     ( '0' .. '9' ) ( '0' .. '9' ) '-' 
     ( '0' .. '9' ) ( '0' .. '9' )
     ;

Я думаю, что это более читабельно, так как вы не повторяете часть месяца / дня. Сначала я бы поставил необязательную часть для удобства чтения, но я понимаю, что в этих случаях следует избегать начинать с необязательных частей, поскольку это затрудняет синтаксический анализ.

...