# HG changeset patch # User aziz # Date 1183140901 0 # Node ID c29229fbf2f78268c18bf75820cb34fbfdd23217 # Parent 96af5653acefe3c9d4e73f69eaa8dd76a2f9a95a - Recognizing floats that start with a dot. - Fixed while loop of integer scanner. - Consuming octal as well as decimal digits in octal number scanner. - Implemented scanReal() function. - Added finalizeFloat() function to convert the recognized float string and complete the token. diff -r 96af5653acef -r c29229fbf2f7 trunk/src/Lexer.d --- a/trunk/src/Lexer.d Fri Jun 29 15:07:05 2007 +0000 +++ b/trunk/src/Lexer.d Fri Jun 29 18:15:01 2007 +0000 @@ -398,7 +398,7 @@ goto Lcommon2; } assert(0); - case '.': /* . .. ... */ + case '.': /* . .[0-9] .. ... */ if (p[1] == '.') { ++p; @@ -409,6 +409,10 @@ else t.type = TOK.Slice; } + else if (isdigit(p[1])) + { + return scanReal(t); + } else t.type = TOK.Dot; goto Lcommon; @@ -891,13 +895,6 @@ Suffix:= (L|[uU]|L[uU]|[uU]L)? HexDigits:= [0-9a-zA-Z_]+ - FloatLiteral:= Float[fFL]?i? - Float:= DecFloat | HexFloat - DecFloat:= ([0-9][0-9_]*[.]([0-9_]*DecExponent?)?) | [.][0-9][0-9_]*DecExponent? | [0-9][0-9_]*DecExponent - DecExponent:= [eE][+-]?[0-9_]+ - HexFloat:= 0[xX](HexDigits[.]HexDigits | [.][0-9a-zA-Z]HexDigits? | HexDigits)HexExponent - HexExponent:= [pP][+-]?[0-9_]+ - Invalid: "0b_", "0x_", "._" */ void scanNumber(ref Token t) @@ -939,10 +936,12 @@ LscanInteger: isDecimal = true; - while (isdigit(*++p)) + while (1) { - if (*p == '_') + if (*++p == '_') continue; + if (!isdigit(*p)) + break; if (ulong_ < ulong.max/10 || (ulong_ == ulong.max/10 && *p <= '5')) { ulong_ *= 10; @@ -1063,11 +1062,18 @@ } // Overflow: skip following digits. overflow = true; - while (isoctal(*++p)) {} + while (isdigit(*++p)) {} break; } - // The number could be a float, so check overflow below. + bool hasDecimalDigits; + if (isdigit(*p)) + { + hasDecimalDigits = true; + while (isdigit(*++p)) {} + } + + // The number could be a float, so check errors below. switch (*p) { case '.': @@ -1079,8 +1085,11 @@ break; case 'i', 'f', 'F', 'e', 'E': goto LscanReal; + default: } + if (hasDecimalDigits) + error(MID.OctalNumberHasDecimals); if (overflow) error(MID.OverflowOctalNumber); // goto Lfinalize; @@ -1158,14 +1167,64 @@ t.end = p; return; LscanReal: - p = t.start; scanReal(t); return; } + /* + FloatLiteral:= Float[fFL]?i? + Float:= DecFloat | HexFloat + DecFloat:= ([0-9][0-9_]*[.]([0-9_]*DecExponent?)?) | [.][0-9][0-9_]*DecExponent? | [0-9][0-9_]*DecExponent + DecExponent:= [eE][+-]?[0-9][0-9_]* + HexFloat:= 0[xX](HexDigits[.]HexDigits | [.][0-9a-zA-Z]HexDigits? | HexDigits)HexExponent + HexExponent:= [pP][+-]?[0-9][0-9_]* + */ void scanReal(ref Token t) { - assert(*p == '.' || isdigit(*p)); + if (*p == '.') + // This function was called by scan() or scanNumber(). + while (isdigit(*++p) || *p == '_') {} + else + { + // This function was called by scanNumber(). + debug switch (*p) + { + case 'L': + if (p[1] != 'i') + assert(0); + case 'i', 'f', 'F', 'e', 'E': break; + default: assert(0); + } + } + + // Scan exponent. + if (*p == 'e' || *p == 'E') + { + ++p; + if (*p == '-' || *p == '+') + ++p; + if (!isdigit(*p)) + error(MID.FloatExponentDigitExpected); + else + while (isdigit(*p) || *p == '_') { ++p; } + } + + // Copy string to buffer ignoring underscores. + char[] buffer; + char* end = p; + p = t.start; + do + { + if (*p == '_') + { + ++p; + continue; + } + buffer ~= *p; + ++p; + } while (p != end) + buffer ~= 0; + finalizeFloat(t, buffer); } void scanHexReal(ref Token t) @@ -1186,9 +1245,11 @@ do { if (*p == '_') + { + ++p; continue; - else - buffer ~= *p; + } + buffer ~= *p; ++p; } while (p != end) @@ -1211,6 +1272,16 @@ goto Lerr; } buffer ~= 0; // Terminate for C functions. + finalizeFloat(t, buffer); + return; + Lerr: + t.type = TOK.Float32; + t.end = p; + error(mid); + } + + void finalizeFloat(ref Token t, string buffer) + { // Float number is well-formed. Check suffixes and do conversion. switch (*p) { @@ -1232,19 +1303,11 @@ if (*p == 'i') { ++p; - t.type += 3; // Switch to imaginary version. + t.type += 3; // Switch to imaginary counterpart. } if (getErrno == ERANGE) - { - mid = MID.OverflowHexFloatNumber; - goto Lerr; - } + error(MID.OverflowFloatNumber); t.end = p; - return; - Lerr: - t.type = TOK.Float32; - t.end = p; - error(mid); } /// Scan special token: #line Integer [Filespec] EndOfLine diff -r 96af5653acef -r c29229fbf2f7 trunk/src/Messages.d --- a/trunk/src/Messages.d Fri Jun 29 15:07:05 2007 +0000 +++ b/trunk/src/Messages.d Fri Jun 29 18:15:01 2007 +0000 @@ -42,11 +42,13 @@ OverflowHexNumber, OverflowBinaryNumber, OverflowOctalNumber, - OverflowHexFloatNumber, + OverflowFloatNumber, + OctalNumberHasDecimals, NoDigitsInHexNumber, NoDigitsInBinNumber, HexFloatExponentRequired, HexFloatMissingExpDigits, + FloatExponentDigitExpected, } string[] messages = [ @@ -85,9 +87,11 @@ "overflow in hexadecimal number.", "overflow in binary number.", "overflow in octal number.", - "overflow in hexadecimal float number.", + "overflow in float number.", + "decimal digits are not allowed in octal numbers.", "invalid hex number; at least one hex digit expected.", "invalid binary number; at least one binary digit expected.", "the exponent of a hexadecimal float number is required.", "missing decimal digits in hexadecimal float exponent.", + "exponents have to start with a digit.", ];