我想构建一个antlr语法来解析模板语言。该语言可以嵌入任何文本中,并且边界标记为打开/关闭标记:{{
/}}
。因此,一个有效的模板看起来是这样的:在antlr3语法中切换词法分析器状态
foo {{ someVariable }} bar
凡foo
和bar
应该被忽略,{{
和}}
标签内的部分应被解析。我发现this question基本上有问题的答案,除了标签只有一个{
和}
。我试图修改语法来匹配2个打开/关闭字符,但只要我这样做,BUFFER
规则将消耗所有字符,也包括开始和结束括号。永远不会调用LD
规则。
有没有人有一个想法,为什么antlr词法分析器消耗Buffer
规则中的所有标记时,分隔符有2个字符,但是当它们只有一个字符时不消耗分隔符?
grammar Test;
options {
output=AST;
ASTLabelType=CommonTree;
}
@lexer::members {
private boolean insideTag = false;
}
start
: (tag | BUFFER)*
;
tag
: LD IDENT^ RD
;
LD @after {
// flip lexer the state
insideTag=true;
System.err.println("FLIPPING TAG");
} : '{{';
RD @after {
// flip the state back
insideTag=false;
} : '}}';
SPACE : (' ' | '\t' | '\r' | '\n') {$channel=HIDDEN;};
IDENT : (LETTER)*;
BUFFER : { !insideTag }?=> ~(LD | RD)+;
fragment LETTER : ('a'..'z' | 'A'..'Z');
请注意'IDENT:(LETTER)*;'(might)会导致词法分析器进入一个无限循环。 Lexer规则_必须总是匹配至少1个字符。 – 2012-01-01 16:12:13