summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml/parser/qdeclarativejslexer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/qml/parser/qdeclarativejslexer.cpp')
-rw-r--r--src/declarative/qml/parser/qdeclarativejslexer.cpp150
1 files changed, 120 insertions, 30 deletions
diff --git a/src/declarative/qml/parser/qdeclarativejslexer.cpp b/src/declarative/qml/parser/qdeclarativejslexer.cpp
index 3a0e897..975ad4c 100644
--- a/src/declarative/qml/parser/qdeclarativejslexer.cpp
+++ b/src/declarative/qml/parser/qdeclarativejslexer.cpp
@@ -484,6 +484,8 @@ int Lexer::lex()
stackToken = -1;
}
+ bool identifierWithEscapedUnicode = false;
+
while (!done) {
switch (state) {
case Start:
@@ -523,7 +525,26 @@ int Lexer::lex()
state = InString;
multiLineString = false;
stringType = current;
+ } else if (current == '\\' && next1 == 'u') {
+ identifierWithEscapedUnicode = true;
+ recordStartPos();
+
+ shift(2); // skip the unicode escape prefix `\u'
+
+ if (isHexDigit(current) && isHexDigit(next1) &&
+ isHexDigit(next2) && isHexDigit(next3)) {
+ record16(convertUnicode(current, next1, next2, next3));
+ shift(3);
+ state = InIdentifier;
+ } else {
+ setDone(Bad);
+ err = IllegalUnicodeEscapeSequence;
+ errmsg = QCoreApplication::translate("QDeclarativeParser", "Illegal unicode escape sequence");
+ break;
+ }
+
} else if (isIdentLetter(current)) {
+ identifierWithEscapedUnicode = false;
recordStartPos();
record16(current);
state = InIdentifier;
@@ -683,6 +704,21 @@ int Lexer::lex()
if (isIdentLetter(current) || isDecimalDigit(current)) {
record16(current);
break;
+ } else if (current == '\\' && next1 == 'u') {
+ identifierWithEscapedUnicode = true;
+ shift(2); // skip the unicode escape prefix `\u'
+
+ if (isHexDigit(current) && isHexDigit(next1) &&
+ isHexDigit(next2) && isHexDigit(next3)) {
+ record16(convertUnicode(current, next1, next2, next3));
+ shift(3);
+ break;
+ } else {
+ setDone(Bad);
+ err = IllegalUnicodeEscapeSequence;
+ errmsg = QCoreApplication::translate("QDeclarativeParser", "Illegal unicode escape sequence");
+ break;
+ }
}
setDone(Identifier);
break;
@@ -825,7 +861,11 @@ int Lexer::lex()
delimited = true;
return token;
case Identifier:
- if ((token = findReservedWord(buffer16, pos16)) < 0) {
+ token = -1;
+ if (! identifierWithEscapedUnicode)
+ token = findReservedWord(buffer16, pos16);
+
+ if (token < 0) {
/* TODO: close leak on parse error. same holds true for String */
if (driver)
qsyylval.ustr = driver->intern(buffer16, pos16);
@@ -1104,47 +1144,97 @@ void Lexer::recordStartPos()
bool Lexer::scanRegExp(RegExpBodyPrefix prefix)
{
pos16 = 0;
- bool lastWasEscape = false;
+ pattern = 0;
if (prefix == EqualPrefix)
record16(QLatin1Char('='));
- while (1) {
- if (isLineTerminator() || current == 0) {
+ while (true) {
+ switch (current) {
+
+ case 0: // eof
+ case '\n': case '\r': // line terminator
errmsg = QCoreApplication::translate("QDeclarativeParser", "Unterminated regular expression literal");
return false;
- }
- else if (current != '/' || lastWasEscape == true)
- {
- record16(current);
- lastWasEscape = !lastWasEscape && (current == '\\');
- }
- else {
- if (driver)
+
+ case '/':
+ shift(1);
+
+ if (driver) // create the pattern
pattern = driver->intern(buffer16, pos16);
- else
- pattern = 0;
+
+ // scan the flags
pos16 = 0;
+ flags = 0;
+ while (isIdentLetter(current)) {
+ int flag = Ecma::RegExp::flagFromChar(current);
+ if (flag == 0) {
+ errmsg = QCoreApplication::translate("QDeclarativeParser", "Invalid regular expression flag '%0'")
+ .arg(QChar(current));
+ return false;
+ }
+ flags |= flag;
+ record16(current);
+ shift(1);
+ }
+ return true;
+
+ case '\\':
+ // regular expression backslash sequence
+ record16(current);
+ shift(1);
+
+ if (! current || isLineTerminator()) {
+ errmsg = QCoreApplication::translate("QDeclarativeParser", "Unterminated regular expression backslash sequence");
+ return false;
+ }
+
+ record16(current);
shift(1);
break;
- }
- shift(1);
- }
- flags = 0;
- while (isIdentLetter(current)) {
- int flag = Ecma::RegExp::flagFromChar(current);
- if (flag == 0) {
- errmsg = QCoreApplication::translate("QDeclarativeParser", "Invalid regular expression flag '%0'")
- .arg(QChar(current));
- return false;
- }
- flags |= flag;
- record16(current);
- shift(1);
- }
+ case '[':
+ // regular expression class
+ record16(current);
+ shift(1);
+
+ while (current && ! isLineTerminator()) {
+ if (current == ']')
+ break;
+ else if (current == '\\') {
+ // regular expression backslash sequence
+ record16(current);
+ shift(1);
+
+ if (! current || isLineTerminator()) {
+ errmsg = QCoreApplication::translate("QDeclarativeParser", "Unterminated regular expression backslash sequence");
+ return false;
+ }
+
+ record16(current);
+ shift(1);
+ } else {
+ record16(current);
+ shift(1);
+ }
+ }
+
+ if (current != ']') {
+ errmsg = QCoreApplication::translate("QDeclarativeParser", "Unterminated regular expression class");
+ return false;
+ }
+
+ record16(current);
+ shift(1); // skip ]
+ break;
+
+ default:
+ record16(current);
+ shift(1);
+ } // switch
+ } // while
- return true;
+ return false;
}
void Lexer::syncProhibitAutomaticSemicolon()