如何使用ANTLR区分保留字和变量?

Chr*_*ert 6 antlr antlr3

我正在使用ANTLR来标记一个简单的语法,并需要区分一个ID:

ID              : LETTER (LETTER | DIGIT)* ;

fragment DIGIT  : '0'..'9' ;
fragment LETTER : 'a'..'z' | 'A'..'Z' ;
Run Code Online (Sandbox Code Playgroud)

和一个RESERVED_WORD:

RESERVED_WORD : 'class' | 'public' | 'static' | 'extends' | 'void' | 'int' | 'boolean' | 'if' | 'else' | 'while' | 'return' | 'null' | 'true' | 'false' | 'this' | 'new' | 'String' ;
Run Code Online (Sandbox Code Playgroud)

假设我在输入上运行词法分析器:

class abc
Run Code Online (Sandbox Code Playgroud)

我收到两个用于"class"和"abc"的ID令牌,而我希望"class"被识别为RESERVED_WORD.我怎么能做到这一点?

Bar*_*ers 8

每当2(或更多)规则匹配相同数量的字符时,首先定义的规则将"赢".所以,如果你RESERVED_WORD之前定义ID,像这样:

RESERVED_WORD : 'class' | 'public' | 'static' | 'extends' | 'void' | 'int' | 'boolean' | 'if' | 'else' | 'while' | 'return' | 'null' | 'true' | 'false' | 'this' | 'new' | 'String' ;

ID              : LETTER (LETTER | DIGIT)* ;

fragment DIGIT  : '0'..'9' ;
fragment LETTER : 'a'..'z' | 'A'..'Z' ;
Run Code Online (Sandbox Code Playgroud)

输入"class"将被标记为a RESERVED_WORD.

请注意,创建匹配任何保留字的单个标记并没有多大意义:通常它是这样做的:

// ...

NULL  : 'null';
TRUE  : 'true';
FALSE : 'false;

// ...

ID              : LETTER (LETTER | DIGIT)* ;

fragment DIGIT  : '0'..'9' ;
fragment LETTER : 'a'..'z' | 'A'..'Z' ;
Run Code Online (Sandbox Code Playgroud)

现在"false"将成为一个FALSE象征,"falser"一个ID.