Я не знаю JavaCC, но я инженер-компилятор.
Правило FLOAT_PAIR
неоднозначно. Рассмотрим следующий текст:
0.0
Это может быть FLOAT 0
, за которым следует FLOAT .0
; или это может быть FLOAT 0.
, за которым следует FLOAT 0
; оба приводят к FLOAT_PAIR. Или это может быть один FLOAT 0.0
.
Более важно, однако, что вы используете лексический анализ с композицией таким образом, который никогда не будет работать. Считайте это число:
12345
Это может быть проанализировано как INTEGER 12, INTEGER 345
, что приведет к INTEGER_PAIR
. Или это может быть проанализировано как INTEGER 123, INTEGER 45
, другое INTEGER_PAIR
. Или это может быть INTEGER 12345
, другой токен. Проблема существует, потому что вам не требуется пробел между лексическими элементами INTEGER_PAIR
(или FLOAT_PAIR
).
Вы почти никогда не должны пытаться обрабатывать такие пары в лексере. Вместо этого вы должны обрабатывать простые числа (INTEGER
и FLOAT
) как токены и обрабатывать такие вещи, как отрицание и спаривание, в анализаторе, где с пробелами обращаются и удаляют.
(Например, как вы собираетесь обрабатывать "----42"
? Это допустимое выражение в большинстве языков программирования, которое будет правильно рассчитывать множественные отрицания, но не будет обрабатываться вашим лексером.)
Также помните, что однозначные целые числа в вашем лексере не будут совпадать с INTEGER
, они будут иметь вид DIGIT
. Я не знаю правильный синтаксис для JavaCC, чтобы исправить это для вас, хотя. Вам нужно определить DIGIT
не как токен, а просто что-то, что вы можете использовать в определениях других токенов; в качестве альтернативы, вставьте определение DIGIT
([0-9]
) напрямую, где бы вы ни использовали DIGIT
в своих правилах.