Antlr4覆盖Lexer的文本

Antlr4覆盖Lexer的文本,antlr,antlr4,Antlr,Antlr4,我知道我可以通过多种方式(侦听器或访问者)重写(解析器)规则的文本 但是,我想处理一些特定词汇匹配的文本(Lexer规则) 假设我们使用java语法。我们有一个完整的关键字列表: ABSTRACT : 'abstract'; ASSERT : 'assert'; BOOLEAN : 'boolean'; BREAK : 'break'; // 50 more or so... 这是一个采样输入: public \t\t\t\t class Y

我知道我可以通过多种方式(侦听器或访问者)重写(解析器)规则的文本

但是,我想处理一些特定词汇匹配的文本(Lexer规则)

假设我们使用java语法。我们有一个完整的关键字列表:

ABSTRACT      : 'abstract';
ASSERT        : 'assert';
BOOLEAN       : 'boolean';
BREAK         : 'break';
// 50 more or so...
这是一个采样输入:

public \t\t\t\t class Yolo{}
当然,跳过空格和注释比将它们放在解析器规则之间更方便。但是,当我创建翻译器时,我希望每个关键字后面都有一个空格:

public class Yolo{}

我最大的问题是,在Listener或Visitor中添加空白实在是太麻烦了,所以我在想是否可以覆盖一个打印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;
    }
}
资料来源:

/** 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);
}

不确定这是否是最好的方法,但它是有效的:

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

我重写了
public-Token-emit()
而不是
public-void-emit(Token-Token)

我不会修改lexer,而是更改获取文本的方式。在C#中,您可以使用扩展方法获取带有额外空格的文本。在其他语言中,至少可以创建一个接受标记并返回修改文本的函数。
@Override
public Token emit() {
    if(getType()==PACKAGE){
        setText(getText()+" ");
    }
    return super.emit();
}