我有以下语法:
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()
方法在这里不起作用?
修改
我用以下方式修改了Bart的答案:
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]]]_
。
我该如何解决这个问题?
答案 0 :(得分:1)
创建令牌后,您只能使用setText(...)
。您递归调用此标记 和 设置其他一些文本,这些文本无效。您需要使用QualifiedName
而不是词法分析器规则创建解析器规则,并在fragment
之前移除Identifier
。
rule: q=qualifiedName {System.out.println($q.text);};
qualifiedName
:
i=Identifier { $i.setText($i.text + "_");}
('[' (qualifiedName+ | Integer)? ']')*
;
Identifier
: ( '_'
| '$'
| ('a'..'z' | 'A'..'Z')
)
('a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '$')*
;
Integer
: Digit Digit*
;
fragment
Digit
: '0'..'9'
;
现在,将在控制台上打印:array1_[array2_[array3_[index_]]]
。
我不知道您为什么要这样做,但似乎您只是想将]
重写为]_
,这可以按照我上面显示的相同方式完成:
qualifiedName
:
Identifier
('[' (qualifiedName+ | Integer)? t=']' {$t.setText("]_");} )*
;