Я знаю, что я могу переопределить правила (парсера) разными способами (слушателем или посетителем).Antlr4 override text of Lexer
Однако я хочу манипулировать текстом, определенным для некоторых лексических совпадений (правила Лексера).
Предположим, что мы работаем с грамматикой Java. И у нас есть полный список Ключевых слов:
ABSTRACT : 'abstract';
ASSERT : 'assert';
BOOLEAN : 'boolean';
BREAK : 'break';
// 50 more or so...
Это входная выборка:
public \t\t\t\t class Yolo{}
Это более удобно, чтобы пропустить пробела & комментариев вместо того, чтобы их между правилами синтаксического анализа, конечно. Однако, когда я создаю мой переводчик, я хочу иметь после каждого ключевого слова один пробел:
public class Yolo{}
Моя огромная проблема в том, что это действительно громоздким, чтобы добавить в приемнике или посетитель белое пространство, так что я думаю, если Я мог бы переопределить общий метод, который печатает текст Lexer. Как:
@lexer::members {
//the list of Keyword that I want them to be followed by a space
ArrayList<Int> keyword = ....
@Override
public String getText() {
String text = super.getText();
if(keywords.contains(getToken().getType())){
text = text + " ";
}
return text;
}
}
Update
Следующая должно было сработать, так как исходный код обрабатывает текст переопределение. Я думаю, что _text
обновляется или сбрасывается (с reset()
Lexer), поэтому мой пользовательский текст никогда не достигает результата.
@Override
public void emit(Token t) {
super.emit(t);
if(t.getType()==PACKAGE){
setText(getText()+" ");
}
}
Источник:
/** Return the text matched so far for the current token or any
* text override.
*/
public String getText() {
if (_text !=null) {
return _text;
}
return getInterpreter().getText(_input);
}
Я бы не изменил lexer, а изменил способ получения текста. В C# вы можете использовать методы расширения, чтобы получить текст с дополнительным пространством. На других языках, по крайней мере, возможно создать функцию, которая принимает токен, возвращает измененный текст. – Onur