@@ -1973,10 +1973,10 @@ class Lexer
19731973 t.postfix = * p;
19741974 p++ ;
19751975 // disallow e.g. `@r"_"dtype var;`
1976- if (! Ccompile && (isidchar (* p) || * p & 0x80 ))
1976+ if (! Ccompile && (isalpha (* p) || * p & 0x80 ))
19771977 {
19781978 const loc = loc();
1979- error(loc, " alphanumeric character cannot follow string literal `%c` postfix without whitespace" ,
1979+ error(loc, " identifier character cannot follow string `%c` postfix without whitespace" ,
19801980 p[- 1 ]);
19811981 }
19821982 break ;
@@ -2000,18 +2000,6 @@ class Lexer
20002000 {
20012001 int base = 10 ;
20022002 const start = p;
2003- scope (exit)
2004- {
2005- // disallow e.g. `@10Utype var;`
2006- if (! Ccompile && p > start &&
2007- (isalpha(p[- 1 ]) || p[- 1 ] & 0x80 ) &&
2008- (isidchar(* p) || * p & 0x80 ))
2009- {
2010- const loc = loc();
2011- error(loc, " alphanumeric character cannot follow numeric literal `%s` without whitespace" ,
2012- start[0 .. p- start].xarraydup().ptr);
2013- }
2014- }
20152003 ulong n = 0 ; // unsigned >=64 bit integer type
20162004 int d;
20172005 bool err = false ;
@@ -2205,6 +2193,7 @@ class Lexer
22052193 FLAGS flags = (base == 10 ) ? FLAGS .decimal : FLAGS .none;
22062194 // Parse trailing 'u', 'U', 'l' or 'L' in any combination
22072195 const psuffix = p;
2196+ LIntegerSuffix:
22082197 while (1 )
22092198 {
22102199 FLAGS f;
@@ -2213,26 +2202,31 @@ class Lexer
22132202 case ' U' :
22142203 case ' u' :
22152204 f = FLAGS .unsigned;
2216- goto L1 ;
2205+ break ;
22172206 case ' l' :
2218- f = FLAGS .long_;
22192207 error(" lower case integer suffix 'l' is not allowed. Please use 'L' instead" );
2220- goto L1 ;
2208+ goto case ;
22212209 case ' L' :
22222210 f = FLAGS .long_;
2223- L1 :
2224- p++ ;
2225- if ((flags & f) && ! err)
2211+ break ;
2212+ default :
2213+ // disallow e.g. `Foo!5Luvar;`
2214+ if (! Ccompile && flags >= FLAGS .unsigned && (isalpha(* p) || * p & 0x80 ))
22262215 {
2227- error(" unrecognized token" );
2228- err = true ;
2216+ const loc = loc();
2217+ error(loc, " identifier character cannot follow integer `%c` suffix without whitespace" ,
2218+ p[- 1 ]);
22292219 }
2230- flags = cast (FLAGS )(flags | f);
2231- continue ;
2232- default :
2233- break ;
2220+ break LIntegerSuffix;
22342221 }
2235- break ;
2222+ p++ ;
2223+ if ((flags & f) && ! err)
2224+ {
2225+ error(" unrecognized token" );
2226+ err = true ;
2227+ }
2228+ flags = cast (FLAGS )(flags | f);
2229+ continue ;
22362230 }
22372231 if (base == 8 && n >= 8 )
22382232 {
@@ -2609,6 +2603,7 @@ class Lexer
26092603 imaginary = true ;
26102604 }
26112605
2606+ bool gotSuffix = false ;
26122607 switch (* p)
26132608 {
26142609 case ' F' :
@@ -2622,7 +2617,7 @@ class Lexer
26222617 if (isWellformedString && ! isOutOfRange)
26232618 isOutOfRange = Port.isFloat64LiteralOutOfRange(sbufptr);
26242619 result = TOK .float64Literal;
2625- break ;
2620+ goto LcheckI ;
26262621 case ' l' :
26272622 if (! Ccompile)
26282623 error(" use 'L' suffix instead of 'l'" );
@@ -2634,13 +2629,22 @@ class Lexer
26342629 result = TOK .float80Literal;
26352630 break ;
26362631 }
2637-
2632+ gotSuffix = true ;
2633+ LcheckI:
26382634 if ((* p == ' i' || * p == ' I' ) && ! Ccompile)
26392635 {
26402636 if (* p == ' I' )
26412637 error(" use 'i' suffix instead of 'I'" );
26422638 p++ ;
26432639 imaginary = true ;
2640+ gotSuffix = true ;
2641+ }
2642+ // disallow e.g. `Foo!5fvar;`
2643+ if (! Ccompile && gotSuffix && (isalpha(* p) || * p & 0x80 ))
2644+ {
2645+ const loc = loc();
2646+ error(loc, " identifier character cannot follow float `%c` suffix without whitespace" ,
2647+ p[- 1 ]);
26442648 }
26452649
26462650 if (imaginary)
0 commit comments