处理Antlr中的关键字冲突

时间:2016-04-16 19:33:38

标签: 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];

然后它与我的其他名字打破了一致性。

什么是避免碰撞但保持一致的好技术?

以下是我考虑过的事情:

1重命名,如果我不正确编码EQUALS,我将收到错误

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

2使用'c'

前缀所有字符定义

3 个答案:

答案 0 :(得分:3)

我经常在关键字前加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];

答案 1 :(得分:0)

Antlr区分大小写,

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

使用大写字母以混合大小写和字符串全部大写命名的约定。

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

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

如果这只是一次性碰撞。

答案 2 :(得分:0)

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

我通常做的是append a _SYM or _SYMBOL to all lexer rule names,除了操作员,我使用_OPERATOR。除了那些我没有这种语义的词法规则(ID,ML_COMMENT,SL_COMMENT等)。应用于您的案例,您将拥有EQUAL_OPERATOR和EQUALS_SYMBOL。如果你有一个关键词"等于"您仍然可以通过给定的附录很好地分离运算符和关键字。另外,他们在你的语法中添加了澄清。像:

这样的规则
rule1: A EQUAL B;

目前还不完全清楚现在是否有' ='预期或等于'等等。通过使用适当的附录,事情立即变得清晰:

rule1: A EQUAL_OPERATOR B;

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