java ANTLR以递归方式替换令牌
我的语法如下:
rule: q=QualifiedName {System.out.println($q.text);};
QualifiedName
:
i=Identifier { $i.setText($i.text + "_");}
('[' (QualifiedName+ | Integer)? ']')*
;
Integer
: Digit Digit*
;
fragment
Digit
: '0'..'9'
;
fragment
Identifier
: ( '_'
| '$'
| ('a'..'z' | 'A'..'Z')
)
('a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '$')*
;
以及来自Java的代码:
ANTLRStringStream stream = new ANTLRStringStream("array1[array2[array3[index]]]");
TestLexer lexer = new TestLexer(stream);
CommonTokenStream tokens = new TokenRewriteStream(lexer);
TestParser parser = new TestParser(tokens);
try {
parser.rule();
} catch (RecognitionException e) {
e.printStackTrace();
}
对于输入:array1[array2[array3[index]]]
,我想修改每个标识符。我希望看到输出:array1_[array_2[array3_[index_]]]
,但输出与输入相同
所以问题是:setText()
方法为什么在这里不起作用
编辑:
我用以下方式修改了巴特的答案:
rule: q=qualifiedName {System.out.println($q.modified);};
qualifiedName returns [String modified]
:
Identifier
('[' (qualifiedName+ | Integer)? ']')*
{
$modified = $text + "_";
}
;
Identifier
: ( '_'
| '$'
| ('a'..'z' | 'A'..'Z')
)
('a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '$')*
;
Integer
: Digit Digit*
;
fragment
Digit
: '0'..'9'
;
我想修改规则qualifiedName
匹配的每个标记。我尝试了上面的代码,对于输入array1[array2[array3[index]]]
,我希望看到输出array1[array2[array3[index_]_]_]_
,但是只修改了最后一个标记:array1[array2[array3[index]]]_
我怎样才能解决这个问题
# 1 楼答案
创建令牌后,您只能使用
setText(...)
。您正在递归地调用此令牌和设置其他一些文本,这将不起作用。您需要从QualifiedName
而不是lexer规则中创建解析器规则,并删除Identifier
之前的fragment
现在,它将在控制台上打印:
array1_[array2_[array3_[index_]]]
编辑
我不知道您为什么要这样做,但似乎您只是试图将
]
重写为]_
,这可以通过与上面所示相同的方式完成: