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

时间:2011-12-02 14:31:33

标签: antlr grammar variable-names

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

VAR: ('A'..'Z')+ DIGIT*  ;
IDENT  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'-')*;

这段语法(在ANTLR中)不起作用,因为编译器会抱怨某些输入可能永远无法访问IDENT。这似乎是编译器编写者The lexer hack

的经典头脑攻击

对于ANTLR用户,你能告诉我你的整洁方法吗?感谢

1 个答案:

答案 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';

不会产生任何错误或警告。词法分析器只创建两种类型的标记:

  1. 如果某件事以一个或多个大写字母ascii字母后跟零个或多个数字开头,则会创建VAR;
  2. 如果某些内容以小写的ascii字母或下划线开头,后跟('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'-')*,则会创建IDENT
  3. 请注意,IDENT永远不能以大写的ascii字母开头:它始终会成为VAR

    因此,如果您的解析器规则如下:

    foo
      :  IDENT
      ;
    

    并且整个输入都是"BAR",然后会出现解析器错误,因为词法分析器不会产生INDENT令牌,而是VAR令牌,即使解析器“询问“对于IDENT

    你必须明白,无论解析器从词法分析器询问什么,词法分析器都独立于解析器运行。