Qt 4.8
qscriptsyntaxchecker.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtScript module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL-ONLY$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser
11 ** General Public License version 2.1 as published by the Free Software
12 ** Foundation and appearing in the file LICENSE.LGPL included in the
13 ** packaging of this file. Please review the following information to
14 ** ensure the GNU Lesser General Public License version 2.1 requirements
15 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** If you have questions regarding the use of this file, please contact
18 ** us via http://www.qt-project.org/.
19 **
20 ** $QT_END_LICENSE$
21 **
22 ****************************************************************************/
23 
24 #include "qscriptsyntaxchecker_p.h"
25 
26 #include "qscriptlexer_p.h"
27 #include "qscriptparser_p.h"
28 
30 
31 namespace QScript {
32 
33 
35  tos(0),
36  stack_size(0),
37  state_stack(0)
38 {
39 }
40 
42 {
43  if (stack_size) {
45  }
46 }
47 
48 bool SyntaxChecker::automatic(QScript::Lexer *lexer, int token) const
49 {
50  return token == T_RBRACE || token == 0 || lexer->prevTerminator();
51 }
52 
54 {
55  const int INITIAL_STATE = 0;
56  QScript::Lexer lexer (/*engine=*/ 0);
57  lexer.setCode(code, /*lineNo*/ 1);
58 
59  int yytoken = -1;
60  int saved_yytoken = -1;
61  QString error_message;
62  int error_lineno = -1;
63  int error_column = -1;
64  State checkerState = Valid;
65 
67 
68  tos = 0;
69  state_stack[++tos] = INITIAL_STATE;
70 
71  while (true)
72  {
73  const int state = state_stack [tos];
74  if (yytoken == -1 && - TERMINAL_COUNT != action_index [state])
75  {
76  if (saved_yytoken == -1)
77  yytoken = lexer.lex();
78  else
79  {
80  yytoken = saved_yytoken;
81  saved_yytoken = -1;
82  }
83  }
84 
85  int act = t_action (state, yytoken);
86 
87  if (act == ACCEPT_STATE) {
89  checkerState = Intermediate;
90  else
91  checkerState = Valid;
92  break;
93  } else if (act > 0) {
94  if (++tos == stack_size)
96 
97  state_stack [tos] = act;
98  yytoken = -1;
99  }
100 
101  else if (act < 0)
102  {
103  int r = - act - 1;
104 
105  tos -= rhs [r];
106  act = state_stack [tos++];
107 
109  || (r == Q_SCRIPT_REGEXPLITERAL_RULE2)) {
110  // Skip the rest of the RegExp literal
111  bool rx = lexer.scanRegExp();
112  if (!rx) {
113  checkerState = Intermediate;
114  break;
115  }
116  }
117 
118  state_stack [tos] = nt_action (act, lhs [r] - TERMINAL_COUNT);
119  }
120 
121  else
122  {
123  if (saved_yytoken == -1 && automatic (&lexer, yytoken) && t_action (state, T_AUTOMATIC_SEMICOLON) > 0)
124  {
125  saved_yytoken = yytoken;
126  yytoken = T_SEMICOLON;
127  continue;
128  }
129 
130  else if ((state == INITIAL_STATE) && (yytoken == 0)) {
131  // accept empty input
132  yytoken = T_SEMICOLON;
133  continue;
134  }
135 
136  int ers = state;
137  int shifts = 0;
138  int reduces = 0;
139  int expected_tokens [3];
140  for (int tk = 0; tk < TERMINAL_COUNT; ++tk)
141  {
142  int k = t_action (ers, tk);
143 
144  if (! k)
145  continue;
146  else if (k < 0)
147  ++reduces;
148  else if (spell [tk])
149  {
150  if (shifts < 3)
151  expected_tokens [shifts] = tk;
152  ++shifts;
153  }
154  }
155 
156  error_message.clear ();
157  if (shifts && shifts < 3)
158  {
159  bool first = true;
160 
161  for (int s = 0; s < shifts; ++s)
162  {
163  if (first)
164  error_message += QLatin1String ("Expected ");
165  else
166  error_message += QLatin1String (", ");
167 
168  first = false;
169  error_message += QLatin1Char('`');
170  error_message += QLatin1String (spell [expected_tokens [s]]);
171  error_message += QLatin1Char('\'');
172  }
173  }
174 
175  if (error_message.isEmpty())
176  error_message = lexer.errorMessage();
177 
178  error_lineno = lexer.startLineNo();
179  error_column = lexer.startColumnNo();
180  checkerState = Error;
181  break;
182  }
183  }
184 
185  if (checkerState == Error) {
186  if (lexer.error() == QScript::Lexer::UnclosedComment)
187  checkerState = Intermediate;
188  else if (yytoken == 0)
189  checkerState = Intermediate;
190  }
191  return Result(checkerState, error_lineno, error_column, error_message);
192 }
193 
194 } // namespace QScript
195 
static const short lhs[]
int startLineNo() const
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
#define Q_SCRIPT_REGEXPLITERAL_RULE1
Q_CORE_EXPORT void qFree(void *ptr)
Definition: qmalloc.cpp:58
static int t_action(int state, int token)
static int nt_action(int state, int nt)
Error error() const
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
#define Q_SCRIPT_REGEXPLITERAL_RULE2
The QString class provides a Unicode character string.
Definition: qstring.h:83
Result checkSyntax(const QString &code)
bool automatic(QScript::Lexer *lexer, int token) const
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QString errorMessage() const
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
bool scanRegExp(RegExpBodyPrefix prefix=NoPrefix)
The State element defines configurations of objects and properties.
bool prevTerminator() const
static const short action_index[]
void clear()
Clears the contents of the string and makes it empty.
Definition: qstring.h:723
static const char *const spell[]
static const short rhs[]
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
void setCode(const QString &c, int lineno)
int startColumnNo() const