Velocity的变量有以下符号。 (见Velocity User Guide):
变量的简写符号由一个前导" $"字符后跟VTL标识符。 VTL标识符必须以字母字符(a .. z或A .. Z)开头。其余字符仅限于以下类型的字符:
- 字母(a .. z,A .. Z)
- 数字(0 .. 9)
- 下划线(" _")
我想使用词法模式来分割普通文本和变量,所以我写了这样的东西:
// default mode
DOLLAR : ‘$’ -> pushMode(VARIABLE);
TEXT : ~[$]+? -> skip;
mode VARIABLE:
ID : [a-zA-Z] [a-zA-Z0-9-_]*;
???? : XXX -> popMode; // how can I pop mode to default?
因为变量的符号没有明确的结束字符,所以我不知道如何确定它的结束。
也许我弄错了?
答案 0 :(得分:0)
你会像这样弹出那个范围:
mode VARIABLE;
ID : [a-zA-Z] [a-zA-Z0-9-_]* -> popMode;
这是一个快速演示:
lexer grammar VelocityLexer;
DOLLAR : '$' -> more, pushMode(VARIABLE);
TEXT : ~[$]+ -> skip;
mode VARIABLE;
// the `-` needs to be escaped!
ID : [a-zA-Z] [a-zA-Z0-9\-_]* -> popMode;
请注意more
中的DOLLAR
,$
会导致ID
令牌中包含$
。如果您没有,则最终会输入两个令牌(foo
和$foo
作为输入import org.antlr.v4.runtime.*;
public class Main {
public static void main(String[] args) {
VelocityLexer lexer = new VelocityLexer(CharStreams.fromString("<strong>$Mu</strong>$foo..."));
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
tokenStream.fill();
for (Token t : tokenStream.getTokens()) {
System.out.printf("%-10s '%s'\n", VelocityLexer.VOCABULARY.getSymbolicName(t.getType()), t.getText());
}
}
}
)
使用以下Java类测试语法:
ID '$Mu'
ID '$foo'
EOF '<EOF>'
将打印:
ID
但是,我觉得如果lexer grammar VelocityLexer;
DOLLAR : '$' [a-zA-Z] [a-zA-Z0-9\-_]*;
TEXT : ~[$]+ -> skip;
,词汇模式不是一个好的选择。为什么不简单地做:
{{1}}