Improved parsing of numeric literals
authorRoberto Raggi <roberto.raggi@nokia.com>
Wed, 20 Jul 2011 13:08:05 +0000 (15:08 +0200)
committerQt by Nokia <qt-info@nokia.com>
Tue, 30 Aug 2011 11:18:28 +0000 (13:18 +0200)
Change-Id: Id02b5b0b0ab590b7ea5d20098472459e1fd986a6
Reviewed-on: http://codereview.qt.nokia.com/3755
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
src/declarative/qml/parser/qdeclarativejsengine_p.h
src/declarative/qml/parser/qdeclarativejskeywords_p.h
src/declarative/qml/parser/qdeclarativejslexer.cpp

index 56c6be4..20abd55 100644 (file)
@@ -117,6 +117,8 @@ public:
     QStringRef newStringRef(const QChar *chars, int size);
 };
 
+double integerFromString(const char *buf, int size, int radix);
+
 } // end of namespace QDeclarativeJS
 
 QT_QML_END_NAMESPACE
index b0762d5..26e0def 100644 (file)
@@ -508,21 +508,6 @@ static inline int classify7(const QChar *s) {
       }
     }
   }
-  else if (s[0].unicode() == 'c') {
-    if (s[1].unicode() == 'o') {
-      if (s[2].unicode() == 'm') {
-        if (s[3].unicode() == 'm') {
-          if (s[4].unicode() == 'e') {
-            if (s[5].unicode() == 'n') {
-              if (s[6].unicode() == 't') {
-                return Lexer::T_COMMENT;
-              }
-            }
-          }
-        }
-      }
-    }
-  }
   else if (s[0].unicode() == 'd') {
     if (s[1].unicode() == 'e') {
       if (s[2].unicode() == 'f') {
index ac4be34..980c15c 100644 (file)
@@ -407,26 +407,40 @@ again:
         if (_char.isDigit()) {
             QByteArray chars;
             chars.reserve(32);
-            while (_char.isLetterOrNumber() || _char == QLatin1Char('.')) {
-                if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) {
+
+            chars += ch.unicode(); // append the `.'
+
+            while (_char.isDigit()) {
+                chars += _char.unicode();
+                scanChar();
+            }
+
+            if (_char.toLower() == QLatin1Char('e')) {
+                if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) &&
+                                              _codePtr[1].isDigit())) {
+
                     chars += _char.unicode();
-                    scanChar(); // skip e
+                    scanChar(); // consume `e'
 
                     if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) {
                         chars += _char.unicode();
-                        scanChar(); // skip +/-
+                        scanChar(); // consume the sign
+                    }
+
+                    while (_char.isDigit()) {
+                        chars += _char.unicode();
+                        scanChar();
                     }
-                } else {
-                    chars += _char.unicode();
-                    scanChar();
                 }
             }
+
             const char *begin = chars.constData();
             const char *end = 0;
             bool ok = false;
+
             _tokenValue = qstrtod(begin, &end, &ok);
 
-            if (! ok || end != chars.end()) {
+            if (end != chars.end()) {
                 _errorCode = IllegalExponentIndicator;
                 _errorMessage = QCoreApplication::translate("QDeclarativeParser", "Illegal syntax for exponential number");
                 return T_ERROR;
@@ -676,27 +690,80 @@ again:
             chars.reserve(32);
             chars += ch.unicode();
 
-            while (_char.isLetterOrNumber() || _char == QLatin1Char('.')) {
-                if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) {
+            if (ch == QLatin1Char('0') && (_char == 'x' || _char == 'X')) {
+                // parse hex integer literal
+
+                chars += _char.unicode();
+                scanChar(); // consume `x'
+
+                while (isHexDigit(_char)) {
                     chars += _char.unicode();
-                    scanChar(); // skip e
+                    scanChar();
+                }
+
+                _tokenValue = integerFromString(chars.constData(), chars.size(), 16);
+                return T_NUMERIC_LITERAL;
+            }
+
+            // decimal integer literal
+            while (_char.isDigit()) {
+                chars += _char.unicode();
+                scanChar(); // consume the digit
+            }
+
+            if (_char == QLatin1Char('.')) {
+                chars += _char.unicode();
+                scanChar(); // consume `.'
+
+                while (_char.isDigit()) {
+                    chars += _char.unicode();
+                    scanChar();
+                }
+
+                if (_char.toLower() == QLatin1Char('e')) {
+                    if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) &&
+                                                  _codePtr[1].isDigit())) {
 
-                    if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) {
                         chars += _char.unicode();
-                        scanChar(); // skip +/-
+                        scanChar(); // consume `e'
+
+                        if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) {
+                            chars += _char.unicode();
+                            scanChar(); // consume the sign
+                        }
+
+                        while (_char.isDigit()) {
+                            chars += _char.unicode();
+                            scanChar();
+                        }
                     }
-                } else {
+                }
+            } else if (_char.toLower() == QLatin1Char('e')) {
+                if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) &&
+                                              _codePtr[1].isDigit())) {
+
                     chars += _char.unicode();
-                    scanChar();
+                    scanChar(); // consume `e'
+
+                    if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) {
+                        chars += _char.unicode();
+                        scanChar(); // consume the sign
+                    }
+
+                    while (_char.isDigit()) {
+                        chars += _char.unicode();
+                        scanChar();
+                    }
                 }
             }
+
             const char *begin = chars.constData();
             const char *end = 0;
             bool ok = false;
 
             _tokenValue = qstrtod(begin, &end, &ok);
 
-            if (! ok || end != chars.end()) {
+            if (end != chars.end()) {
                 _errorCode = IllegalExponentIndicator;
                 _errorMessage = QCoreApplication::translate("QDeclarativeParser", "Illegal syntax for exponential number");
                 return T_ERROR;