我们如何区分 ANTLR 语法中的变量名和标识符?
VAR: ('A'..'Z')+ DIGIT* ;
IDENT : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'-')*;
这段语法(在 ANTLR 中)不起作用,因为编译器会抱怨某些输入可能永远无法达到 IDENT。对于编译器作者来说,这似乎是一个经典的头脑风暴,The lexer hack
对于 ANTLR 用户,您能告诉我您的巧妙解决方法吗?谢谢
我们如何区分 ANTLR 语法中的变量名和标识符?
VAR: ('A'..'Z')+ DIGIT* ;
IDENT : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'-')*;
这段语法(在 ANTLR 中)不起作用,因为编译器会抱怨某些输入可能永远无法达到 IDENT。对于编译器作者来说,这似乎是一个经典的头脑风暴,The lexer hack
对于 ANTLR 用户,您能告诉我您的巧妙解决方法吗?谢谢
泽尔写道:
这段语法(在 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;('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'-')*
,IDENT
则创建 a。请注意,因此 anIDENT
永远不能以大写 ascii 字母开头:那将始终变为VAR
.
因此,如果您有一个如下所示的解析器规则:
foo
: IDENT
;
并且整个输入是"BAR"
,那么就会出现解析器错误,因为词法分析器不会产生一个INDENT
标记,而是一个VAR
标记,即使解析器“要求”一个IDENT
.
您必须了解,无论解析器向词法分析器提出什么要求,词法分析器都独立于解析器运行。