source: trunk/tools/linguist/lupdate/qscript.g@ 706

Last change on this file since 706 was 651, checked in by Dmitry A. Kuminov, 16 years ago

trunk: Merged in qt 4.6.2 sources.

  • Property svn:eol-style set to native
File size: 71.2 KB
Line 
1----------------------------------------------------------------------------
2--
3-- Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4-- All rights reserved.
5-- Contact: Nokia Corporation (qt-info@nokia.com)
6--
7-- This file is part of the Qt Linguist of the Qt Toolkit.
8--
9-- $QT_BEGIN_LICENSE:LGPL$
10-- Commercial Usage
11-- Licensees holding valid Qt Commercial licenses may use this file in
12-- accordance with the Qt Commercial License Agreement provided with the
13-- Software or, alternatively, in accordance with the terms contained in
14-- a written agreement between you and Nokia.
15--
16-- GNU Lesser General Public License Usage
17-- Alternatively, this file may be used under the terms of the GNU Lesser
18-- General Public License version 2.1 as published by the Free Software
19-- Foundation and appearing in the file LICENSE.LGPL included in the
20-- packaging of this file. Please review the following information to
21-- ensure the GNU Lesser General Public License version 2.1 requirements
22-- will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23--
24-- In addition, as a special exception, Nokia gives you certain additional
25-- rights. These rights are described in the Nokia Qt LGPL Exception
26-- version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27--
28-- GNU General Public License Usage
29-- Alternatively, this file may be used under the terms of the GNU
30-- General Public License version 3.0 as published by the Free Software
31-- Foundation and appearing in the file LICENSE.GPL included in the
32-- packaging of this file. Please review the following information to
33-- ensure the GNU General Public License version 3.0 requirements will be
34-- met: http://www.gnu.org/copyleft/gpl.html.
35--
36-- If you have questions regarding the use of this file, please contact
37-- Nokia at qt-info@nokia.com.
38-- $QT_END_LICENSE$
39--
40----------------------------------------------------------------------------
41
42--------------------------------------------------------------------------------
43-- Process with "qlalr --no-debug --no-lines qscript.g" to update qscript.cpp --
44--------------------------------------------------------------------------------
45
46%parser QScriptGrammar
47%merged_output qscript.cpp
48%expect 3
49%expect-rr 1
50
51%token T_AND "&" T_AND_AND "&&" T_AND_EQ "&="
52%token T_BREAK "break" T_CASE "case" T_CATCH "catch"
53%token T_COLON ":" T_COMMA ";" T_CONTINUE "continue"
54%token T_DEFAULT "default" T_DELETE "delete" T_DIVIDE_ "/"
55%token T_DIVIDE_EQ "/=" T_DO "do" T_DOT "."
56%token T_ELSE "else" T_EQ "=" T_EQ_EQ "=="
57%token T_EQ_EQ_EQ "===" T_FINALLY "finally" T_FOR "for"
58%token T_FUNCTION "function" T_GE ">=" T_GT ">"
59%token T_GT_GT ">>" T_GT_GT_EQ ">>=" T_GT_GT_GT ">>>"
60%token T_GT_GT_GT_EQ ">>>=" T_IDENTIFIER "identifier" T_IF "if"
61%token T_IN "in" T_INSTANCEOF "instanceof" T_LBRACE "{"
62%token T_LBRACKET "[" T_LE "<=" T_LPAREN "("
63%token T_LT "<" T_LT_LT "<<" T_LT_LT_EQ "<<="
64%token T_MINUS "-" T_MINUS_EQ "-=" T_MINUS_MINUS "--"
65%token T_NEW "new" T_NOT "!" T_NOT_EQ "!="
66%token T_NOT_EQ_EQ "!==" T_NUMERIC_LITERAL "numeric literal" T_OR "|"
67%token T_OR_EQ "|=" T_OR_OR "||" T_PLUS "+"
68%token T_PLUS_EQ "+=" T_PLUS_PLUS "++" T_QUESTION "?"
69%token T_RBRACE "}" T_RBRACKET "]" T_REMAINDER "%"
70%token T_REMAINDER_EQ "%=" T_RETURN "return" T_RPAREN ")"
71%token T_SEMICOLON ";" T_AUTOMATIC_SEMICOLON T_STAR "*"
72%token T_STAR_EQ "*=" T_STRING_LITERAL "string literal"
73%token T_SWITCH "switch" T_THIS "this" T_THROW "throw"
74%token T_TILDE "~" T_TRY "try" T_TYPEOF "typeof"
75%token T_VAR "var" T_VOID "void" T_WHILE "while"
76%token T_WITH "with" T_XOR "^" T_XOR_EQ "^="
77%token T_NULL "null" T_TRUE "true" T_FALSE "false"
78%token T_CONST "const"
79%token T_DEBUGGER "debugger"
80%token T_RESERVED_WORD "reserved word"
81
82%start Program
83
84/.
85#include <translator.h>
86
87#include <QtCore/qdebug.h>
88#include <QtCore/qnumeric.h>
89#include <QtCore/qstring.h>
90#include <QtCore/qtextcodec.h>
91#include <QtCore/qvariant.h>
92
93#include <ctype.h>
94#include <stdlib.h>
95#include <stdio.h>
96#include <string.h>
97
98QT_BEGIN_NAMESPACE
99
100static void recordMessage(
101 Translator *tor, const QString &context, const QString &text, const QString &comment,
102 const QString &extracomment, bool plural, const QString &fileName, int lineNo)
103{
104 TranslatorMessage msg(
105 context, text, comment, QString(),
106 fileName, lineNo, QStringList(),
107 TranslatorMessage::Unfinished, plural);
108 msg.setExtraComment(extracomment.simplified());
109 tor->replace(msg);
110}
111
112
113namespace QScript
114{
115
116class Lexer
117{
118public:
119 Lexer();
120 ~Lexer();
121
122 void setCode(const QString &c, int lineno);
123 int lex();
124
125 int currentLineNo() const { return yylineno; }
126 int currentColumnNo() const { return yycolumn; }
127
128 int startLineNo() const { return startlineno; }
129 int startColumnNo() const { return startcolumn; }
130
131 int endLineNo() const { return currentLineNo(); }
132 int endColumnNo() const
133 { int col = currentColumnNo(); return (col > 0) ? col - 1 : col; }
134
135 bool prevTerminator() const { return terminator; }
136
137 enum State { Start,
138 Identifier,
139 InIdentifier,
140 InSingleLineComment,
141 InMultiLineComment,
142 InNum,
143 InNum0,
144 InHex,
145 InOctal,
146 InDecimal,
147 InExponentIndicator,
148 InExponent,
149 Hex,
150 Octal,
151 Number,
152 String,
153 Eof,
154 InString,
155 InEscapeSequence,
156 InHexEscape,
157 InUnicodeEscape,
158 Other,
159 Bad };
160
161 enum Error {
162 NoError,
163 IllegalCharacter,
164 UnclosedStringLiteral,
165 IllegalEscapeSequence,
166 IllegalUnicodeEscapeSequence,
167 UnclosedComment,
168 IllegalExponentIndicator,
169 IllegalIdentifier
170 };
171
172 enum ParenthesesState {
173 IgnoreParentheses,
174 CountParentheses,
175 BalancedParentheses
176 };
177
178 enum RegExpBodyPrefix {
179 NoPrefix,
180 EqualPrefix
181 };
182
183 bool scanRegExp(RegExpBodyPrefix prefix = NoPrefix);
184
185 QString pattern;
186 int flags;
187
188 State lexerState() const
189 { return state; }
190
191 QString errorMessage() const
192 { return errmsg; }
193 void setErrorMessage(const QString &err)
194 { errmsg = err; }
195 void setErrorMessage(const char *err)
196 { setErrorMessage(QString::fromLatin1(err)); }
197
198 Error error() const
199 { return err; }
200 void clearError()
201 { err = NoError; }
202
203private:
204 int yylineno;
205 bool done;
206 char *buffer8;
207 QChar *buffer16;
208 uint size8, size16;
209 uint pos8, pos16;
210 bool terminator;
211 bool restrKeyword;
212 // encountered delimiter like "'" and "}" on last run
213 bool delimited;
214 int stackToken;
215
216 State state;
217 void setDone(State s);
218 uint pos;
219 void shift(uint p);
220 int lookupKeyword(const char *);
221
222 bool isWhiteSpace() const;
223 bool isLineTerminator() const;
224 bool isHexDigit(ushort c) const;
225 bool isOctalDigit(ushort c) const;
226
227 int matchPunctuator(ushort c1, ushort c2,
228 ushort c3, ushort c4);
229 ushort singleEscape(ushort c) const;
230 ushort convertOctal(ushort c1, ushort c2,
231 ushort c3) const;
232public:
233 static unsigned char convertHex(ushort c1);
234 static unsigned char convertHex(ushort c1, ushort c2);
235 static QChar convertUnicode(ushort c1, ushort c2,
236 ushort c3, ushort c4);
237 static bool isIdentLetter(ushort c);
238 static bool isDecimalDigit(ushort c);
239
240 inline int ival() const { return qsyylval.toInt(); }
241 inline double dval() const { return qsyylval.toDouble(); }
242 inline QString ustr() const { return qsyylval.toString(); }
243 inline QVariant val() const { return qsyylval; }
244
245 const QChar *characterBuffer() const { return buffer16; }
246 int characterCount() const { return pos16; }
247
248private:
249 void record8(ushort c);
250 void record16(QChar c);
251 void recordStartPos();
252
253 int findReservedWord(const QChar *buffer, int size) const;
254
255 void syncProhibitAutomaticSemicolon();
256
257 const QChar *code;
258 uint length;
259 int yycolumn;
260 int startlineno;
261 int startcolumn;
262 int bol; // begin of line
263
264 QVariant qsyylval;
265
266 // current and following unicode characters
267 ushort current, next1, next2, next3;
268
269 struct keyword {
270 const char *name;
271 int token;
272 };
273
274 QString errmsg;
275 Error err;
276
277 bool wantRx;
278 bool check_reserved;
279
280 ParenthesesState parenthesesState;
281 int parenthesesCount;
282 bool prohibitAutomaticSemicolon;
283};
284
285} // namespace QScript
286
287extern double qstrtod(const char *s00, char const **se, bool *ok);
288
289#define shiftWindowsLineBreak() if(current == '\r' && next1 == '\n') shift(1);
290
291namespace QScript {
292
293static int toDigit(char c)
294{
295 if ((c >= '0') && (c <= '9'))
296 return c - '0';
297 else if ((c >= 'a') && (c <= 'z'))
298 return 10 + c - 'a';
299 else if ((c >= 'A') && (c <= 'Z'))
300 return 10 + c - 'A';
301 return -1;
302}
303
304double integerFromString(const char *buf, int size, int radix)
305{
306 if (size == 0)
307 return qSNaN();
308
309 double sign = 1.0;
310 int i = 0;
311 if (buf[0] == '+') {
312 ++i;
313 } else if (buf[0] == '-') {
314 sign = -1.0;
315 ++i;
316 }
317
318 if (((size-i) >= 2) && (buf[i] == '0')) {
319 if (((buf[i+1] == 'x') || (buf[i+1] == 'X'))
320 && (radix < 34)) {
321 if ((radix != 0) && (radix != 16))
322 return 0;
323 radix = 16;
324 i += 2;
325 } else {
326 if (radix == 0) {
327 radix = 8;
328 ++i;
329 }
330 }
331 } else if (radix == 0) {
332 radix = 10;
333 }
334
335 int j = i;
336 for ( ; i < size; ++i) {
337 int d = toDigit(buf[i]);
338 if ((d == -1) || (d >= radix))
339 break;
340 }
341 double result;
342 if (j == i) {
343 if (!qstrcmp(buf, "Infinity"))
344 result = qInf();
345 else
346 result = qSNaN();
347 } else {
348 result = 0;
349 double multiplier = 1;
350 for (--i ; i >= j; --i, multiplier *= radix)
351 result += toDigit(buf[i]) * multiplier;
352 }
353 result *= sign;
354 return result;
355}
356
357} // namespace QScript
358
359QScript::Lexer::Lexer()
360 :
361 yylineno(0),
362 size8(128), size16(128), restrKeyword(false),
363 stackToken(-1), pos(0),
364 code(0), length(0),
365 bol(true),
366 current(0), next1(0), next2(0), next3(0),
367 err(NoError),
368 check_reserved(true),
369 parenthesesState(IgnoreParentheses),
370 prohibitAutomaticSemicolon(false)
371{
372 // allocate space for read buffers
373 buffer8 = new char[size8];
374 buffer16 = new QChar[size16];
375 flags = 0;
376
377}
378
379QScript::Lexer::~Lexer()
380{
381 delete [] buffer8;
382 delete [] buffer16;
383}
384
385void QScript::Lexer::setCode(const QString &c, int lineno)
386{
387 errmsg = QString();
388 yylineno = lineno;
389 yycolumn = 1;
390 restrKeyword = false;
391 delimited = false;
392 stackToken = -1;
393 pos = 0;
394 code = c.unicode();
395 length = c.length();
396 bol = true;
397
398 // read first characters
399 current = (length > 0) ? code[0].unicode() : 0;
400 next1 = (length > 1) ? code[1].unicode() : 0;
401 next2 = (length > 2) ? code[2].unicode() : 0;
402 next3 = (length > 3) ? code[3].unicode() : 0;
403}
404
405void QScript::Lexer::shift(uint p)
406{
407 while (p--) {
408 ++pos;
409 ++yycolumn;
410 current = next1;
411 next1 = next2;
412 next2 = next3;
413 next3 = (pos + 3 < length) ? code[pos+3].unicode() : 0;
414 }
415}
416
417void QScript::Lexer::setDone(State s)
418{
419 state = s;
420 done = true;
421}
422
423int QScript::Lexer::findReservedWord(const QChar *c, int size) const
424{
425 switch (size) {
426 case 2: {
427 if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('o'))
428 return QScriptGrammar::T_DO;
429 else if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('f'))
430 return QScriptGrammar::T_IF;
431 else if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n'))
432 return QScriptGrammar::T_IN;
433 } break;
434
435 case 3: {
436 if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('o') && c[2] == QLatin1Char('r'))
437 return QScriptGrammar::T_FOR;
438 else if (c[0] == QLatin1Char('n') && c[1] == QLatin1Char('e') && c[2] == QLatin1Char('w'))
439 return QScriptGrammar::T_NEW;
440 else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('r') && c[2] == QLatin1Char('y'))
441 return QScriptGrammar::T_TRY;
442 else if (c[0] == QLatin1Char('v') && c[1] == QLatin1Char('a') && c[2] == QLatin1Char('r'))
443 return QScriptGrammar::T_VAR;
444 else if (check_reserved) {
445 if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n') && c[2] == QLatin1Char('t'))
446 return QScriptGrammar::T_RESERVED_WORD;
447 }
448 } break;
449
450 case 4: {
451 if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('a')
452 && c[2] == QLatin1Char('s') && c[3] == QLatin1Char('e'))
453 return QScriptGrammar::T_CASE;
454 else if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('l')
455 && c[2] == QLatin1Char('s') && c[3] == QLatin1Char('e'))
456 return QScriptGrammar::T_ELSE;
457 else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('h')
458 && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('s'))
459 return QScriptGrammar::T_THIS;
460 else if (c[0] == QLatin1Char('v') && c[1] == QLatin1Char('o')
461 && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('d'))
462 return QScriptGrammar::T_VOID;
463 else if (c[0] == QLatin1Char('w') && c[1] == QLatin1Char('i')
464 && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('h'))
465 return QScriptGrammar::T_WITH;
466 else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('r')
467 && c[2] == QLatin1Char('u') && c[3] == QLatin1Char('e'))
468 return QScriptGrammar::T_TRUE;
469 else if (c[0] == QLatin1Char('n') && c[1] == QLatin1Char('u')
470 && c[2] == QLatin1Char('l') && c[3] == QLatin1Char('l'))
471 return QScriptGrammar::T_NULL;
472 else if (check_reserved) {
473 if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('n')
474 && c[2] == QLatin1Char('u') && c[3] == QLatin1Char('m'))
475 return QScriptGrammar::T_RESERVED_WORD;
476 else if (c[0] == QLatin1Char('b') && c[1] == QLatin1Char('y')
477 && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('e'))
478 return QScriptGrammar::T_RESERVED_WORD;
479 else if (c[0] == QLatin1Char('l') && c[1] == QLatin1Char('o')
480 && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('g'))
481 return QScriptGrammar::T_RESERVED_WORD;
482 else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('h')
483 && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('r'))
484 return QScriptGrammar::T_RESERVED_WORD;
485 else if (c[0] == QLatin1Char('g') && c[1] == QLatin1Char('o')
486 && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('o'))
487 return QScriptGrammar::T_RESERVED_WORD;
488 }
489 } break;
490
491 case 5: {
492 if (c[0] == QLatin1Char('b') && c[1] == QLatin1Char('r')
493 && c[2] == QLatin1Char('e') && c[3] == QLatin1Char('a')
494 && c[4] == QLatin1Char('k'))
495 return QScriptGrammar::T_BREAK;
496 else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('a')
497 && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('c')
498 && c[4] == QLatin1Char('h'))
499 return QScriptGrammar::T_CATCH;
500 else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('h')
501 && c[2] == QLatin1Char('r') && c[3] == QLatin1Char('o')
502 && c[4] == QLatin1Char('w'))
503 return QScriptGrammar::T_THROW;
504 else if (c[0] == QLatin1Char('w') && c[1] == QLatin1Char('h')
505 && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('l')
506 && c[4] == QLatin1Char('e'))
507 return QScriptGrammar::T_WHILE;
508 else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('o')
509 && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('s')
510 && c[4] == QLatin1Char('t'))
511 return QScriptGrammar::T_CONST;
512 else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('a')
513 && c[2] == QLatin1Char('l') && c[3] == QLatin1Char('s')
514 && c[4] == QLatin1Char('e'))
515 return QScriptGrammar::T_FALSE;
516 else if (check_reserved) {
517 if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('h')
518 && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('r')
519 && c[4] == QLatin1Char('t'))
520 return QScriptGrammar::T_RESERVED_WORD;
521 else if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('u')
522 && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('e')
523 && c[4] == QLatin1Char('r'))
524 return QScriptGrammar::T_RESERVED_WORD;
525 else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('i')
526 && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('a')
527 && c[4] == QLatin1Char('l'))
528 return QScriptGrammar::T_RESERVED_WORD;
529 else if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('l')
530 && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('s')
531 && c[4] == QLatin1Char('s'))
532 return QScriptGrammar::T_RESERVED_WORD;
533 else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('l')
534 && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('a')
535 && c[4] == QLatin1Char('t'))
536 return QScriptGrammar::T_RESERVED_WORD;
537 }
538 } break;
539
540 case 6: {
541 if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('e')
542 && c[2] == QLatin1Char('l') && c[3] == QLatin1Char('e')
543 && c[4] == QLatin1Char('t') && c[5] == QLatin1Char('e'))
544 return QScriptGrammar::T_DELETE;
545 else if (c[0] == QLatin1Char('r') && c[1] == QLatin1Char('e')
546 && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('u')
547 && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('n'))
548 return QScriptGrammar::T_RETURN;
549 else if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('w')
550 && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('t')
551 && c[4] == QLatin1Char('c') && c[5] == QLatin1Char('h'))
552 return QScriptGrammar::T_SWITCH;
553 else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('y')
554 && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('e')
555 && c[4] == QLatin1Char('o') && c[5] == QLatin1Char('f'))
556 return QScriptGrammar::T_TYPEOF;
557 else if (check_reserved) {
558 if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('x')
559 && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('o')
560 && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('t'))
561 return QScriptGrammar::T_RESERVED_WORD;
562 else if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('t')
563 && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('t')
564 && c[4] == QLatin1Char('i') && c[5] == QLatin1Char('c'))
565 return QScriptGrammar::T_RESERVED_WORD;
566 else if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('o')
567 && c[2] == QLatin1Char('u') && c[3] == QLatin1Char('b')
568 && c[4] == QLatin1Char('l') && c[5] == QLatin1Char('e'))
569 return QScriptGrammar::T_RESERVED_WORD;
570 else if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('m')
571 && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('o')
572 && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('t'))
573 return QScriptGrammar::T_RESERVED_WORD;
574 else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('u')
575 && c[2] == QLatin1Char('b') && c[3] == QLatin1Char('l')
576 && c[4] == QLatin1Char('i') && c[5] == QLatin1Char('c'))
577 return QScriptGrammar::T_RESERVED_WORD;
578 else if (c[0] == QLatin1Char('n') && c[1] == QLatin1Char('a')
579 && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('i')
580 && c[4] == QLatin1Char('v') && c[5] == QLatin1Char('e'))
581 return QScriptGrammar::T_RESERVED_WORD;
582 else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('h')
583 && c[2] == QLatin1Char('r') && c[3] == QLatin1Char('o')
584 && c[4] == QLatin1Char('w') && c[5] == QLatin1Char('s'))
585 return QScriptGrammar::T_RESERVED_WORD;
586 }
587 } break;
588
589 case 7: {
590 if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('e')
591 && c[2] == QLatin1Char('f') && c[3] == QLatin1Char('a')
592 && c[4] == QLatin1Char('u') && c[5] == QLatin1Char('l')
593 && c[6] == QLatin1Char('t'))
594 return QScriptGrammar::T_DEFAULT;
595 else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('i')
596 && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('a')
597 && c[4] == QLatin1Char('l') && c[5] == QLatin1Char('l')
598 && c[6] == QLatin1Char('y'))
599 return QScriptGrammar::T_FINALLY;
600 else if (check_reserved) {
601 if (c[0] == QLatin1Char('b') && c[1] == QLatin1Char('o')
602 && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('l')
603 && c[4] == QLatin1Char('e') && c[5] == QLatin1Char('a')
604 && c[6] == QLatin1Char('n'))
605 return QScriptGrammar::T_RESERVED_WORD;
606 else if (c[0] == QLatin1Char('e') && c[1] == QLatin1Char('x')
607 && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('e')
608 && c[4] == QLatin1Char('n') && c[5] == QLatin1Char('d')
609 && c[6] == QLatin1Char('s'))
610 return QScriptGrammar::T_RESERVED_WORD;
611 else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('a')
612 && c[2] == QLatin1Char('c') && c[3] == QLatin1Char('k')
613 && c[4] == QLatin1Char('a') && c[5] == QLatin1Char('g')
614 && c[6] == QLatin1Char('e'))
615 return QScriptGrammar::T_RESERVED_WORD;
616 else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('r')
617 && c[2] == QLatin1Char('i') && c[3] == QLatin1Char('v')
618 && c[4] == QLatin1Char('a') && c[5] == QLatin1Char('t')
619 && c[6] == QLatin1Char('e'))
620 return QScriptGrammar::T_RESERVED_WORD;
621 }
622 } break;
623
624 case 8: {
625 if (c[0] == QLatin1Char('c') && c[1] == QLatin1Char('o')
626 && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('t')
627 && c[4] == QLatin1Char('i') && c[5] == QLatin1Char('n')
628 && c[6] == QLatin1Char('u') && c[7] == QLatin1Char('e'))
629 return QScriptGrammar::T_CONTINUE;
630 else if (c[0] == QLatin1Char('f') && c[1] == QLatin1Char('u')
631 && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('c')
632 && c[4] == QLatin1Char('t') && c[5] == QLatin1Char('i')
633 && c[6] == QLatin1Char('o') && c[7] == QLatin1Char('n'))
634 return QScriptGrammar::T_FUNCTION;
635 else if (c[0] == QLatin1Char('d') && c[1] == QLatin1Char('e')
636 && c[2] == QLatin1Char('b') && c[3] == QLatin1Char('u')
637 && c[4] == QLatin1Char('g') && c[5] == QLatin1Char('g')
638 && c[6] == QLatin1Char('e') && c[7] == QLatin1Char('r'))
639 return QScriptGrammar::T_DEBUGGER;
640 else if (check_reserved) {
641 if (c[0] == QLatin1Char('a') && c[1] == QLatin1Char('b')
642 && c[2] == QLatin1Char('s') && c[3] == QLatin1Char('t')
643 && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('a')
644 && c[6] == QLatin1Char('c') && c[7] == QLatin1Char('t'))
645 return QScriptGrammar::T_RESERVED_WORD;
646 else if (c[0] == QLatin1Char('v') && c[1] == QLatin1Char('o')
647 && c[2] == QLatin1Char('l') && c[3] == QLatin1Char('a')
648 && c[4] == QLatin1Char('t') && c[5] == QLatin1Char('i')
649 && c[6] == QLatin1Char('l') && c[7] == QLatin1Char('e'))
650 return QScriptGrammar::T_RESERVED_WORD;
651 }
652 } break;
653
654 case 9: {
655 if (check_reserved) {
656 if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n')
657 && c[2] == QLatin1Char('t') && c[3] == QLatin1Char('e')
658 && c[4] == QLatin1Char('r') && c[5] == QLatin1Char('f')
659 && c[6] == QLatin1Char('a') && c[7] == QLatin1Char('c')
660 && c[8] == QLatin1Char('e'))
661 return QScriptGrammar::T_RESERVED_WORD;
662 else if (c[0] == QLatin1Char('t') && c[1] == QLatin1Char('r')
663 && c[2] == QLatin1Char('a') && c[3] == QLatin1Char('n')
664 && c[4] == QLatin1Char('s') && c[5] == QLatin1Char('i')
665 && c[6] == QLatin1Char('e') && c[7] == QLatin1Char('n')
666 && c[8] == QLatin1Char('t'))
667 return QScriptGrammar::T_RESERVED_WORD;
668 else if (c[0] == QLatin1Char('p') && c[1] == QLatin1Char('r')
669 && c[2] == QLatin1Char('o') && c[3] == QLatin1Char('t')
670 && c[4] == QLatin1Char('e') && c[5] == QLatin1Char('c')
671 && c[6] == QLatin1Char('t') && c[7] == QLatin1Char('e')
672 && c[8] == QLatin1Char('d'))
673 return QScriptGrammar::T_RESERVED_WORD;
674 }
675 } break;
676
677 case 10: {
678 if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('n')
679 && c[2] == QLatin1Char('s') && c[3] == QLatin1Char('t')
680 && c[4] == QLatin1Char('a') && c[5] == QLatin1Char('n')
681 && c[6] == QLatin1Char('c') && c[7] == QLatin1Char('e')
682 && c[8] == QLatin1Char('o') && c[9] == QLatin1Char('f'))
683 return QScriptGrammar::T_INSTANCEOF;
684 else if (check_reserved) {
685 if (c[0] == QLatin1Char('i') && c[1] == QLatin1Char('m')
686 && c[2] == QLatin1Char('p') && c[3] == QLatin1Char('l')
687 && c[4] == QLatin1Char('e') && c[5] == QLatin1Char('m')
688 && c[6] == QLatin1Char('e') && c[7] == QLatin1Char('n')
689 && c[8] == QLatin1Char('t') && c[9] == QLatin1Char('s'))
690 return QScriptGrammar::T_RESERVED_WORD;
691 }
692 } break;
693
694 case 12: {
695 if (check_reserved) {
696 if (c[0] == QLatin1Char('s') && c[1] == QLatin1Char('y')
697 && c[2] == QLatin1Char('n') && c[3] == QLatin1Char('c')
698 && c[4] == QLatin1Char('h') && c[5] == QLatin1Char('r')
699 && c[6] == QLatin1Char('o') && c[7] == QLatin1Char('n')
700 && c[8] == QLatin1Char('i') && c[9] == QLatin1Char('z')
701 && c[10] == QLatin1Char('e') && c[11] == QLatin1Char('d'))
702 return QScriptGrammar::T_RESERVED_WORD;
703 }
704 } break;
705
706 } // switch
707
708 return -1;
709}
710
711int QScript::Lexer::lex()
712{
713 int token = 0;
714 state = Start;
715 ushort stringType = 0; // either single or double quotes
716 pos8 = pos16 = 0;
717 done = false;
718 terminator = false;
719
720 // did we push a token on the stack previously ?
721 // (after an automatic semicolon insertion)
722 if (stackToken >= 0) {
723 setDone(Other);
724 token = stackToken;
725 stackToken = -1;
726 }
727
728 while (!done) {
729 switch (state) {
730 case Start:
731 if (isWhiteSpace()) {
732 // do nothing
733 } else if (current == '/' && next1 == '/') {
734 recordStartPos();
735 shift(1);
736 state = InSingleLineComment;
737 } else if (current == '/' && next1 == '*') {
738 recordStartPos();
739 shift(1);
740 state = InMultiLineComment;
741 } else if (current == 0) {
742 syncProhibitAutomaticSemicolon();
743 if (!terminator && !delimited && !prohibitAutomaticSemicolon) {
744 // automatic semicolon insertion if program incomplete
745 token = QScriptGrammar::T_SEMICOLON;
746 stackToken = 0;
747 setDone(Other);
748 } else {
749 setDone(Eof);
750 }
751 } else if (isLineTerminator()) {
752 shiftWindowsLineBreak();
753 yylineno++;
754 yycolumn = 0;
755 bol = true;
756 terminator = true;
757 syncProhibitAutomaticSemicolon();
758 if (restrKeyword) {
759 token = QScriptGrammar::T_SEMICOLON;
760 setDone(Other);
761 }
762 } else if (current == '"' || current == '\'') {
763 recordStartPos();
764 state = InString;
765 stringType = current;
766 } else if (isIdentLetter(current)) {
767 recordStartPos();
768 record16(current);
769 state = InIdentifier;
770 } else if (current == '0') {
771 recordStartPos();
772 record8(current);
773 state = InNum0;
774 } else if (isDecimalDigit(current)) {
775 recordStartPos();
776 record8(current);
777 state = InNum;
778 } else if (current == '.' && isDecimalDigit(next1)) {
779 recordStartPos();
780 record8(current);
781 state = InDecimal;
782 } else {
783 recordStartPos();
784 token = matchPunctuator(current, next1, next2, next3);
785 if (token != -1) {
786 if (terminator && !delimited && !prohibitAutomaticSemicolon
787 && (token == QScriptGrammar::T_PLUS_PLUS
788 || token == QScriptGrammar::T_MINUS_MINUS)) {
789 // automatic semicolon insertion
790 stackToken = token;
791 token = QScriptGrammar::T_SEMICOLON;
792 }
793 setDone(Other);
794 }
795 else {
796 setDone(Bad);
797 err = IllegalCharacter;
798 errmsg = QLatin1String("Illegal character");
799 }
800 }
801 break;
802 case InString:
803 if (current == stringType) {
804 shift(1);
805 setDone(String);
806 } else if (current == 0 || isLineTerminator()) {
807 setDone(Bad);
808 err = UnclosedStringLiteral;
809 errmsg = QLatin1String("Unclosed string at end of line");
810 } else if (current == '\\') {
811 state = InEscapeSequence;
812 } else {
813 record16(current);
814 }
815 break;
816 // Escape Sequences inside of strings
817 case InEscapeSequence:
818 if (isOctalDigit(current)) {
819 if (current >= '0' && current <= '3' &&
820 isOctalDigit(next1) && isOctalDigit(next2)) {
821 record16(convertOctal(current, next1, next2));
822 shift(2);
823 state = InString;
824 } else if (isOctalDigit(current) &&
825 isOctalDigit(next1)) {
826 record16(convertOctal('0', current, next1));
827 shift(1);
828 state = InString;
829 } else if (isOctalDigit(current)) {
830 record16(convertOctal('0', '0', current));
831 state = InString;
832 } else {
833 setDone(Bad);
834 err = IllegalEscapeSequence;
835 errmsg = QLatin1String("Illegal escape squence");
836 }
837 } else if (current == 'x')
838 state = InHexEscape;
839 else if (current == 'u')
840 state = InUnicodeEscape;
841 else {
842 record16(singleEscape(current));
843 state = InString;
844 }
845 break;
846 case InHexEscape:
847 if (isHexDigit(current) && isHexDigit(next1)) {
848 state = InString;
849 record16(QLatin1Char(convertHex(current, next1)));
850 shift(1);
851 } else if (current == stringType) {
852 record16(QLatin1Char('x'));
853 shift(1);
854 setDone(String);
855 } else {
856 record16(QLatin1Char('x'));
857 record16(current);
858 state = InString;
859 }
860 break;
861 case InUnicodeEscape:
862 if (isHexDigit(current) && isHexDigit(next1) &&
863 isHexDigit(next2) && isHexDigit(next3)) {
864 record16(convertUnicode(current, next1, next2, next3));
865 shift(3);
866 state = InString;
867 } else if (current == stringType) {
868 record16(QLatin1Char('u'));
869 shift(1);
870 setDone(String);
871 } else {
872 setDone(Bad);
873 err = IllegalUnicodeEscapeSequence;
874 errmsg = QLatin1String("Illegal unicode escape sequence");
875 }
876 break;
877 case InSingleLineComment:
878 if (isLineTerminator()) {
879 shiftWindowsLineBreak();
880 yylineno++;
881 yycolumn = 0;
882 terminator = true;
883 bol = true;
884 if (restrKeyword) {
885 token = QScriptGrammar::T_SEMICOLON;
886 setDone(Other);
887 } else
888 state = Start;
889 } else if (current == 0) {
890 setDone(Eof);
891 }
892 break;
893 case InMultiLineComment:
894 if (current == 0) {
895 setDone(Bad);
896 err = UnclosedComment;
897 errmsg = QLatin1String("Unclosed comment at end of file");
898 } else if (isLineTerminator()) {
899 shiftWindowsLineBreak();
900 yylineno++;
901 } else if (current == '*' && next1 == '/') {
902 state = Start;
903 shift(1);
904 }
905 break;
906 case InIdentifier:
907 if (isIdentLetter(current) || isDecimalDigit(current)) {
908 record16(current);
909 break;
910 }
911 setDone(Identifier);
912 break;
913 case InNum0:
914 if (current == 'x' || current == 'X') {
915 record8(current);
916 state = InHex;
917 } else if (current == '.') {
918 record8(current);
919 state = InDecimal;
920 } else if (current == 'e' || current == 'E') {
921 record8(current);
922 state = InExponentIndicator;
923 } else if (isOctalDigit(current)) {
924 record8(current);
925 state = InOctal;
926 } else if (isDecimalDigit(current)) {
927 record8(current);
928 state = InDecimal;
929 } else {
930 setDone(Number);
931 }
932 break;
933 case InHex:
934 if (isHexDigit(current))
935 record8(current);
936 else
937 setDone(Hex);
938 break;
939 case InOctal:
940 if (isOctalDigit(current)) {
941 record8(current);
942 } else if (isDecimalDigit(current)) {
943 record8(current);
944 state = InDecimal;
945 } else {
946 setDone(Octal);
947 }
948 break;
949 case InNum:
950 if (isDecimalDigit(current)) {
951 record8(current);
952 } else if (current == '.') {
953 record8(current);
954 state = InDecimal;
955 } else if (current == 'e' || current == 'E') {
956 record8(current);
957 state = InExponentIndicator;
958 } else {
959 setDone(Number);
960 }
961 break;
962 case InDecimal:
963 if (isDecimalDigit(current)) {
964 record8(current);
965 } else if (current == 'e' || current == 'E') {
966 record8(current);
967 state = InExponentIndicator;
968 } else {
969 setDone(Number);
970 }
971 break;
972 case InExponentIndicator:
973 if (current == '+' || current == '-') {
974 record8(current);
975 } else if (isDecimalDigit(current)) {
976 record8(current);
977 state = InExponent;
978 } else {
979 setDone(Bad);
980 err = IllegalExponentIndicator;
981 errmsg = QLatin1String("Illegal syntax for exponential number");
982 }
983 break;
984 case InExponent:
985 if (isDecimalDigit(current)) {
986 record8(current);
987 } else {
988 setDone(Number);
989 }
990 break;
991 default:
992 Q_ASSERT_X(0, "Lexer::lex", "Unhandled state in switch statement");
993 }
994
995 // move on to the next character
996 if (!done)
997 shift(1);
998 if (state != Start && state != InSingleLineComment)
999 bol = false;
1000 }
1001
1002 // no identifiers allowed directly after numeric literal, e.g. "3in" is bad
1003 if ((state == Number || state == Octal || state == Hex)
1004 && isIdentLetter(current)) {
1005 state = Bad;
1006 err = IllegalIdentifier;
1007 errmsg = QLatin1String("Identifier cannot start with numeric literal");
1008 }
1009
1010 // terminate string
1011 buffer8[pos8] = '\0';
1012
1013 double dval = 0;
1014 if (state == Number) {
1015 dval = qstrtod(buffer8, 0, 0);
1016 } else if (state == Hex) { // scan hex numbers
1017 dval = QScript::integerFromString(buffer8, pos8, 16);
1018 state = Number;
1019 } else if (state == Octal) { // scan octal number
1020 dval = QScript::integerFromString(buffer8, pos8, 8);
1021 state = Number;
1022 }
1023
1024 restrKeyword = false;
1025 delimited = false;
1026
1027 switch (parenthesesState) {
1028 case IgnoreParentheses:
1029 break;
1030 case CountParentheses:
1031 if (token == QScriptGrammar::T_RPAREN) {
1032 --parenthesesCount;
1033 if (parenthesesCount == 0)
1034 parenthesesState = BalancedParentheses;
1035 } else if (token == QScriptGrammar::T_LPAREN) {
1036 ++parenthesesCount;
1037 }
1038 break;
1039 case BalancedParentheses:
1040 parenthesesState = IgnoreParentheses;
1041 break;
1042 }
1043
1044 switch (state) {
1045 case Eof:
1046 return 0;
1047 case Other:
1048 if(token == QScriptGrammar::T_RBRACE || token == QScriptGrammar::T_SEMICOLON)
1049 delimited = true;
1050 return token;
1051 case Identifier:
1052 if ((token = findReservedWord(buffer16, pos16)) < 0) {
1053 /* TODO: close leak on parse error. same holds true for String */
1054 qsyylval = QString(buffer16, pos16);
1055 return QScriptGrammar::T_IDENTIFIER;
1056 }
1057 if (token == QScriptGrammar::T_CONTINUE || token == QScriptGrammar::T_BREAK
1058 || token == QScriptGrammar::T_RETURN || token == QScriptGrammar::T_THROW) {
1059 restrKeyword = true;
1060 } else if (token == QScriptGrammar::T_IF || token == QScriptGrammar::T_FOR
1061 || token == QScriptGrammar::T_WHILE || token == QScriptGrammar::T_WITH) {
1062 parenthesesState = CountParentheses;
1063 parenthesesCount = 0;
1064 } else if (token == QScriptGrammar::T_DO) {
1065 parenthesesState = BalancedParentheses;
1066 }
1067 return token;
1068 case String:
1069 qsyylval = QString(buffer16, pos16);
1070 return QScriptGrammar::T_STRING_LITERAL;
1071 case Number:
1072 qsyylval = dval;
1073 return QScriptGrammar::T_NUMERIC_LITERAL;
1074 case Bad:
1075 return -1;
1076 default:
1077 Q_ASSERT(!"unhandled numeration value in switch");
1078 return -1;
1079 }
1080}
1081
1082bool QScript::Lexer::isWhiteSpace() const
1083{
1084 return (current == ' ' || current == '\t' ||
1085 current == 0x0b || current == 0x0c);
1086}
1087
1088bool QScript::Lexer::isLineTerminator() const
1089{
1090 return (current == '\n' || current == '\r');
1091}
1092
1093bool QScript::Lexer::isIdentLetter(ushort c)
1094{
1095 /* TODO: allow other legitimate unicode chars */
1096 return ((c >= 'a' && c <= 'z')
1097 || (c >= 'A' && c <= 'Z')
1098 || c == '$'
1099 || c == '_');
1100}
1101
1102bool QScript::Lexer::isDecimalDigit(ushort c)
1103{
1104 return (c >= '0' && c <= '9');
1105}
1106
1107bool QScript::Lexer::isHexDigit(ushort c) const
1108{
1109 return ((c >= '0' && c <= '9')
1110 || (c >= 'a' && c <= 'f')
1111 || (c >= 'A' && c <= 'F'));
1112}
1113
1114bool QScript::Lexer::isOctalDigit(ushort c) const
1115{
1116 return (c >= '0' && c <= '7');
1117}
1118
1119int QScript::Lexer::matchPunctuator(ushort c1, ushort c2,
1120 ushort c3, ushort c4)
1121{
1122 if (c1 == '>' && c2 == '>' && c3 == '>' && c4 == '=') {
1123 shift(4);
1124 return QScriptGrammar::T_GT_GT_GT_EQ;
1125 } else if (c1 == '=' && c2 == '=' && c3 == '=') {
1126 shift(3);
1127 return QScriptGrammar::T_EQ_EQ_EQ;
1128 } else if (c1 == '!' && c2 == '=' && c3 == '=') {
1129 shift(3);
1130 return QScriptGrammar::T_NOT_EQ_EQ;
1131 } else if (c1 == '>' && c2 == '>' && c3 == '>') {
1132 shift(3);
1133 return QScriptGrammar::T_GT_GT_GT;
1134 } else if (c1 == '<' && c2 == '<' && c3 == '=') {
1135 shift(3);
1136 return QScriptGrammar::T_LT_LT_EQ;
1137 } else if (c1 == '>' && c2 == '>' && c3 == '=') {
1138 shift(3);
1139 return QScriptGrammar::T_GT_GT_EQ;
1140 } else if (c1 == '<' && c2 == '=') {
1141 shift(2);
1142 return QScriptGrammar::T_LE;
1143 } else if (c1 == '>' && c2 == '=') {
1144 shift(2);
1145 return QScriptGrammar::T_GE;
1146 } else if (c1 == '!' && c2 == '=') {
1147 shift(2);
1148 return QScriptGrammar::T_NOT_EQ;
1149 } else if (c1 == '+' && c2 == '+') {
1150 shift(2);
1151 return QScriptGrammar::T_PLUS_PLUS;
1152 } else if (c1 == '-' && c2 == '-') {
1153 shift(2);
1154 return QScriptGrammar::T_MINUS_MINUS;
1155 } else if (c1 == '=' && c2 == '=') {
1156 shift(2);
1157 return QScriptGrammar::T_EQ_EQ;
1158 } else if (c1 == '+' && c2 == '=') {
1159 shift(2);
1160 return QScriptGrammar::T_PLUS_EQ;
1161 } else if (c1 == '-' && c2 == '=') {
1162 shift(2);
1163 return QScriptGrammar::T_MINUS_EQ;
1164 } else if (c1 == '*' && c2 == '=') {
1165 shift(2);
1166 return QScriptGrammar::T_STAR_EQ;
1167 } else if (c1 == '/' && c2 == '=') {
1168 shift(2);
1169 return QScriptGrammar::T_DIVIDE_EQ;
1170 } else if (c1 == '&' && c2 == '=') {
1171 shift(2);
1172 return QScriptGrammar::T_AND_EQ;
1173 } else if (c1 == '^' && c2 == '=') {
1174 shift(2);
1175 return QScriptGrammar::T_XOR_EQ;
1176 } else if (c1 == '%' && c2 == '=') {
1177 shift(2);
1178 return QScriptGrammar::T_REMAINDER_EQ;
1179 } else if (c1 == '|' && c2 == '=') {
1180 shift(2);
1181 return QScriptGrammar::T_OR_EQ;
1182 } else if (c1 == '<' && c2 == '<') {
1183 shift(2);
1184 return QScriptGrammar::T_LT_LT;
1185 } else if (c1 == '>' && c2 == '>') {
1186 shift(2);
1187 return QScriptGrammar::T_GT_GT;
1188 } else if (c1 == '&' && c2 == '&') {
1189 shift(2);
1190 return QScriptGrammar::T_AND_AND;
1191 } else if (c1 == '|' && c2 == '|') {
1192 shift(2);
1193 return QScriptGrammar::T_OR_OR;
1194 }
1195
1196 switch(c1) {
1197 case '=': shift(1); return QScriptGrammar::T_EQ;
1198 case '>': shift(1); return QScriptGrammar::T_GT;
1199 case '<': shift(1); return QScriptGrammar::T_LT;
1200 case ',': shift(1); return QScriptGrammar::T_COMMA;
1201 case '!': shift(1); return QScriptGrammar::T_NOT;
1202 case '~': shift(1); return QScriptGrammar::T_TILDE;
1203 case '?': shift(1); return QScriptGrammar::T_QUESTION;
1204 case ':': shift(1); return QScriptGrammar::T_COLON;
1205 case '.': shift(1); return QScriptGrammar::T_DOT;
1206 case '+': shift(1); return QScriptGrammar::T_PLUS;
1207 case '-': shift(1); return QScriptGrammar::T_MINUS;
1208 case '*': shift(1); return QScriptGrammar::T_STAR;
1209 case '/': shift(1); return QScriptGrammar::T_DIVIDE_;
1210 case '&': shift(1); return QScriptGrammar::T_AND;
1211 case '|': shift(1); return QScriptGrammar::T_OR;
1212 case '^': shift(1); return QScriptGrammar::T_XOR;
1213 case '%': shift(1); return QScriptGrammar::T_REMAINDER;
1214 case '(': shift(1); return QScriptGrammar::T_LPAREN;
1215 case ')': shift(1); return QScriptGrammar::T_RPAREN;
1216 case '{': shift(1); return QScriptGrammar::T_LBRACE;
1217 case '}': shift(1); return QScriptGrammar::T_RBRACE;
1218 case '[': shift(1); return QScriptGrammar::T_LBRACKET;
1219 case ']': shift(1); return QScriptGrammar::T_RBRACKET;
1220 case ';': shift(1); return QScriptGrammar::T_SEMICOLON;
1221
1222 default: return -1;
1223 }
1224}
1225
1226ushort QScript::Lexer::singleEscape(ushort c) const
1227{
1228 switch(c) {
1229 case 'b':
1230 return 0x08;
1231 case 't':
1232 return 0x09;
1233 case 'n':
1234 return 0x0A;
1235 case 'v':
1236 return 0x0B;
1237 case 'f':
1238 return 0x0C;
1239 case 'r':
1240 return 0x0D;
1241 case '"':
1242 return 0x22;
1243 case '\'':
1244 return 0x27;
1245 case '\\':
1246 return 0x5C;
1247 default:
1248 return c;
1249 }
1250}
1251
1252ushort QScript::Lexer::convertOctal(ushort c1, ushort c2,
1253 ushort c3) const
1254{
1255 return ((c1 - '0') * 64 + (c2 - '0') * 8 + c3 - '0');
1256}
1257
1258unsigned char QScript::Lexer::convertHex(ushort c)
1259{
1260 if (c >= '0' && c <= '9')
1261 return (c - '0');
1262 else if (c >= 'a' && c <= 'f')
1263 return (c - 'a' + 10);
1264 else
1265 return (c - 'A' + 10);
1266}
1267
1268unsigned char QScript::Lexer::convertHex(ushort c1, ushort c2)
1269{
1270 return ((convertHex(c1) << 4) + convertHex(c2));
1271}
1272
1273QChar QScript::Lexer::convertUnicode(ushort c1, ushort c2,
1274 ushort c3, ushort c4)
1275{
1276 return QChar((convertHex(c3) << 4) + convertHex(c4),
1277 (convertHex(c1) << 4) + convertHex(c2));
1278}
1279
1280void QScript::Lexer::record8(ushort c)
1281{
1282 Q_ASSERT(c <= 0xff);
1283
1284 // enlarge buffer if full
1285 if (pos8 >= size8 - 1) {
1286 char *tmp = new char[2 * size8];
1287 memcpy(tmp, buffer8, size8 * sizeof(char));
1288 delete [] buffer8;
1289 buffer8 = tmp;
1290 size8 *= 2;
1291 }
1292
1293 buffer8[pos8++] = (char) c;
1294}
1295
1296void QScript::Lexer::record16(QChar c)
1297{
1298 // enlarge buffer if full
1299 if (pos16 >= size16 - 1) {
1300 QChar *tmp = new QChar[2 * size16];
1301 memcpy(tmp, buffer16, size16 * sizeof(QChar));
1302 delete [] buffer16;
1303 buffer16 = tmp;
1304 size16 *= 2;
1305 }
1306
1307 buffer16[pos16++] = c;
1308}
1309
1310void QScript::Lexer::recordStartPos()
1311{
1312 startlineno = yylineno;
1313 startcolumn = yycolumn;
1314}
1315
1316bool QScript::Lexer::scanRegExp(RegExpBodyPrefix prefix)
1317{
1318 pos16 = 0;
1319 bool lastWasEscape = false;
1320
1321 if (prefix == EqualPrefix)
1322 record16(QLatin1Char('='));
1323
1324 while (1) {
1325 if (isLineTerminator() || current == 0) {
1326 errmsg = QLatin1String("Unterminated regular expression literal");
1327 return false;
1328 }
1329 else if (current != '/' || lastWasEscape == true)
1330 {
1331 record16(current);
1332 lastWasEscape = !lastWasEscape && (current == '\\');
1333 }
1334 else {
1335 pattern = QString(buffer16, pos16);
1336 pos16 = 0;
1337 shift(1);
1338 break;
1339 }
1340 shift(1);
1341 }
1342
1343 flags = 0;
1344 while (isIdentLetter(current)) {
1345 record16(current);
1346 shift(1);
1347 }
1348
1349 return true;
1350}
1351
1352void QScript::Lexer::syncProhibitAutomaticSemicolon()
1353{
1354 if (parenthesesState == BalancedParentheses) {
1355 // we have seen something like "if (foo)", which means we should
1356 // never insert an automatic semicolon at this point, since it would
1357 // then be expanded into an empty statement (ECMA-262 7.9.1)
1358 prohibitAutomaticSemicolon = true;
1359 parenthesesState = IgnoreParentheses;
1360 } else {
1361 prohibitAutomaticSemicolon = false;
1362 }
1363}
1364
1365
1366class Translator;
1367
1368class QScriptParser: protected $table
1369{
1370public:
1371 QVariant val;
1372
1373 struct Location {
1374 int startLine;
1375 int startColumn;
1376 int endLine;
1377 int endColumn;
1378 };
1379
1380public:
1381 QScriptParser();
1382 ~QScriptParser();
1383
1384 bool parse(QScript::Lexer *lexer,
1385 const QString &fileName,
1386 Translator *translator);
1387
1388 inline QString errorMessage() const
1389 { return error_message; }
1390 inline int errorLineNumber() const
1391 { return error_lineno; }
1392 inline int errorColumnNumber() const
1393 { return error_column; }
1394
1395protected:
1396 inline void reallocateStack();
1397
1398 inline QVariant &sym(int index)
1399 { return sym_stack [tos + index - 1]; }
1400
1401 inline Location &loc(int index)
1402 { return location_stack [tos + index - 2]; }
1403
1404protected:
1405 int tos;
1406 int stack_size;
1407 QVector<QVariant> sym_stack;
1408 int *state_stack;
1409 Location *location_stack;
1410 QString error_message;
1411 int error_lineno;
1412 int error_column;
1413};
1414
1415inline void QScriptParser::reallocateStack()
1416{
1417 if (! stack_size)
1418 stack_size = 128;
1419 else
1420 stack_size <<= 1;
1421
1422 sym_stack.resize(stack_size);
1423 state_stack = reinterpret_cast<int*> (qRealloc(state_stack, stack_size * sizeof(int)));
1424 location_stack = reinterpret_cast<Location*> (qRealloc(location_stack, stack_size * sizeof(Location)));
1425}
1426
1427inline static bool automatic(QScript::Lexer *lexer, int token)
1428{
1429 return (token == $table::T_RBRACE)
1430 || (token == 0)
1431 || lexer->prevTerminator();
1432}
1433
1434QScriptParser::QScriptParser():
1435 tos(0),
1436 stack_size(0),
1437 sym_stack(0),
1438 state_stack(0),
1439 location_stack(0)
1440{
1441}
1442
1443QScriptParser::~QScriptParser()
1444{
1445 if (stack_size) {
1446 qFree(state_stack);
1447 qFree(location_stack);
1448 }
1449}
1450
1451static inline QScriptParser::Location location(QScript::Lexer *lexer)
1452{
1453 QScriptParser::Location loc;
1454 loc.startLine = lexer->startLineNo();
1455 loc.startColumn = lexer->startColumnNo();
1456 loc.endLine = lexer->endLineNo();
1457 loc.endColumn = lexer->endColumnNo();
1458 return loc;
1459}
1460
1461bool QScriptParser::parse(QScript::Lexer *lexer,
1462 const QString &fileName,
1463 Translator *translator)
1464{
1465 const int INITIAL_STATE = 0;
1466
1467 int yytoken = -1;
1468 int saved_yytoken = -1;
1469 int identLineNo = -1;
1470
1471 reallocateStack();
1472
1473 tos = 0;
1474 state_stack[++tos] = INITIAL_STATE;
1475
1476 while (true)
1477 {
1478 const int state = state_stack [tos];
1479 if (yytoken == -1 && - TERMINAL_COUNT != action_index [state])
1480 {
1481 if (saved_yytoken == -1)
1482 {
1483 yytoken = lexer->lex();
1484 location_stack [tos] = location(lexer);
1485 }
1486 else
1487 {
1488 yytoken = saved_yytoken;
1489 saved_yytoken = -1;
1490 }
1491 }
1492
1493 int act = t_action (state, yytoken);
1494
1495 if (act == ACCEPT_STATE)
1496 return true;
1497
1498 else if (act > 0)
1499 {
1500 if (++tos == stack_size)
1501 reallocateStack();
1502
1503 sym_stack [tos] = lexer->val ();
1504 state_stack [tos] = act;
1505 location_stack [tos] = location(lexer);
1506 yytoken = -1;
1507 }
1508
1509 else if (act < 0)
1510 {
1511 int r = - act - 1;
1512
1513 tos -= rhs [r];
1514 act = state_stack [tos++];
1515
1516 switch (r) {
1517./
1518
1519PrimaryExpression: T_THIS ;
1520
1521PrimaryExpression: T_IDENTIFIER ;
1522/.
1523case $rule_number: {
1524 sym(1) = sym(1).toByteArray();
1525 identLineNo = lexer->startLineNo();
1526} break;
1527./
1528
1529PrimaryExpression: T_NULL ;
1530PrimaryExpression: T_TRUE ;
1531PrimaryExpression: T_FALSE ;
1532PrimaryExpression: T_NUMERIC_LITERAL ;
1533PrimaryExpression: T_STRING_LITERAL ;
1534
1535PrimaryExpression: T_DIVIDE_ ;
1536/:
1537#define Q_SCRIPT_REGEXPLITERAL_RULE1 $rule_number
1538:/
1539/.
1540case $rule_number: {
1541 bool rx = lexer->scanRegExp(QScript::Lexer::NoPrefix);
1542 if (!rx) {
1543 error_message = lexer->errorMessage();
1544 error_lineno = lexer->startLineNo();
1545 error_column = lexer->startColumnNo();
1546 return false;
1547 }
1548} break;
1549./
1550
1551PrimaryExpression: T_DIVIDE_EQ ;
1552/:
1553#define Q_SCRIPT_REGEXPLITERAL_RULE2 $rule_number
1554:/
1555/.
1556case $rule_number: {
1557 bool rx = lexer->scanRegExp(QScript::Lexer::EqualPrefix);
1558 if (!rx) {
1559 error_message = lexer->errorMessage();
1560 error_lineno = lexer->startLineNo();
1561 error_column = lexer->startColumnNo();
1562 return false;
1563 }
1564} break;
1565./
1566
1567PrimaryExpression: T_LBRACKET ElisionOpt T_RBRACKET ;
1568PrimaryExpression: T_LBRACKET ElementList T_RBRACKET ;
1569PrimaryExpression: T_LBRACKET ElementList T_COMMA ElisionOpt T_RBRACKET ;
1570PrimaryExpression: T_LBRACE PropertyNameAndValueListOpt T_RBRACE ;
1571PrimaryExpression: T_LPAREN Expression T_RPAREN ;
1572ElementList: ElisionOpt AssignmentExpression ;
1573ElementList: ElementList T_COMMA ElisionOpt AssignmentExpression ;
1574Elision: T_COMMA ;
1575Elision: Elision T_COMMA ;
1576ElisionOpt: ;
1577ElisionOpt: Elision ;
1578PropertyNameAndValueList: PropertyName T_COLON AssignmentExpression ;
1579PropertyNameAndValueList: PropertyNameAndValueList T_COMMA PropertyName T_COLON AssignmentExpression ;
1580PropertyName: T_IDENTIFIER ;
1581PropertyName: T_STRING_LITERAL ;
1582PropertyName: T_NUMERIC_LITERAL ;
1583PropertyName: ReservedIdentifier ;
1584ReservedIdentifier: T_BREAK ;
1585ReservedIdentifier: T_CASE ;
1586ReservedIdentifier: T_CATCH ;
1587ReservedIdentifier: T_CONST ;
1588ReservedIdentifier: T_CONTINUE ;
1589ReservedIdentifier: T_DEBUGGER ;
1590ReservedIdentifier: T_DEFAULT ;
1591ReservedIdentifier: T_DELETE ;
1592ReservedIdentifier: T_DO ;
1593ReservedIdentifier: T_ELSE ;
1594ReservedIdentifier: T_FALSE ;
1595ReservedIdentifier: T_FINALLY ;
1596ReservedIdentifier: T_FOR ;
1597ReservedIdentifier: T_FUNCTION ;
1598ReservedIdentifier: T_IF ;
1599ReservedIdentifier: T_IN ;
1600ReservedIdentifier: T_INSTANCEOF ;
1601ReservedIdentifier: T_NEW ;
1602ReservedIdentifier: T_NULL ;
1603ReservedIdentifier: T_RESERVED_WORD ;
1604ReservedIdentifier: T_RETURN ;
1605ReservedIdentifier: T_SWITCH ;
1606ReservedIdentifier: T_THIS ;
1607ReservedIdentifier: T_THROW ;
1608ReservedIdentifier: T_TRUE ;
1609ReservedIdentifier: T_TRY ;
1610ReservedIdentifier: T_TYPEOF ;
1611ReservedIdentifier: T_VAR ;
1612ReservedIdentifier: T_VOID ;
1613ReservedIdentifier: T_WHILE ;
1614ReservedIdentifier: T_WITH ;
1615PropertyIdentifier: T_IDENTIFIER ;
1616PropertyIdentifier: ReservedIdentifier ;
1617
1618MemberExpression: PrimaryExpression ;
1619MemberExpression: FunctionExpression ;
1620MemberExpression: MemberExpression T_LBRACKET Expression T_RBRACKET ;
1621MemberExpression: MemberExpression T_DOT PropertyIdentifier ;
1622MemberExpression: T_NEW MemberExpression Arguments ;
1623NewExpression: MemberExpression ;
1624NewExpression: T_NEW NewExpression ;
1625
1626CallExpression: MemberExpression Arguments ;
1627/.
1628case $rule_number: {
1629 QString name = sym(1).toString();
1630 if ((name == QLatin1String("qsTranslate")) || (name == QLatin1String("QT_TRANSLATE_NOOP"))) {
1631 QVariantList args = sym(2).toList();
1632 if (args.size() < 2) {
1633 qWarning("%s:%d: %s() requires at least two arguments",
1634 qPrintable(fileName), identLineNo, qPrintable(name));
1635 } else {
1636 if ((args.at(0).type() != QVariant::String)
1637 || (args.at(1).type() != QVariant::String)) {
1638 qWarning("%s:%d: %s(): both arguments must be literal strings",
1639 qPrintable(fileName), identLineNo, qPrintable(name));
1640 } else {
1641 QString context = args.at(0).toString();
1642 QString text = args.at(1).toString();
1643 QString comment = args.value(2).toString();
1644 QString extracomment;
1645 bool plural = (args.size() > 4);
1646 recordMessage(translator, context, text, comment, extracomment,
1647 plural, fileName, identLineNo);
1648 }
1649 }
1650 } else if ((name == QLatin1String("qsTr")) || (name == QLatin1String("QT_TR_NOOP"))) {
1651 QVariantList args = sym(2).toList();
1652 if (args.size() < 1) {
1653 qWarning("%s:%d: %s() requires at least one argument",
1654 qPrintable(fileName), identLineNo, qPrintable(name));
1655 } else {
1656 if (args.at(0).type() != QVariant::String) {
1657 qWarning("%s:%d: %s(): text to translate must be a literal string",
1658 qPrintable(fileName), identLineNo, qPrintable(name));
1659 } else {
1660 QString context = QFileInfo(fileName).baseName();
1661 QString text = args.at(0).toString();
1662 QString comment = args.value(1).toString();
1663 QString extracomment;
1664 bool plural = (args.size() > 2);
1665 recordMessage(translator, context, text, comment, extracomment,
1666 plural, fileName, identLineNo);
1667 }
1668 }
1669 }
1670} break;
1671./
1672
1673CallExpression: CallExpression Arguments ;
1674CallExpression: CallExpression T_LBRACKET Expression T_RBRACKET ;
1675CallExpression: CallExpression T_DOT PropertyIdentifier ;
1676
1677Arguments: T_LPAREN T_RPAREN ;
1678/.
1679case $rule_number: {
1680 sym(1) = QVariantList();
1681} break;
1682./
1683
1684Arguments: T_LPAREN ArgumentList T_RPAREN ;
1685/.
1686case $rule_number: {
1687 sym(1) = sym(2);
1688} break;
1689./
1690
1691ArgumentList: AssignmentExpression ;
1692/.
1693case $rule_number: {
1694 sym(1) = QVariantList() << sym(1);
1695} break;
1696./
1697
1698ArgumentList: ArgumentList T_COMMA AssignmentExpression ;
1699/.
1700case $rule_number: {
1701 sym(1) = sym(1).toList() << sym(3);
1702} break;
1703./
1704
1705LeftHandSideExpression: NewExpression ;
1706LeftHandSideExpression: CallExpression ;
1707PostfixExpression: LeftHandSideExpression ;
1708PostfixExpression: LeftHandSideExpression T_PLUS_PLUS ;
1709PostfixExpression: LeftHandSideExpression T_MINUS_MINUS ;
1710UnaryExpression: PostfixExpression ;
1711UnaryExpression: T_DELETE UnaryExpression ;
1712UnaryExpression: T_VOID UnaryExpression ;
1713UnaryExpression: T_TYPEOF UnaryExpression ;
1714UnaryExpression: T_PLUS_PLUS UnaryExpression ;
1715UnaryExpression: T_MINUS_MINUS UnaryExpression ;
1716UnaryExpression: T_PLUS UnaryExpression ;
1717UnaryExpression: T_MINUS UnaryExpression ;
1718UnaryExpression: T_TILDE UnaryExpression ;
1719UnaryExpression: T_NOT UnaryExpression ;
1720MultiplicativeExpression: UnaryExpression ;
1721MultiplicativeExpression: MultiplicativeExpression T_STAR UnaryExpression ;
1722MultiplicativeExpression: MultiplicativeExpression T_DIVIDE_ UnaryExpression ;
1723MultiplicativeExpression: MultiplicativeExpression T_REMAINDER UnaryExpression ;
1724AdditiveExpression: MultiplicativeExpression ;
1725
1726AdditiveExpression: AdditiveExpression T_PLUS MultiplicativeExpression ;
1727/.
1728case $rule_number: {
1729 if ((sym(1).type() == QVariant::String) || (sym(3).type() == QVariant::String))
1730 sym(1) = sym(1).toString() + sym(3).toString();
1731 else
1732 sym(1) = QVariant();
1733} break;
1734./
1735
1736AdditiveExpression: AdditiveExpression T_MINUS MultiplicativeExpression ;
1737ShiftExpression: AdditiveExpression ;
1738ShiftExpression: ShiftExpression T_LT_LT AdditiveExpression ;
1739ShiftExpression: ShiftExpression T_GT_GT AdditiveExpression ;
1740ShiftExpression: ShiftExpression T_GT_GT_GT AdditiveExpression ;
1741RelationalExpression: ShiftExpression ;
1742RelationalExpression: RelationalExpression T_LT ShiftExpression ;
1743RelationalExpression: RelationalExpression T_GT ShiftExpression ;
1744RelationalExpression: RelationalExpression T_LE ShiftExpression ;
1745RelationalExpression: RelationalExpression T_GE ShiftExpression ;
1746RelationalExpression: RelationalExpression T_INSTANCEOF ShiftExpression ;
1747RelationalExpression: RelationalExpression T_IN ShiftExpression ;
1748RelationalExpressionNotIn: ShiftExpression ;
1749RelationalExpressionNotIn: RelationalExpressionNotIn T_LT ShiftExpression ;
1750RelationalExpressionNotIn: RelationalExpressionNotIn T_GT ShiftExpression ;
1751RelationalExpressionNotIn: RelationalExpressionNotIn T_LE ShiftExpression ;
1752RelationalExpressionNotIn: RelationalExpressionNotIn T_GE ShiftExpression ;
1753RelationalExpressionNotIn: RelationalExpressionNotIn T_INSTANCEOF ShiftExpression ;
1754EqualityExpression: RelationalExpression ;
1755EqualityExpression: EqualityExpression T_EQ_EQ RelationalExpression ;
1756EqualityExpression: EqualityExpression T_NOT_EQ RelationalExpression ;
1757EqualityExpression: EqualityExpression T_EQ_EQ_EQ RelationalExpression ;
1758EqualityExpression: EqualityExpression T_NOT_EQ_EQ RelationalExpression ;
1759EqualityExpressionNotIn: RelationalExpressionNotIn ;
1760EqualityExpressionNotIn: EqualityExpressionNotIn T_EQ_EQ RelationalExpressionNotIn ;
1761EqualityExpressionNotIn: EqualityExpressionNotIn T_NOT_EQ RelationalExpressionNotIn;
1762EqualityExpressionNotIn: EqualityExpressionNotIn T_EQ_EQ_EQ RelationalExpressionNotIn ;
1763EqualityExpressionNotIn: EqualityExpressionNotIn T_NOT_EQ_EQ RelationalExpressionNotIn ;
1764BitwiseANDExpression: EqualityExpression ;
1765BitwiseANDExpression: BitwiseANDExpression T_AND EqualityExpression ;
1766BitwiseANDExpressionNotIn: EqualityExpressionNotIn ;
1767BitwiseANDExpressionNotIn: BitwiseANDExpressionNotIn T_AND EqualityExpressionNotIn ;
1768BitwiseXORExpression: BitwiseANDExpression ;
1769BitwiseXORExpression: BitwiseXORExpression T_XOR BitwiseANDExpression ;
1770BitwiseXORExpressionNotIn: BitwiseANDExpressionNotIn ;
1771BitwiseXORExpressionNotIn: BitwiseXORExpressionNotIn T_XOR BitwiseANDExpressionNotIn ;
1772BitwiseORExpression: BitwiseXORExpression ;
1773BitwiseORExpression: BitwiseORExpression T_OR BitwiseXORExpression ;
1774BitwiseORExpressionNotIn: BitwiseXORExpressionNotIn ;
1775BitwiseORExpressionNotIn: BitwiseORExpressionNotIn T_OR BitwiseXORExpressionNotIn ;
1776LogicalANDExpression: BitwiseORExpression ;
1777LogicalANDExpression: LogicalANDExpression T_AND_AND BitwiseORExpression ;
1778LogicalANDExpressionNotIn: BitwiseORExpressionNotIn ;
1779LogicalANDExpressionNotIn: LogicalANDExpressionNotIn T_AND_AND BitwiseORExpressionNotIn ;
1780LogicalORExpression: LogicalANDExpression ;
1781LogicalORExpression: LogicalORExpression T_OR_OR LogicalANDExpression ;
1782LogicalORExpressionNotIn: LogicalANDExpressionNotIn ;
1783LogicalORExpressionNotIn: LogicalORExpressionNotIn T_OR_OR LogicalANDExpressionNotIn ;
1784ConditionalExpression: LogicalORExpression ;
1785ConditionalExpression: LogicalORExpression T_QUESTION AssignmentExpression T_COLON AssignmentExpression ;
1786ConditionalExpressionNotIn: LogicalORExpressionNotIn ;
1787ConditionalExpressionNotIn: LogicalORExpressionNotIn T_QUESTION AssignmentExpressionNotIn T_COLON AssignmentExpressionNotIn ;
1788AssignmentExpression: ConditionalExpression ;
1789AssignmentExpression: LeftHandSideExpression AssignmentOperator AssignmentExpression ;
1790AssignmentExpressionNotIn: ConditionalExpressionNotIn ;
1791AssignmentExpressionNotIn: LeftHandSideExpression AssignmentOperator AssignmentExpressionNotIn ;
1792AssignmentOperator: T_EQ ;
1793AssignmentOperator: T_STAR_EQ ;
1794AssignmentOperator: T_DIVIDE_EQ ;
1795AssignmentOperator: T_REMAINDER_EQ ;
1796AssignmentOperator: T_PLUS_EQ ;
1797AssignmentOperator: T_MINUS_EQ ;
1798AssignmentOperator: T_LT_LT_EQ ;
1799AssignmentOperator: T_GT_GT_EQ ;
1800AssignmentOperator: T_GT_GT_GT_EQ ;
1801AssignmentOperator: T_AND_EQ ;
1802AssignmentOperator: T_XOR_EQ ;
1803AssignmentOperator: T_OR_EQ ;
1804Expression: AssignmentExpression ;
1805Expression: Expression T_COMMA AssignmentExpression ;
1806ExpressionOpt: ;
1807ExpressionOpt: Expression ;
1808ExpressionNotIn: AssignmentExpressionNotIn ;
1809ExpressionNotIn: ExpressionNotIn T_COMMA AssignmentExpressionNotIn ;
1810ExpressionNotInOpt: ;
1811ExpressionNotInOpt: ExpressionNotIn ;
1812
1813Statement: Block ;
1814Statement: VariableStatement ;
1815Statement: EmptyStatement ;
1816Statement: ExpressionStatement ;
1817Statement: IfStatement ;
1818Statement: IterationStatement ;
1819Statement: ContinueStatement ;
1820Statement: BreakStatement ;
1821Statement: ReturnStatement ;
1822Statement: WithStatement ;
1823Statement: LabelledStatement ;
1824Statement: SwitchStatement ;
1825Statement: ThrowStatement ;
1826Statement: TryStatement ;
1827Statement: DebuggerStatement ;
1828
1829Block: T_LBRACE StatementListOpt T_RBRACE ;
1830StatementList: Statement ;
1831StatementList: StatementList Statement ;
1832StatementListOpt: ;
1833StatementListOpt: StatementList ;
1834VariableStatement: VariableDeclarationKind VariableDeclarationList T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
1835VariableStatement: VariableDeclarationKind VariableDeclarationList T_SEMICOLON ;
1836VariableDeclarationKind: T_CONST ;
1837VariableDeclarationKind: T_VAR ;
1838VariableDeclarationList: VariableDeclaration ;
1839VariableDeclarationList: VariableDeclarationList T_COMMA VariableDeclaration ;
1840VariableDeclarationListNotIn: VariableDeclarationNotIn ;
1841VariableDeclarationListNotIn: VariableDeclarationListNotIn T_COMMA VariableDeclarationNotIn ;
1842VariableDeclaration: T_IDENTIFIER InitialiserOpt ;
1843VariableDeclarationNotIn: T_IDENTIFIER InitialiserNotInOpt ;
1844Initialiser: T_EQ AssignmentExpression ;
1845InitialiserOpt: ;
1846InitialiserOpt: Initialiser ;
1847InitialiserNotIn: T_EQ AssignmentExpressionNotIn ;
1848InitialiserNotInOpt: ;
1849InitialiserNotInOpt: InitialiserNotIn ;
1850EmptyStatement: T_SEMICOLON ;
1851ExpressionStatement: Expression T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
1852ExpressionStatement: Expression T_SEMICOLON ;
1853IfStatement: T_IF T_LPAREN Expression T_RPAREN Statement T_ELSE Statement ;
1854IfStatement: T_IF T_LPAREN Expression T_RPAREN Statement ;
1855IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression T_RPAREN T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
1856IterationStatement: T_DO Statement T_WHILE T_LPAREN Expression T_RPAREN T_SEMICOLON ;
1857IterationStatement: T_WHILE T_LPAREN Expression T_RPAREN Statement ;
1858IterationStatement: T_FOR T_LPAREN ExpressionNotInOpt T_SEMICOLON ExpressionOpt T_SEMICOLON ExpressionOpt T_RPAREN Statement ;
1859IterationStatement: T_FOR T_LPAREN T_VAR VariableDeclarationListNotIn T_SEMICOLON ExpressionOpt T_SEMICOLON ExpressionOpt T_RPAREN Statement ;
1860IterationStatement: T_FOR T_LPAREN LeftHandSideExpression T_IN Expression T_RPAREN Statement ;
1861IterationStatement: T_FOR T_LPAREN T_VAR VariableDeclarationNotIn T_IN Expression T_RPAREN Statement ;
1862ContinueStatement: T_CONTINUE T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
1863ContinueStatement: T_CONTINUE T_SEMICOLON ;
1864ContinueStatement: T_CONTINUE T_IDENTIFIER T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
1865ContinueStatement: T_CONTINUE T_IDENTIFIER T_SEMICOLON ;
1866BreakStatement: T_BREAK T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
1867BreakStatement: T_BREAK T_SEMICOLON ;
1868BreakStatement: T_BREAK T_IDENTIFIER T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
1869BreakStatement: T_BREAK T_IDENTIFIER T_SEMICOLON ;
1870ReturnStatement: T_RETURN ExpressionOpt T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
1871ReturnStatement: T_RETURN ExpressionOpt T_SEMICOLON ;
1872WithStatement: T_WITH T_LPAREN Expression T_RPAREN Statement ;
1873SwitchStatement: T_SWITCH T_LPAREN Expression T_RPAREN CaseBlock ;
1874CaseBlock: T_LBRACE CaseClausesOpt T_RBRACE ;
1875CaseBlock: T_LBRACE CaseClausesOpt DefaultClause CaseClausesOpt T_RBRACE ;
1876CaseClauses: CaseClause ;
1877CaseClauses: CaseClauses CaseClause ;
1878CaseClausesOpt: ;
1879CaseClausesOpt: CaseClauses ;
1880CaseClause: T_CASE Expression T_COLON StatementListOpt ;
1881DefaultClause: T_DEFAULT T_COLON StatementListOpt ;
1882LabelledStatement: T_IDENTIFIER T_COLON Statement ;
1883ThrowStatement: T_THROW Expression T_AUTOMATIC_SEMICOLON ; -- automatic semicolon
1884ThrowStatement: T_THROW Expression T_SEMICOLON ;
1885TryStatement: T_TRY Block Catch ;
1886TryStatement: T_TRY Block Finally ;
1887TryStatement: T_TRY Block Catch Finally ;
1888Catch: T_CATCH T_LPAREN T_IDENTIFIER T_RPAREN Block ;
1889Finally: T_FINALLY Block ;
1890DebuggerStatement: T_DEBUGGER ;
1891FunctionDeclaration: T_FUNCTION T_IDENTIFIER T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
1892FunctionExpression: T_FUNCTION IdentifierOpt T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ;
1893FormalParameterList: T_IDENTIFIER ;
1894FormalParameterList: FormalParameterList T_COMMA T_IDENTIFIER ;
1895FormalParameterListOpt: ;
1896FormalParameterListOpt: FormalParameterList ;
1897FunctionBodyOpt: ;
1898FunctionBodyOpt: FunctionBody ;
1899FunctionBody: SourceElements ;
1900Program: SourceElements ;
1901SourceElements: SourceElement ;
1902SourceElements: SourceElements SourceElement ;
1903SourceElement: Statement ;
1904SourceElement: FunctionDeclaration ;
1905IdentifierOpt: ;
1906IdentifierOpt: T_IDENTIFIER ;
1907PropertyNameAndValueListOpt: ;
1908PropertyNameAndValueListOpt: PropertyNameAndValueList ;
1909
1910/.
1911 } // switch
1912
1913 state_stack [tos] = nt_action (act, lhs [r] - TERMINAL_COUNT);
1914
1915 if (rhs[r] > 1) {
1916 location_stack[tos - 1].endLine = location_stack[tos + rhs[r] - 2].endLine;
1917 location_stack[tos - 1].endColumn = location_stack[tos + rhs[r] - 2].endColumn;
1918 location_stack[tos] = location_stack[tos + rhs[r] - 1];
1919 }
1920 }
1921
1922 else
1923 {
1924 if (saved_yytoken == -1 && automatic (lexer, yytoken) && t_action (state, T_AUTOMATIC_SEMICOLON) > 0)
1925 {
1926 saved_yytoken = yytoken;
1927 yytoken = T_SEMICOLON;
1928 continue;
1929 }
1930
1931 else if ((state == INITIAL_STATE) && (yytoken == 0)) {
1932 // accept empty input
1933 yytoken = T_SEMICOLON;
1934 continue;
1935 }
1936
1937 int ers = state;
1938 int shifts = 0;
1939 int reduces = 0;
1940 int expected_tokens [3];
1941 for (int tk = 0; tk < TERMINAL_COUNT; ++tk)
1942 {
1943 int k = t_action (ers, tk);
1944
1945 if (! k)
1946 continue;
1947 else if (k < 0)
1948 ++reduces;
1949 else if (spell [tk])
1950 {
1951 if (shifts < 3)
1952 expected_tokens [shifts] = tk;
1953 ++shifts;
1954 }
1955 }
1956
1957 error_message.clear ();
1958 if (shifts && shifts < 3)
1959 {
1960 bool first = true;
1961
1962 for (int s = 0; s < shifts; ++s)
1963 {
1964 if (first)
1965 error_message += QLatin1String ("Expected ");
1966 else
1967 error_message += QLatin1String (", ");
1968
1969 first = false;
1970 error_message += QLatin1String("`");
1971 error_message += QLatin1String (spell [expected_tokens [s]]);
1972 error_message += QLatin1String("'");
1973 }
1974 }
1975
1976 if (error_message.isEmpty())
1977 error_message = lexer->errorMessage();
1978
1979 error_lineno = lexer->startLineNo();
1980 error_column = lexer->startColumnNo();
1981
1982 return false;
1983 }
1984 }
1985
1986 return false;
1987}
1988
1989
1990bool loadQScript(Translator &translator, const QString &filename, ConversionData &cd)
1991{
1992 QFile file(filename);
1993 if (!file.open(QIODevice::ReadOnly)) {
1994 cd.appendError(QString::fromLatin1("Cannot open %1: %2")
1995 .arg(filename, file.errorString()));
1996 return false;
1997 }
1998 QTextStream ts(&file);
1999 QByteArray codecName;
2000 if (!cd.m_codecForSource.isEmpty())
2001 codecName = cd.m_codecForSource;
2002 else
2003 codecName = translator.codecName(); // Just because it should be latin1 already
2004 ts.setCodec(QTextCodec::codecForName(codecName));
2005 ts.setAutoDetectUnicode(true);
2006
2007 QString code = ts.readAll();
2008 QScript::Lexer lexer;
2009 lexer.setCode(code, /*lineNumber=*/1);
2010 QScriptParser parser;
2011 if (!parser.parse(&lexer, filename, &translator)) {
2012 qWarning("%s:%d: %s", qPrintable(filename), parser.errorLineNumber(),
2013 qPrintable(parser.errorMessage()));
2014 return false;
2015 }
2016
2017 // Java uses UTF-16 internally and Jambi makes UTF-8 for tr() purposes of it.
2018 translator.setCodecName("UTF-8");
2019 return true;
2020}
2021
2022QT_END_NAMESPACE
2023./
Note: See TracBrowser for help on using the repository browser.