summaryrefslogtreecommitdiffstats
path: root/src/declarative/qml/parser
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/qml/parser')
-rw-r--r--src/declarative/qml/parser/javascript.g6
-rw-r--r--src/declarative/qml/parser/javascriptast.cpp38
-rw-r--r--src/declarative/qml/parser/javascriptast_p.h37
-rw-r--r--src/declarative/qml/parser/javascriptlexer.cpp57
-rw-r--r--src/declarative/qml/parser/javascriptlexer_p.h19
-rw-r--r--src/declarative/qml/parser/javascriptparser.cpp6
-rw-r--r--src/declarative/qml/parser/parser.pri2
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 \