Antlr4 在Antlr中处理关键字冲突

Antlr4 在Antlr中处理关键字冲突,antlr4,Antlr4,我正在解析一种类似以下内容的语言: SORT EQUALS,FORMAT=CH 我定义为 EQUALS : '='; 如果我定义这一点: EQUALS : [Ee][Qq][Uu][Aa][Ll][Ss]; 我要一个名字 显然,我可以这样做: ChrEQUALS : '='; EQUALS : [Ee][Qq][Uu][Aa][Ll][Ss]; 或者这个: 等于:'='; StrEQUALS:[Ee][Qq][Uu][Aa][Ll][Ss]

我正在解析一种类似以下内容的语言:

SORT EQUALS,FORMAT=CH
我定义为

EQUALS          : '=';
如果我定义这一点:

EQUALS    : [Ee][Qq][Uu][Aa][Ll][Ss];
我要一个名字

显然,我可以这样做:

ChrEQUALS          : '=';
EQUALS    : [Ee][Qq][Uu][Aa][Ll][Ss];
或者这个: 等于:'='; StrEQUALS:[Ee][Qq][Uu][Aa][Ll][Ss]

但它打破了与我其他名字的一致性

有哪些好的技术可以避免碰撞,但保持一致

以下是我考虑过的事情:

我重命名这两个,这样如果我的代码错误地等于,我会得到一个错误

ChrEQUALS    : '=';
StrEQUALS    : [Ee][Qq][Uu][Aa][Ll][Ss];

2在所有字符定义前面加上“c”

Antlr区分大小写,因此

Equals    : '=';
EQUALS    : [Ee][Qq][Uu][Aa][Ll][Ss];
按照惯例,字符文本使用大小写混合命名,字符串都是大写

或者,也许是更精确的命名:

EQUAL     : '=';
EQUALS    : [Ee][Qq][Uu][Aa][Ll][Ss];

如果这只是一次性的冲突。

我经常在关键字前面加上
K
来区分。在您的情况下,这将看起来像:

EQUALS
 : '='
 ;

K_EQUALS
 : [Ee][Qq][Uu][Aa][Ll][Ss]
 ;
如果你有很多关键词,你可以创建一堆片段来捕获不区分大小写的字母:

EQUALS
 : '='
 ;

K_EQUALS
 : E Q U A L S
 ;

fragment A : [aA];
fragment B : [bB];
...
fragment Z : [zZ];

不仅需要在语法中选择唯一的名称,还应该考虑目标语言中可能存在的冲突(例如,名为EOF的标记在C或C++中肯定会给您带来麻烦)。因此,目标应该是使名称尽可能唯一(同时保持可读性)

我通常做的是,除了运算符,我使用_运算符。除此之外,我还有没有这种语义的lexer规则(ID、ML_注释、SL_注释等)。应用到你的例子中,你会得到等分算子和等分符号。如果您有一个关键字“equal”,您仍然可以通过给定的附录很好地分隔运算符和关键字。此外,他们在你的语法中添加了澄清。像这样的规则:

rule1: A EQUAL B;
不完全清楚现在是否需要“=”或“相等”一词。通过使用适当的附录,事情会立即变得清晰:

rule1: A EQUAL_OPERATOR B;

例如,如果应用程序中有多个解析器定义了相同的规则(例如ID),那么您甚至可能需要在名称中添加更多修饰(例如ID_lang1、ID_lang2等)。

请注意,以小写开头的规则是解析器规则:
strEQUALS
应该是
strEQUALS
我喜欢在关键字上添加K_>的想法。除非有人想出更好的主意,否则我会同意的。在我将此标记为已被接受的答案之前几天,我将给出它,以便给其他一些人一个发表评论的机会。顺便说一句:我认为等号中的“=”是一个拼写错误。