src/jdk/nashorn/internal/parser/JSONParser.java

Print this page

        

@@ -52,14 +52,13 @@
 
     /**
      * Constructor
      * @param source  the source
      * @param errors  the error manager
-     * @param strict  are we in strict mode
      */
-    public JSONParser(final Source source, final ErrorManager errors, final boolean strict) {
-        super(source, errors, strict);
+    public JSONParser(final Source source, final ErrorManager errors) {
+        super(source, errors, false);
     }
 
     /**
      * Implementation of the Quote(value) operation as defined in the ECMA script spec
      * It wraps a String value in double quotes and escapes characters within in

@@ -133,19 +132,113 @@
             @Override
             protected boolean isStringDelimiter(final char ch) {
                 return ch == '\"';
             }
 
+            // ECMA 15.12.1.1 The JSON Lexical Grammar - JSONWhiteSpace
             @Override
             protected boolean isWhitespace(final char ch) {
                 return Lexer.isJsonWhitespace(ch);
             }
 
             @Override
             protected boolean isEOL(final char ch) {
                 return Lexer.isJsonEOL(ch);
             }
+
+            // ECMA 15.12.1.1 The JSON Lexical Grammar - JSONNumber
+            @Override
+            protected void scanNumber() {
+                // Record beginning of number.
+                final int start = position;
+                // Assume value is a decimal.
+                TokenType type = TokenType.DECIMAL;
+
+                // floating point can't start with a "." with no leading digit before
+                if (ch0 == '.') {
+                    error(Lexer.message("json.invalid.number"), STRING, position, limit);
+                }
+
+                // First digit of number.
+                int digit = convertDigit(ch0, 10);
+
+                // skip first digit
+                skip(1);
+
+                if (digit != 0) {
+                    // Skip over remaining digits.
+                    while (convertDigit(ch0, 10) != -1) {
+                        skip(1);
+                    }
+                }
+
+                if (ch0 == '.' || ch0 == 'E' || ch0 == 'e') {
+                    // Must be a double.
+                    if (ch0 == '.') {
+                        // Skip period.
+                        skip(1);
+
+                        boolean mantissa = false;
+                        // Skip mantissa.
+                        while (convertDigit(ch0, 10) != -1) {
+                            mantissa = true;
+                            skip(1);
+                        }
+
+                        if (! mantissa) {
+                            // no digit after "."
+                            error(Lexer.message("json.invalid.number"), STRING, position, limit);
+                        }
+                    }
+
+                    // Detect exponent.
+                    if (ch0 == 'E' || ch0 == 'e') {
+                        // Skip E.
+                        skip(1);
+                        // Detect and skip exponent sign.
+                        if (ch0 == '+' || ch0 == '-') {
+                            skip(1);
+                        }
+                        boolean exponent = false;
+                        // Skip exponent.
+                        while (convertDigit(ch0, 10) != -1) {
+                            exponent = true;
+                            skip(1);
+                        }
+
+                        if (! exponent) {
+                            // no digit after "E"
+                            error(Lexer.message("json.invalid.number"), STRING, position, limit);
+                        }
+                    }
+
+                    type = TokenType.FLOATING;
+                }
+
+                // Add number token.
+                add(type, start);
+            }
+
+            // ECMA 15.12.1.1 The JSON Lexical Grammar - JSONEscapeCharacter
+            @Override
+            protected boolean isEscapeCharacter(final char ch) {
+                switch (ch) {
+                    case '"':
+                    case '/':
+                    case '\\':
+                    case 'b':
+                    case 'f':
+                    case 'n':
+                    case 'r':
+                    case 't':
+                    // could be unicode escape
+                    case 'u':
+                        return true;
+                    default:
+                        return false;
+                }
+            }
         };
 
         k = -1;
 
         next();