我知道我可以通过多种方式覆盖(解析器)规则的文本(侦听器或访问者)。
但是我想操纵给定某些特定词汇匹配的文本(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);
}
答案 0 :(得分:1)
不确定这是否是最佳方式,但它有效:
@Override
public Token emit() {
if(getType()==PACKAGE){
setText(getText()+" ");
}
return super.emit();
}
我覆盖了public Token emit()
而不是public void emit(Token token)
。