- switch (token.kind) {
- case T_INTEGER:
- kind = EXPR_LITERAL_INTEGER;
- check_integer_suffix();
- type = type_int;
- break;
- case T_INTEGER_OCTAL:
- kind = EXPR_LITERAL_INTEGER_OCTAL;
- check_integer_suffix();
- type = type_int;
- break;
- case T_INTEGER_HEXADECIMAL:
- kind = EXPR_LITERAL_INTEGER_HEXADECIMAL;
- check_integer_suffix();
- type = type_int;
+ /* Parse base prefix. */
+ unsigned base;
+ if (*i == '0') {
+ switch (*++i) {
+ case 'B': case 'b': base = 2; ++i; break;
+ case 'X': case 'x': base = 16; ++i; break;
+ default: base = 8; digits |= 1U << 0; break;
+ }
+ } else {
+ base = 10;
+ }
+
+ /* Parse mantissa. */
+ for (;; ++i) {
+ unsigned digit;
+ switch (*i) {
+ case '.':
+ if (is_float) {
+ errorf(HERE, "multiple decimal points in %K", &token);
+ i = 0;
+ goto done;
+ }
+ is_float = true;
+ if (base == 8)
+ base = 10;
+ continue;
+
+ case '0': digit = 0; break;
+ case '1': digit = 1; break;
+ case '2': digit = 2; break;
+ case '3': digit = 3; break;
+ case '4': digit = 4; break;
+ case '5': digit = 5; break;
+ case '6': digit = 6; break;
+ case '7': digit = 7; break;
+ case '8': digit = 8; break;
+ case '9': digit = 9; break;
+ case 'A': case 'a': digit = 10; break;
+ case 'B': case 'b': digit = 11; break;
+ case 'C': case 'c': digit = 12; break;
+ case 'D': case 'd': digit = 13; break;
+ case 'E': case 'e': digit = 14; break;
+ case 'F': case 'f': digit = 15; break;
+
+ default: goto done_mantissa;
+ }
+
+ if (digit >= 10 && base != 16)
+ goto done_mantissa;
+
+ digits |= 1U << digit;
+ }
+done_mantissa:
+
+ /* Parse exponent. */
+ switch (base) {
+ case 2:
+ if (is_float)
+ errorf(HERE, "binary floating %K not allowed", &token);