in src/Parsing/Impl/Tokens/Tokenizer.cs [1053:1141]
private Token ReadNumber(int start) {
var b = 10;
if (start == '0') {
if (NextChar('x') || NextChar('X')) {
return ReadHexNumber();
} else if (LanguageVersion >= PythonLanguageVersion.V26) {
if ((NextChar('b') || NextChar('B'))) {
return ReadBinaryNumber();
} else if (NextChar('o') || NextChar('O')) {
return ReadOctalNumber();
}
}
b = 8;
}
while (true) {
var ch = NextChar();
switch (ch) {
case '.':
return ReadFraction();
case 'e':
case 'E':
return ReadExponent();
case 'j':
case 'J':
MarkTokenEnd();
// TODO: parse in place
if (Verbatim) {
var tokenStr = GetTokenString();
return new VerbatimConstantValueToken(LiteralParser.ParseImaginary(tokenStr), tokenStr);
}
return new ConstantValueToken(LiteralParser.ParseImaginary(GetTokenString()));
case 'l':
case 'L': {
MarkTokenEnd();
var tokenStr = GetTokenString();
try {
if (Verbatim) {
return new VerbatimConstantValueToken(ParseBigInteger(tokenStr, b), tokenStr);
}
return new ConstantValueToken(ParseBigInteger(tokenStr, b));
} catch (ArgumentException e) {
return new ErrorToken(e.Message, tokenStr);
}
}
case '_':
if (LanguageVersion < PythonLanguageVersion.V36) {
goto default;
}
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
break;
default:
BufferBack();
MarkTokenEnd();
var image = GetTokenString();
var val = ParseInteger(GetTokenString(), b);
if (b == 8 && LanguageVersion.Is3x() && (!(val is int) || !((int)val == 0))) {
ReportSyntaxError(BufferTokenSpan, "invalid token", ErrorCodes.SyntaxError);
}
if (Verbatim) {
return new VerbatimConstantValueToken(val, image);
}
// TODO: parse in place
return new ConstantValueToken(val);
}
}
}