Я пытаюсь сопоставлять измерения в текстовом тексте на английском языке, используя Antlr 3.2 и Java1.6. У меня есть лексические правила, как следующее:Соответствующие варианты лексемы с Antlr3
fragment
MILLIMETRE
: 'millimetre' | 'millimetres'
| 'millimeter' | 'millimeters'
| 'mm'
;
MEASUREMENT
: MILLIMETRE | CENTIMETRE | ... ;
Я хотел бы быть в состоянии принять любую комбинацию прописных и строчных ввода и - что более важно - просто возвращают один лексический маркер для всех вариантов миллиметр. Но на данный момент мой АСТ содержит «миллиметр», «миллиметры», «мм» и т. Д., Как и во входном тексте.
После прочтения http://www.antlr.org/wiki/pages/viewpage.action?pageId=1802308, я думаю, что мне нужно сделать что-то вроде следующего:
tokens {
T_MILLIMETRE;
}
fragment
MILLIMETRE
: ('millimetre' | 'millimetres'
| 'millimeter' | 'millimeters'
| 'mm') { $type = T_MILLIMETRE; }
;
Однако, когда я делаю это, я получаю следующие ошибки компиляции в коде Java, порожденного Antlr:
cannot find symbol
_type = T_MILLIMETRE;
Я попробовал следующий вместо:
MEASUREMENT
: MILLIMETRE { $type = T_MILLIMETRE; }
| ...
но затем ИЗМЕРЕНИЕ больше не сопоставляется.
Более очевидное решение с правилом подстановки:
MEASUREMENT
: MILLIMETRE -> ^(T_MILLIMETRE MILLIMETRE)
| ...
вызывает NPE:
java.lang.NullPointerException at org.antlr.grammar.v2.DefineGrammarItemsWalker.alternative(DefineGrammarItemsWalker.java:1555).
Создание ИЗМЕРЕНИЯ в правило синтаксического анализа дает мне страшное «Следующие определения маркеров никогда не могут быть сопоставлены потому что предыдущие токены соответствуют одной и той же ошибке ввода.
При создании правила синтаксического анализатора
measurement : T_MILLIMETRE | ...
я получаю предупреждение «не правило лексического анализатора, соответствующий маркер: T_MILLIMETRE». Antlr работает, но он все равно дает мне входной текст в AST, а не T_MILLIMETRE.
Я, очевидно, еще не вижу мир так, как это делает Antlr. Может ли кто-нибудь дать мне какие-нибудь подсказки или советы?
Стив
Спасибо за ваш ответ, Барт. Я знал об этой возможности. Разница в том, что я пытаюсь решить проблему на лексическом уровне, тогда как вы предлагаете синтаксическое правило. Ваш путь, по-видимому, правильный путь Antlr. Мой опыт в этой проблеме заключается в том, что правила перезаписи работают только с синтаксическими правилами, а не с лексическими правилами. Я решаю проблему в своем решении на данный момент, после обработки результатов в моем Java-коде, но я, возможно, должен пересмотреть то, что я делаю в Antlr на лексическом уровне, и то, что я делаю на синтаксическом уровне. –
@ Стефен, хорошо, я понимаю, что вы имеете в виду. Но в моем примере тип (для миллиметра) всегда будет «MilliMeter» (см. Мой ** EDIT **). Поэтому я не совсем уверен, что тебе нужно. –
Ты заставил меня думать, Барт. Я неправильно подходил к проблеме. Я пытался эффективно распознавать снизу вверх, делая лексический анализ контекстно-зависимым. Это означало, что я быстро достиг предела того, что мог сделать Antlr, поскольку это инструмент сверху вниз. Теперь я переместил много анализа в синтаксис (например, в вашем примере), и все становится проще. Я думаю, что нужно очень хорошо понимать разницу между лексическими правилами и синтаксическими правилами в Antlr, даже если они выглядят очень похожими. Не все, что синтаксические правила могут делать, возможно с лексическими. –