Antlr4覆盖Lexer的文本

时间:2014-09-07 02:06:52

标签: antlr antlr4

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

但是我想操纵给定某些特定词汇匹配的文本(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;
    }
}

更新

以下应该有效,因为源代码处理文本覆盖。我认为_text会更新或重置(使用Lexer的reset()),因此我的自定义文本永远不会到达输出。

@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);
}

1 个答案:

答案 0 :(得分:1)

不确定这是否是最佳方式,但它有效:

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

我覆盖了public Token emit()而不是public void emit(Token token)