diff options
Diffstat (limited to 'src/declarative/qml/parser')
-rw-r--r-- | src/declarative/qml/parser/javascript.g | 6 | ||||
-rw-r--r-- | src/declarative/qml/parser/javascriptast.cpp | 38 | ||||
-rw-r--r-- | src/declarative/qml/parser/javascriptast_p.h | 37 | ||||
-rw-r--r-- | src/declarative/qml/parser/javascriptlexer.cpp | 57 | ||||
-rw-r--r-- | src/declarative/qml/parser/javascriptlexer_p.h | 19 | ||||
-rw-r--r-- | src/declarative/qml/parser/javascriptparser.cpp | 6 | ||||
-rw-r--r-- | src/declarative/qml/parser/parser.pri | 2 |
7 files changed, 150 insertions, 15 deletions
diff --git a/src/declarative/qml/parser/javascript.g b/src/declarative/qml/parser/javascript.g index 155630b..8cabeea 100644 --- a/src/declarative/qml/parser/javascript.g +++ b/src/declarative/qml/parser/javascript.g @@ -875,7 +875,7 @@ case $rule_number: { PrimaryExpression: T_NUMERIC_LITERAL ; /. case $rule_number: { - AST::NumericLiteral *node = makeAstNode<AST::NumericLiteral> (driver->nodePool(), sym(1).dval); + AST::NumericLiteral *node = makeAstNode<AST::NumericLiteral> (driver->nodePool(), sym(1).dval, lexer->flags); node->literalToken = loc(1); sym(1).Node = node; } break; @@ -2830,7 +2830,7 @@ PropertyNameAndValueListOpt: PropertyNameAndValueList ; yytoken = *tk; yylval = 0; yylloc = token_buffer[0].loc; - yylloc.length = 0; + yylloc.length = 0; first_token = &token_buffer[0]; last_token = &token_buffer[2]; @@ -2852,7 +2852,7 @@ PropertyNameAndValueListOpt: PropertyNameAndValueList ; yytoken = tk; yylval = 0; yylloc = token_buffer[0].loc; - yylloc.length = 0; + yylloc.length = 0; action = errorState; goto _Lcheck_token; diff --git a/src/declarative/qml/parser/javascriptast.cpp b/src/declarative/qml/parser/javascriptast.cpp index 083dd28..130229b 100644 --- a/src/declarative/qml/parser/javascriptast.cpp +++ b/src/declarative/qml/parser/javascriptast.cpp @@ -49,6 +49,44 @@ QT_BEGIN_NAMESPACE namespace JavaScript { namespace AST { +int NumericLiteral::suffixLength[] = { + 0, // noSuffix + 2, // emSuffix + 2, // exSuffix + 2, // pxSuffix + 2, // cmSuffix + 2, // mmSuffix + 2, // inSuffix + 2, // ptSuffix + 2, // pcSuffix + 3, // degSuffix + 3, // radSuffix + 4, // gradSuffix + 2, // msSuffix + 1, // sSuffix + 2, // hzSuffix + 3 // khzSuffix +}; + +const char *const NumericLiteral::suffixSpell[] = { + "", + "em", + "ex", + "px", + "cm", + "mm", + "in", + "pt", + "pc", + "deg", + "rad", + "grad", + "ms", + "s", + "hz", + "khz" +}; + ExpressionNode *Node::expressionCast() { return 0; diff --git a/src/declarative/qml/parser/javascriptast_p.h b/src/declarative/qml/parser/javascriptast_p.h index 134f3cc..b5fd922 100644 --- a/src/declarative/qml/parser/javascriptast_p.h +++ b/src/declarative/qml/parser/javascriptast_p.h @@ -398,8 +398,30 @@ class NumericLiteral: public ExpressionNode public: JAVASCRIPT_DECLARE_AST_NODE(NumericLiteral) - NumericLiteral(double v): - value (v) { kind = K; } + enum Suffix { // ### keep it in sync with the Suffix enum in javascriptlexer_p.h + noSuffix, + emSuffix, + exSuffix, + pxSuffix, + cmSuffix, + mmSuffix, + inSuffix, + ptSuffix, + pcSuffix, + degSuffix, + radSuffix, + gradSuffix, + msSuffix, + sSuffix, + hzSuffix, + khzSuffix + }; + + static int suffixLength[]; + static const char *const suffixSpell[]; + + NumericLiteral(double v, int suffix): + value(v), suffix(suffix) { kind = K; } virtual ~NumericLiteral() {} virtual void accept0(Visitor *visitor); @@ -412,6 +434,7 @@ public: // attributes: double value; + int suffix; SourceLocation literalToken; }; @@ -2314,7 +2337,7 @@ public: virtual SourceLocation firstSourceLocation() const { if (defaultToken.isValid()) - return defaultToken; + return defaultToken; return propertyToken; } @@ -2375,9 +2398,9 @@ public: virtual SourceLocation firstSourceLocation() const { if (FunctionDeclaration *funDecl = cast<FunctionDeclaration *>(sourceElement)) - return funDecl->firstSourceLocation(); + return funDecl->firstSourceLocation(); else if (VariableStatement *varStmt = cast<VariableStatement *>(sourceElement)) - return varStmt->firstSourceLocation(); + return varStmt->firstSourceLocation(); return SourceLocation(); } @@ -2385,9 +2408,9 @@ public: virtual SourceLocation lastSourceLocation() const { if (FunctionDeclaration *funDecl = cast<FunctionDeclaration *>(sourceElement)) - return funDecl->lastSourceLocation(); + return funDecl->lastSourceLocation(); else if (VariableStatement *varStmt = cast<VariableStatement *>(sourceElement)) - return varStmt->lastSourceLocation(); + return varStmt->lastSourceLocation(); return SourceLocation(); } diff --git a/src/declarative/qml/parser/javascriptlexer.cpp b/src/declarative/qml/parser/javascriptlexer.cpp index 7455b87..fda6ad2 100644 --- a/src/declarative/qml/parser/javascriptlexer.cpp +++ b/src/declarative/qml/parser/javascriptlexer.cpp @@ -377,7 +377,7 @@ int Lexer::findReservedWord(const QChar *c, int size) const else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('r') && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('p') && c[4] == QLatin1Char('e') && c[5] == QLatin1Char('r') - && c[6] == QLatin1Char('t') && c[7] == QLatin1Char('y')) + && c[6] == QLatin1Char('t') && c[7] == QLatin1Char('y')) return JavaScriptGrammar::T_PROPERTY; else if (check_reserved) { if (c[0] == QLatin1Char('a') && c[1] == QLatin1Char('b') @@ -753,12 +753,65 @@ int Lexer::lex() bol = false; } + if (state == Number) { + // CSS-style suffix for numeric literals + + flags = noSuffix; + + if (current == 'e' && next1 == 'm') { + flags = emSuffix; + shift(2); + } else if (current == 'e' && next1 == 'x') { + flags = exSuffix; + shift(2); + } else if (current == 'p' && next1 == 'x') { + flags = pxSuffix; + shift(2); + } else if (current == 'c' && next1 == 'm') { + flags = cmSuffix; + shift(2); + } else if (current == 'm' && next1 == 'm') { + flags = mmSuffix; + shift(2); + } else if (current == 'i' && next1 == 'n') { + flags = inSuffix; + shift(2); + } else if (current == 'p' && next1 == 't') { + flags = ptSuffix; + shift(2); + } else if (current == 'p' && next1 == 'c') { + flags = pcSuffix; + shift(1); + } else if (current == 'd' && next1 == 'e' && next2 == 'g') { + flags = degSuffix; + shift(3); + } else if (current == 'r' && next1 == 'a' && next2 == 'd') { + flags = radSuffix; + shift(3); + } else if (current == 'g' && next1 == 'r' && next2 == 'a' && next3 == 'd') { + flags = gradSuffix; + shift(4); + } else if (current == 'm' && next1 == 's') { + flags = msSuffix; + shift(2); + } else if (current == 's') { + flags = sSuffix; + shift(1); + } else if (current == 'h' && next1 == 'z') { + flags = hzSuffix; + shift(2); + } else if (current == 'k' && next1 == 'h' && next2 == 'z') { + flags = khzSuffix; + shift(3); + } + } + // no identifiers allowed directly after numeric literal, e.g. "3in" is bad if ((state == Number || state == Octal || state == Hex) && isIdentLetter(current)) { state = Bad; err = IllegalIdentifier; - errmsg = QLatin1String("Identifier cannot start with numeric literal"); + errmsg = QLatin1String("Identifier cannot start with numeric literal `%1'"); } // terminate string diff --git a/src/declarative/qml/parser/javascriptlexer_p.h b/src/declarative/qml/parser/javascriptlexer_p.h index 092609c..a47c1ae 100644 --- a/src/declarative/qml/parser/javascriptlexer_p.h +++ b/src/declarative/qml/parser/javascriptlexer_p.h @@ -112,6 +112,25 @@ public: Other, Bad }; + enum Suffix { + noSuffix, + emSuffix, + exSuffix, + pxSuffix, + cmSuffix, + mmSuffix, + inSuffix, + ptSuffix, + pcSuffix, + degSuffix, + radSuffix, + gradSuffix, + msSuffix, + sSuffix, + hzSuffix, + khzSuffix + }; + enum Error { NoError, IllegalCharacter, diff --git a/src/declarative/qml/parser/javascriptparser.cpp b/src/declarative/qml/parser/javascriptparser.cpp index 7ff438e..34ecd0e 100644 --- a/src/declarative/qml/parser/javascriptparser.cpp +++ b/src/declarative/qml/parser/javascriptparser.cpp @@ -430,7 +430,7 @@ case 51: { } break; case 52: { - AST::NumericLiteral *node = makeAstNode<AST::NumericLiteral> (driver->nodePool(), sym(1).dval); + AST::NumericLiteral *node = makeAstNode<AST::NumericLiteral> (driver->nodePool(), sym(1).dval, lexer->flags); node->literalToken = loc(1); sym(1).Node = node; } break; @@ -1675,7 +1675,7 @@ case 320: { yytoken = *tk; yylval = 0; yylloc = token_buffer[0].loc; - yylloc.length = 0; + yylloc.length = 0; first_token = &token_buffer[0]; last_token = &token_buffer[2]; @@ -1697,7 +1697,7 @@ case 320: { yytoken = tk; yylval = 0; yylloc = token_buffer[0].loc; - yylloc.length = 0; + yylloc.length = 0; action = errorState; goto _Lcheck_token; diff --git a/src/declarative/qml/parser/parser.pri b/src/declarative/qml/parser/parser.pri index b4d226a..72bd46c 100644 --- a/src/declarative/qml/parser/parser.pri +++ b/src/declarative/qml/parser/parser.pri @@ -1,4 +1,6 @@ +INCLUDEPATH += $$PWD + HEADERS += $$PWD/javascriptast_p.h \ $$PWD/javascriptastfwd_p.h \ $$PWD/javascriptastvisitor_p.h \ |