aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main/java/org/anarres/cpp/LexerSource.java66
-rw-r--r--src/test/java/org/anarres/cpp/NumericValueTest.java15
2 files changed, 38 insertions, 43 deletions
diff --git a/src/main/java/org/anarres/cpp/LexerSource.java b/src/main/java/org/anarres/cpp/LexerSource.java
index 607ec65..9b6fb8c 100644
--- a/src/main/java/org/anarres/cpp/LexerSource.java
+++ b/src/main/java/org/anarres/cpp/LexerSource.java
@@ -545,32 +545,6 @@ public class LexerSource extends Source {
return part.toString();
}
- /* We already chewed a zero, so empty is fine. */
- @Nonnull
- private Token number_octal(boolean negative)
- throws IOException,
- LexerException {
- StringBuilder text = new StringBuilder(negative ? "-0" : "0");
- String integer = _number_part(text, 8, false);
- NumericValue value = new NumericValue(8, negative, integer);
- int d = read();
- if (d == '.') {
- // TODO: This means it's decimal.
- text.append((char) d);
- String fraction = _number_part(text, 8, true);
- value.setFractionalPart(fraction);
- d = read();
- }
- if (d == 'E' || d == 'e') {
- // TODO: This means it's decimal.
- text.append((char) d);
- String exponent = _number_part(text, 10, true);
- value.setExponent(10, exponent);
- d = read();
- }
- return _number_suffix(text, value, d);
- }
-
/* We do not know whether know the first digit is valid. */
@Nonnull
private Token number_hex(char x, boolean negative)
@@ -597,6 +571,15 @@ public class LexerSource extends Source {
return _number_suffix(text, value, d);
}
+ private static boolean is_octal(@Nonnull String text) {
+ if (!text.startsWith("0"))
+ return false;
+ for (int i = 0; i < text.length(); i++)
+ if (Character.digit(text.charAt(i), 8) == -1)
+ return false;
+ return true;
+ }
+
/* We know we have at least one valid digit, but empty is not
* fine. */
@Nonnull
@@ -605,20 +588,31 @@ public class LexerSource extends Source {
LexerException {
StringBuilder text = new StringBuilder(negative ? "-" : "");
String integer = _number_part(text, 10, false);
- NumericValue value = new NumericValue(10, negative, integer);
+ String fraction = null;
+ String exponent = null;
int d = read();
if (d == '.') {
text.append((char) d);
- String fraction = _number_part(text, 10, false);
- value.setFractionalPart(fraction);
+ fraction = _number_part(text, 10, false);
d = read();
}
if (d == 'E' || d == 'e') {
text.append((char) d);
- String exponent = _number_part(text, 10, true);
- value.setExponent(10, exponent);
+ exponent = _number_part(text, 10, true);
d = read();
}
+ int base = 10;
+ if (fraction == null && exponent == null && integer.startsWith("0")) {
+ if (!is_octal(integer))
+ warning("Decimal constant starts with 0, but not octal: " + integer);
+ else
+ base = 8;
+ }
+ NumericValue value = new NumericValue(base, negative, integer);
+ if (fraction != null)
+ value.setFractionalPart(fraction);
+ if (exponent != null)
+ value.setExponent(10, exponent);
// XXX Make sure it's got enough parts
return _number_suffix(text, value, d);
}
@@ -669,18 +663,12 @@ public class LexerSource extends Source {
int d = read();
if (d == 'x' || d == 'X') {
tok = number_hex((char) d, negative);
- } else if (d == '.') {
+ } else {
unread(d);
unread(c);
tok = number_decimal(negative);
- } else {
- unread(d);
- tok = number_octal(negative);
}
- } else if (Character.isDigit(c)) {
- unread(c);
- tok = number_decimal(negative);
- } else if (c == '.') {
+ } else if (Character.isDigit(c) || c == '.') {
unread(c);
tok = number_decimal(negative);
} else {
diff --git a/src/test/java/org/anarres/cpp/NumericValueTest.java b/src/test/java/org/anarres/cpp/NumericValueTest.java
index 7907457..9d6cbe4 100644
--- a/src/test/java/org/anarres/cpp/NumericValueTest.java
+++ b/src/test/java/org/anarres/cpp/NumericValueTest.java
@@ -78,13 +78,20 @@ public class NumericValueTest {
testNumericValue("-1e1", -1e1);
testNumericValue("1e-1", 1e-1);
- // Based numbers with exponents
- // testNumericValue("012e3", 012e3); // Fails
+ // Hex numbers with decimal exponents
testNumericValue("0x12e3", 0x12e3);
testNumericValue("0x12p3", 0x12p3);
- // Octal prefix with decimal suffix
- // testNumericValue("067e8", 067e8); // Fails
+ // Octal numbers with decimal exponents
+ testNumericValue("012e3", 012e3); // Fails
+ testNumericValue("067e4", 067e4); // Fails
+
+ // Issues a warning.
+ try {
+ testNumericValue("097", 97);
+ fail("No warning.");
+ } catch (LexerException e) {
+ }
}
}