区分标识符和变量名的简洁方法(ANTLR)?

区分标识符和变量名的简洁方法(ANTLR)?,antlr,grammar,variable-names,Antlr,Grammar,Variable Names,在ANTLR语法中,我们如何区分变量名和标识符 VAR: ('A'..'Z')+ DIGIT* ; IDENT : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'-')*; 这段语法(在ANTLR中)不起作用,因为编译器会抱怨某些输入可能永远无法到达IDENT。这似乎是编译器编写人员的一个典型的头部攻击 对于ANTLR用户,你能告诉我你解决这个问题的好方法吗?谢谢 泽尔写道: 这段语法(在ANTLR中)不起作用,因为编

在ANTLR语法中,我们如何区分变量名和标识符

VAR: ('A'..'Z')+ DIGIT*  ;
IDENT  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'-')*;
这段语法(在ANTLR中)不起作用,因为编译器会抱怨某些输入可能永远无法到达IDENT。这似乎是编译器编写人员的一个典型的头部攻击

对于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';
不会产生任何错误或警告。lexer只创建两种类型的令牌:

  • 如果某个字符以一个或多个大写ascii字母开头,后跟零个或多个数字,则会创建一个
    VAR
  • 如果某个内容以小写ascii字母或下划线开头,后跟
    ('a'..'z'|'a'..'z'|'0'..'9'|'|'|'-')*
    ,则会创建
    标识
  • 请注意,因此,
    IDENT
    永远不能以大写ascii字母开头:它将始终成为
    VAR

    因此,如果您有一个如下所示的解析器规则:

    foo
      :  IDENT
      ;
    
    而整个输入是
    “BAR”
    ,则会出现解析器错误,因为lexer不会生成
    缩进标记,而是
    VAR
    标记,即使解析器“请求”一个
    标识

    您必须理解,无论解析器向lexer请求什么,lexer都独立于解析器进行操作