Antlr解析数字问题

Antlr解析数字问题,antlr,grammar,Antlr,Grammar,我在解析整数和十六进制数时遇到问题。我想用下面的规则解析C++枚举: grammar enum; rule_enum : 'enum' ID '{' enum_values+ '}'';'; enum_values : enum_value (COMMA enum_value)+; enum_value : ID ('=' number)?; number : hex_number | integer_number; hex_number : '0' 'x' HE

我在解析整数和十六进制数时遇到问题。我想用下面的规则解析C++枚举:

grammar enum;

rule_enum
:   'enum' ID '{' enum_values+ '}'';';

enum_values
:   enum_value (COMMA enum_value)+;

enum_value
:   ID ('=' number)?;

number  :   hex_number | integer_number;

hex_number
:   '0' 'x' HEX_DIGIT+;

integer_number
:   DIGIT+;

fragment
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;

fragment
DIGIT   :   ('0'..'9');

COMMA   :   ',';


ID  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
我遇到的问题如下-在解析类似以下代码时:

enum Enum
{
    Option1 = 0,
    Option2 = 1
};
它不将0识别为整数,但尝试将其解析为十六进制数。我如何解决这个问题

多谢各位。
Tobias

以下ANTLR仅适用于枚举的数字位。 (编辑内容包括以下Bart的建议)


首先,片段规则只能被lexer规则“看到”,而不能被解析器规则“看到”。因此,以下内容无效:

integer_number
:   DIGIT+; // can't use DIGIT here!

fragment
DIGIT   :   ('0'..'9');
为了解决这些数字的模糊性,我认为最好将这些
整数
-和
十六进制
数字设置为lexer规则,而不是解析器规则

例如:

grammar enum;

rule_enum
:   'enum' ID '{' enum_values+ '}'';';

enum_values
:   enum_value (COMMA enum_value)+;

enum_value
:   ID ('=' number)?;

number
  :  HEX_NUMBER
  |  INTEGER_NUMBER
  ;

HEX_NUMBER
:   '0' 'x' HEX_DIGIT+;

INTEGER_NUMBER
:   DIGIT+;

fragment
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;

fragment
DIGIT   :   ('0'..'9');

COMMA   :   ',';

ID  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;

SPACE : (' ' | '\t' | '\r' | '\n') {skip();};
这将生成示例代码段的以下解析树:


十六进制介绍(数字|十六进制数字)
将只匹配单个十六进制数字(它无法匹配
0xFF
)。此外,
数字
部分可以省略,因为
十六进制数字
已经包含这些数字。但是,我非常不愿意把这些东西放在语法分析器规则中:我很确定C++分析器本身也处理了一个词汇级上的整数、十六进制和八进制数的标记。上面的语法在我的ANTLR(1.4.2)副本上匹配0xFF(当活动规则是数字:)。您的建议是在Lexer级别上完全匹配十六进制数字吗?啊,是的,对不起,我错过了
十六进制数字之后的
+
。我必须说这有点误导:调用某个东西
十六进制数字
,并使其匹配多个数字!:)Jimmy,您的最新建议现在导致lexer可能生成一个只包含
'0x'
的令牌。最好将
HEX\u INTRO
作为一个片段,或者在
HEX\u NUMBER
中插入'0x'(在这种情况下,您只是复制了我的答案:)
HEX\u DIGIT
也一样:如果要解析的源代码中只有
F
一个,它就会被标记为
HEX\u DIGIT
:这不是我们的本意。最好把它也变成一个片段。谢谢你-我不知道lexer和parser规则之间的细微差别。据我所知,这种语法不处理负数
grammar enum;

rule_enum
:   'enum' ID '{' enum_values+ '}'';';

enum_values
:   enum_value (COMMA enum_value)+;

enum_value
:   ID ('=' number)?;

number
  :  HEX_NUMBER
  |  INTEGER_NUMBER
  ;

HEX_NUMBER
:   '0' 'x' HEX_DIGIT+;

INTEGER_NUMBER
:   DIGIT+;

fragment
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;

fragment
DIGIT   :   ('0'..'9');

COMMA   :   ',';

ID  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;

SPACE : (' ' | '\t' | '\r' | '\n') {skip();};