Floating point 如何解析对数字具有不明确标记引用的复数的ANTLR规则?

Floating point 如何解析对数字具有不明确标记引用的复数的ANTLR规则?,floating-point,antlr4,grammar,complex-numbers,Floating Point,Antlr4,Grammar,Complex Numbers,我有以下ANTLR规则来解析float复数,其中float可以这样写: 三, 3.0 3f 而float和i应该是可互换的(例如,float i | i float) 以下是ANTLR语法规则(我知道,它很难看,都在一行中): 我不知道如何具体检索每个数字,有人知道如何检索吗?因为ctx.DIGIT()?不是每个部分都特别地=o,然后我不确定如何检索或+或-符号等前面的所有数字 非常感谢您提供的任何帮助或想法我想这样做会容易得多,因为我可以直接调用ctx.NUMBER()或ctx.UN

我有以下ANTLR规则来解析
float
复数,其中float可以这样写:

  • 三,
  • 3.0
  • 3f
float
i
应该是可互换的(例如,float i | i float)

以下是ANTLR语法规则(我知道,它很难看,都在一行中):

我不知道如何具体检索每个数字,有人知道如何检索吗?因为
ctx.DIGIT()?不是每个部分都特别地=o,然后我不确定如何检索
+
-
符号等前面的所有数字


非常感谢您提供的任何帮助或想法

我想这样做会容易得多,因为我可以直接调用
ctx.NUMBER()
ctx.UNSIGNED()
来检查是否提供了:

// Parser rules
complexAtom : NUMBER? EXP POW (I UNSIGNED?|UNSIGNED I)  # PolarComplex
    | NUMBER? CIS UNSIGNED                              # CisComplex
    | (NUMBER (ADD|SUB))? (I UNSIGNED?|UNSIGNED I)      # Complex
    ;

// Lexer rules
NUMBER : INT 
    | FLOAT 
    ;
UNSIGNED: DIGIT+ 'f'        
    | DIGIT+ DOT (DIGIT+)?
    | DIGIT+
    ;
INT : SUB? DIGIT+ ;
FLOAT : INT DOT (DIGIT+)?
    | INT 'f' 
    ;
DIGIT : [0-9] ;
EXP: [Ee] ;
ADD : '+' ;
SUB : '-' ;
POW : '^' ;
DOT : '.' ;
CIS : 'cis' ;
I : 'i' ;

WS : [ \t]+ -> skip ;
编辑:我还找到了如何让lexer使用以下lexer语法直接解析成
复杂的
标记(最终我可以管理访问者代码中的实际解析):

// Lexer grammar
COMPLEX : SUB? IMAGINARY
    | NUMBER (ADD|SUB) IMAGINARY
    ;
POLAR_COMPLEX : NUMBER? EXP POW IMAGINARY ; 
CIS_COMPLEX : NUMBER? CIS UNSIGNED ;

UFLOAT : UINT (DOT UINT? | 'f') ;
FLOAT : SUB UFLOAT ;
UINT : DIGITS ;
INT : SUB UINT ;

CIS : 'cis' ;
IM : 'I' ;
ADD : '+' ;
SUB : '-' ;
POW : '^' ;
DOT : '.' ;
EXP : [Ee] ;
DIGITS : DIGIT+ ;
DIGIT : [0-9] ;

fragment IMAGINARY : IM UNSIGNED? 
    | UNSIGNED IM
    ;
fragment NUMBER : UFLOAT
    | FLOAT
    | UINT
    | INT
    ;
fragment UNSIGNED : UFLOAT 
    | UINT 
    ;

WS : [ \t]+ -> skip ;

是的,这是正确的。lexer返回一个带有类型和文本的令牌。它不会像解析器那样将复数划分为多个部分。因此,您将规则移动到了解析器。但是,如果语法中有空格,但规则的标记之间不允许有空格,则还需要检查是否完整。但是,大多数人并不担心这个细节。哦,是的,我很抱歉,为了完整起见,让我现在添加它,我实际上有一个WS-lexer规则来跳过空白。但是谢谢你的确认,因为我还不确定这是不是最好的方式+-inf和nans呢?这些是浮子,eg 17.0+iInf是一个复合物number@dmuir我认为for+和-
inf
可以作为数字和无符号lexer规则内的标记添加。您可能需要考虑的另一件事是以十六进制打印的浮点。例如,C有%a格式说明符;如果打印2647.0/1024.0,则得到0x1.4aep+1。虽然没有多少人会输入这样的数字,但它们很可能出现在程序生成的文件中。它们的优点是直接表示二进制,因此不存在舍入问题。
// Lexer grammar
COMPLEX : SUB? IMAGINARY
    | NUMBER (ADD|SUB) IMAGINARY
    ;
POLAR_COMPLEX : NUMBER? EXP POW IMAGINARY ; 
CIS_COMPLEX : NUMBER? CIS UNSIGNED ;

UFLOAT : UINT (DOT UINT? | 'f') ;
FLOAT : SUB UFLOAT ;
UINT : DIGITS ;
INT : SUB UINT ;

CIS : 'cis' ;
IM : 'I' ;
ADD : '+' ;
SUB : '-' ;
POW : '^' ;
DOT : '.' ;
EXP : [Ee] ;
DIGITS : DIGIT+ ;
DIGIT : [0-9] ;

fragment IMAGINARY : IM UNSIGNED? 
    | UNSIGNED IM
    ;
fragment NUMBER : UFLOAT
    | FLOAT
    | UINT
    | INT
    ;
fragment UNSIGNED : UFLOAT 
    | UINT 
    ;

WS : [ \t]+ -> skip ;