2014-09-07 2 views
1

Я знаю, что я могу переопределить правила (парсера) разными способами (слушателем или посетителем).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); 
} 
+0

Я бы не изменил lexer, а изменил способ получения текста. В C# вы можете использовать методы расширения, чтобы получить текст с дополнительным пространством. На других языках, по крайней мере, возможно создать функцию, которая принимает токен, возвращает измененный текст. – Onur

ответ

1

Не уверен, что это лучший способ, но он работает:

@Override 
public Token emit() { 
    if(getType()==PACKAGE){ 
     setText(getText()+" "); 
    } 
    return super.emit(); 
} 

Я перекрытая public Token emit() вместо public void emit(Token token).

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