【问题标题】:Neat way to distinguish identifiers and variable names (ANTLR)?区分标识符和变量名(ANTLR)的巧妙方法?
【发布时间】:2011-12-02 14:31:33
【问题描述】:
在 ANTLR 语法中,我们如何区分变量名和标识符?
VAR: ('A'..'Z')+ DIGIT* ;
IDENT : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'-')*;
语法(在 ANTLR 中)不起作用,因为编译器会抱怨某些输入可能永远无法达到 IDENT。这似乎是编译器编写者的经典之作,The lexer hack
对于 ANTLR 用户,您能告诉我您的巧妙解决方法吗?谢谢
【问题讨论】:
标签:
antlr
grammar
variable-names
【解决方案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';
不会产生任何错误或警告。词法分析器只创建两种类型的标记:
- 如果某些内容以一个或多个大写 ascii 字母开头,后跟零个或多个数字,则创建
VAR;
- 如果某些内容以小写 ascii 字母或下划线开头,后跟
('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'-')*,则会创建 IDENT。
请注意,IDENT 永远不能以大写的 ascii 字母开头:它总是会变成 VAR。
因此,如果您的解析器规则如下所示:
foo
: IDENT
;
并且整个输入是"BAR",那么就会出现解析器错误,因为词法分析器不会生成INDENT 标记,而是生成VAR 标记,即使解析器“要求”IDENT .
您必须了解,无论解析器向词法分析器提出什么要求,词法分析器都独立于解析器运行。