我们如何在ANTLR语法中区分变量名和标识符?
VAR: ('A'..'Z')+ DIGIT* ;
IDENT : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'-')*;
这段语法(在ANTLR中)不起作用,因为编译器会抱怨某些输入可能永远无法访问IDENT。这似乎是编译器编写者The lexer hack
的经典头脑攻击对于ANTLR用户,你能告诉我你的整洁方法吗?感谢
答案 0 :(得分:1)
zell写道:
这段语法(在ANTLR中)不起作用,因为编译器会抱怨某些输入可能永远无法达到IDENT。
不,这不正确。以下语法:
grammar T;
parse
: .* EOF
;
VAR : ('A'..'Z')+ DIGIT* ;
IDENT : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'-')*;
fragment DIGIT : '0'..'9';
不会产生任何错误或警告。词法分析器只创建两种类型的标记:
VAR
; ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'-')*
,则会创建IDENT
。请注意,IDENT
永远不能以大写的ascii字母开头:它始终会成为VAR
。
因此,如果您的解析器规则如下:
foo
: IDENT
;
并且整个输入都是"BAR"
,然后会出现解析器错误,因为词法分析器不会产生INDENT
令牌,而是VAR
令牌,即使解析器“询问“对于IDENT
。
你必须明白,无论解析器从词法分析器询问什么,词法分析器都独立于解析器运行。