В моей грамматике у меня есть эти правила LeXeR:ANTLR: правило Лексер ловля, что должно быть обработано правилом синтаксического анализа
DECIMAL_NUMBER: DIGITS? DOT_SYMBOL DIGITS;
// Identifiers might start with a digit, even though it is discouraged.
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'
;
WHITESPACE: (' ' | '\t' | '\f' | '\r'| '\n') { $channel = HIDDEN; };
и это парсер правило:
qualified_identifier: IDENTIFIER '.' IDENTIFIER;
Это прекрасно работает, за исключением один особый случай, как это:
... a.0b
проблема здесь состоит в том, что +0,0 захвачен правилом десятичное_число, но я бы н чтобы игнорировать его, если есть цифры без цифр, которые следуют за любыми цифрами. Как это может быть сделано?
Я думал о проверяющем предикате, но это полностью нарушило бы разбор, если правило DECIMAL_NUMBER не соответствует ему. Еще одна мысль о том, что я должен добавить проверку действий для любого символа, следуя тому, что было согласовано до сих пор, а затем вручную генерирует токены, что кажется очень уродливым.
Можно ли пометить позицию после точки и вернуться к ней во входном потоке, когда мой код действия определяет, что это не десятичное число?
Здесь некрасиво решение с ручным лексем поколения: https://github.com/ibre5041/plsql-parser/blob/master/parsers/PLSQLLexer .g # L114. Он анализирует ввод '1..5' как NUMBER INTERVAL NUMBER. Другим вариантом было бы вызвать «set_type (IDENTIFIER)» внутри действия правила DECIMAL_NUMBER. Если за цифрами следуют некоторые символы. – ibre5041
Но это будет делать, например. '.0a' идентификатор, что неверно. Правильный способ заключается в создании последовательности токенов DOT IDENTIFIER. –
да, вы правы – ibre5041