У меня есть эти правила LeXeR в моей ANTLR3 грамматике:разрешения Лексера правила конфликта необходимо
INTEGER: DIGITS;
FLOAT: DIGITS? DOT_SYMBOL DIGITS ('E' (MINUS_OPERATOR | PLUS_OPERATOR)? DIGITS)?;
HEXNUMBER: '0X' HEXDIGIT+;
HEXSTRING: 'X' '\'' HEXDIGIT+ '\'';
BITNUMBER: '0B' ('0' | '1')+;
BITSTRING: 'B' '\'' ('0' | '1')+ '\'';
NCHAR_TEXT: 'N' SINGLE_QUOTED_TEXT;
IDENTIFIER: LETTER_WHEN_UNQUOTED+;
fragment LETTER_WHEN_UNQUOTED:
'0'..'9'
| 'A'..'Z' // Only upper case, as we use a case insensitive parser (insensitive only for ASCII).
| '$'
| '_'
| '\u0080'..'\uffff'
;
и
qualified_identifier:
IDENTIFIER (options { greedy = true; }: DOT_SYMBOL IDENTIFIER)?
;
Это работает в основном отлично подходит для очень специфических ситуаций, таких как вход t1.1_d
, который, как предполагается, за исключением анализируется как 2 идентификатора, связанных с точкой. Случается, что .1 сопоставляется как float, хотя за ним следуют символы подчеркивания и буквы.
Понятно, откуда это взято: LETTER_WHEN_UNQUOTED содержит цифры, так что «1» может быть как целым числом, так и идентификатором. Но порядок правил должен позаботиться о том, чтобы разрешить это целое, как предполагалось (и обычно это делает).
Однако я недоумеваю, что вход t1.1_d
заставляет правило поплавка вставлять и оценит некоторые указатели для решения этой проблемы. Как только я добавляю пробел после точки, все в порядке, но это, очевидно, не настоящее решение.
Когда я перемещаю правило IDENTIFIER перед остальными, у меня возникают новые проблемы, потому что после этого несколько других правил больше не могут быть сопоставлены. Перемещение правила FLOAT после правила IDENTIFIER также не устраняет проблему (но, по крайней мере, не создает новых проблем). В этом случае мы видим фактическую проблему: точка всегда соответствует правилу FLOAT, если непосредственно следовать цифре. Что я могу сделать, чтобы это не соответствовало моему делу?
Вы можете включать в себя полную грамматику (то есть, включают в себя все маркеры/фрагменты ссылки в вашем примере)? Кроме того, жадные значения по умолчанию равны true, поэтому указание этого не должно быть необходимым. –
Возможно, вы захотите сделать несколько редизайнов: в настоящее время 1234 - это как INTEGER, так и IDENTIFIER. Я не говорю, что это не сработает, но у меня болит голова. –