Floating point 如何解析对数字具有不明确标记引用的复数的ANTLR规则?
我有以下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
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 ;