2015-03-03 1 views
0

У меня проблемы с двусмысленными токенами. Моя грамматика определяет две постановки, числовую константу формы 2e3 или 100e1 и идентификаторы формы аЬс или uvw123.JavaCC: соответствие пустой строке

Проблема в том, что e1 является допустимым идентификатором, но также является частью числовой константы. Так, например, если мой ввод состоит из 2e3, он будет обозначаться как число, за которым следует идентификатор (+ e3), чего я не хочу.

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

Я попытался решить эту проблему, используя состояния токенизатора. Поскольку идентификатор не может начинаться с цифры, цифра должна указывать начало числовой константы, поэтому я перехожу к STATE_NUMBER. В этом состоянии я определяю токен e, чтобы обратиться к экспоненциальной части числовой константы. Затем у меня есть токен «поймать все остальное», с целью перехода обратно в состояние DEFAULT. В состоянии по умолчанию e будет соответствовать регулярному выражению идентификатора.

TOKEN : { 
    < digit_sequence: (["0"-"9"])+ > : STATE_NUMBER 
} 

<STATE_NUMBER> TOKEN : { 
    < exponent_prefix: "e" > 
} 

<STATE_NUMBER> MORE : { 
    < end_number: ~[] > : DEFAULT 
} 

TOKEN : { 
    < identifier: ["a"-"z"] (["0"-"9","a"-"z"])* > 
} 

Это не работает должным образом. Символ, совпадающий с маркером , более, кажется, отбрасывается вместо того, чтобы стать первым символом идентификатора.

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

+0

Что делать, если вы определяете digit_sequence как цифры плюс (необязательно) e и более цифр? Что-то вроде (["0" - "9"] + (e ["0" - "9"] +)?), Так что вы получите номер только с одним состоянием ... это сработает? –

+0

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

+0

Я изменил название, поскольку я не думал, что это было чем-то с двусмысленностью. –

ответ

0

Проблема в том, что < end_number: ~[] > : DEFAULT соответствует любому символу, который не является e. Вместо этого вы должны выбрать пустую строку. Попробуйте

< end_number: "" > : DEFAULT 

Я думаю следующее будет работать.

TOKEN : { 
    < (["0"-"9"])+ > : STATE_NUMBER0 
} 

<STATE_NUMBER0> TOKEN : { 
    < "e" > : STATE_NUMBER1 
} 

<STATE_NUMBER0> MORE : { 
    < number_without_exponent: "" > : DEFAULT 
} 

<STATE_NUMBER1> MORE : { 
    < number_with_exponent: (["0"-"9"])+ > : DEFAULT 
} 

Это делает 123e ошибка, как 123edf. Если вы не хотите, чтобы это были ошибки, вы можете уйти с одним меньшим количеством состояний.

TOKEN : { 
    < (["0"-"9"])+ > : STATE_NUMBER 
} 

<STATE_NUMBER> TOKEN : { 
    < number_with_exponent: "e" (["0"-"9"])+ > : DEFAULT 
} 

<STATE_NUMBER> MORE : { 
    < number_without_exponent: "" > : DEFAULT 
} 

Это делает 123e в number_without_exponent, за которым следует identifier "е". Если вы предпочитаете, чтобы это было всего лишь number_without_exponent, измените последнее + на *.

+0

Вы, мошенник, Теодор, вы сделали это, старик! –

 Смежные вопросы

  • Нет связанных вопросов^_^