1 /****************************************************************************
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtScript module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
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.
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.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include "qscriptsyntaxchecker_p.h"
44 #include "qscriptlexer_p.h"
45 #include "qscriptparser_p.h"
52 SyntaxChecker::SyntaxChecker():
59 SyntaxChecker::~SyntaxChecker()
66 bool SyntaxChecker::automatic(QScript::Lexer
*lexer
, int token
) const
68 return token
== T_RBRACE
|| token
== 0 || lexer
->prevTerminator();
71 SyntaxChecker::Result
SyntaxChecker::checkSyntax(const QString
&code
)
73 const int INITIAL_STATE
= 0;
74 QScript::Lexer
lexer (/*engine=*/ 0);
75 lexer
.setCode(code
, /*lineNo*/ 1);
78 int saved_yytoken
= -1;
79 QString error_message
;
80 int error_lineno
= -1;
81 int error_column
= -1;
82 State checkerState
= Valid
;
87 state_stack
[++tos
] = INITIAL_STATE
;
91 const int state
= state_stack
[tos
];
92 if (yytoken
== -1 && - TERMINAL_COUNT
!= action_index
[state
])
94 if (saved_yytoken
== -1)
95 yytoken
= lexer
.lex();
98 yytoken
= saved_yytoken
;
103 int act
= t_action (state
, yytoken
);
105 if (act
== ACCEPT_STATE
) {
106 if (lexer
.error() == QScript::Lexer::UnclosedComment
)
107 checkerState
= Intermediate
;
109 checkerState
= Valid
;
111 } else if (act
> 0) {
112 if (++tos
== stack_size
)
115 state_stack
[tos
] = act
;
124 act
= state_stack
[tos
++];
126 if ((r
== Q_SCRIPT_REGEXPLITERAL_RULE1
)
127 || (r
== Q_SCRIPT_REGEXPLITERAL_RULE2
)) {
128 // Skip the rest of the RegExp literal
129 bool rx
= lexer
.scanRegExp();
131 checkerState
= Intermediate
;
136 state_stack
[tos
] = nt_action (act
, lhs
[r
] - TERMINAL_COUNT
);
141 if (saved_yytoken
== -1 && automatic (&lexer
, yytoken
) && t_action (state
, T_AUTOMATIC_SEMICOLON
) > 0)
143 saved_yytoken
= yytoken
;
144 yytoken
= T_SEMICOLON
;
148 else if ((state
== INITIAL_STATE
) && (yytoken
== 0)) {
149 // accept empty input
150 yytoken
= T_SEMICOLON
;
157 int expected_tokens
[3];
158 for (int tk
= 0; tk
< TERMINAL_COUNT
; ++tk
)
160 int k
= t_action (ers
, tk
);
169 expected_tokens
[shifts
] = tk
;
174 error_message
.clear ();
175 if (shifts
&& shifts
< 3)
179 for (int s
= 0; s
< shifts
; ++s
)
182 error_message
+= QLatin1String ("Expected ");
184 error_message
+= QLatin1String (", ");
187 error_message
+= QLatin1Char('`');
188 error_message
+= QLatin1String (spell
[expected_tokens
[s
]]);
189 error_message
+= QLatin1Char('\'');
193 if (error_message
.isEmpty())
194 error_message
= lexer
.errorMessage();
196 error_lineno
= lexer
.startLineNo();
197 error_column
= lexer
.startColumnNo();
198 checkerState
= Error
;
203 if (checkerState
== Error
) {
204 if (lexer
.error() == QScript::Lexer::UnclosedComment
)
205 checkerState
= Intermediate
;
206 else if (yytoken
== 0)
207 checkerState
= Intermediate
;
209 return Result(checkerState
, error_lineno
, error_column
, error_message
);
212 } // namespace QScript