source: trunk/tools/porting/src/rppexpressionbuilder.cpp@ 500

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

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 9.9 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the qt3to4 porting application of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** 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 are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "rppexpressionbuilder.h"
43#include "tokens.h"
44#include "rpp.h"
45
46QT_BEGIN_NAMESPACE
47
48using namespace TokenEngine;
49namespace Rpp {
50
51ExpressionBuilder::ExpressionBuilder(const TokenList &tokenList, const QVector<Type> &typeList, TypedPool<Item> *memoryPool)
52:i(0)
53,m_tokenList(tokenList)
54,m_typeList(typeList)
55,m_memoryPool(memoryPool)
56{}
57
58Rpp::Expression *ExpressionBuilder::parse()
59{
60 if(unary_expression_lookup())
61 return conditional_expression();
62 else
63 return createIntLiteral(0);
64}
65Type ExpressionBuilder::next()
66{
67 if(!hasNext())
68 return Token_eof;
69 return typeAt(i++);
70}
71
72inline bool ExpressionBuilder::test(int token)
73{
74 if (i < m_tokenList.count() && typeAt(i) == token) {
75 ++i;
76 return true;
77 }
78 return false;
79}
80
81inline bool ExpressionBuilder::moreTokens(int delta)
82{
83 return (i + delta < m_tokenList.count());
84}
85
86inline Type ExpressionBuilder::lookup(int k)
87{
88 const int l = i - 1 + k;
89 return l < m_tokenList.count() ? typeAt(l) : Token_eof;
90}
91
92Expression *ExpressionBuilder::conditional_expression()
93{
94 Expression *value = logical_OR_expression();
95 if (test('?')) {
96 Expression *leftExpression = conditional_expression();
97 Expression *rightExpression;
98 if(test(':'))
99 rightExpression = conditional_expression();
100 else
101 rightExpression = createIntLiteral(0);
102 return createConditionalExpression(value, leftExpression, rightExpression);
103 }
104 return value;
105}
106
107Expression *ExpressionBuilder::logical_OR_expression()
108{
109 Expression *value = logical_AND_expression();
110 if (test(Token_or))
111 return createBinaryExpression(Expression::OrOp, value, logical_OR_expression());
112 return value;
113}
114
115Expression *ExpressionBuilder::logical_AND_expression()
116{
117 Expression *value = inclusive_OR_expression();
118 if (test(Token_and))
119 return createBinaryExpression(Expression::AndOp, value, logical_AND_expression());
120 return value;
121}
122
123Expression *ExpressionBuilder::inclusive_OR_expression()
124{
125 Expression *value = exclusive_OR_expression();
126 if (test('|'))
127 return createBinaryExpression('|', value, inclusive_OR_expression());
128 return value;
129}
130
131Expression *ExpressionBuilder::exclusive_OR_expression()
132{
133 Expression *value = AND_expression();
134 if (test('^'))
135 return createBinaryExpression('^', value, exclusive_OR_expression());
136 return value;
137}
138
139Expression *ExpressionBuilder::AND_expression()
140{
141 Expression *value = equality_expression();
142 if (test('&'))
143 return createBinaryExpression('&', value, AND_expression());
144 return value;
145}
146
147Expression *ExpressionBuilder::equality_expression()
148{
149 Expression *value = relational_expression();
150 switch (next()) {
151 case Token_eq:
152 return createBinaryExpression(Expression::EqOp, value, equality_expression());
153 case Token_not_eq:
154 return createBinaryExpression(Expression::NotEqOp, value, equality_expression());
155 default:
156 prev();
157 return value;
158 }
159}
160
161Expression *ExpressionBuilder::relational_expression()
162{
163 Expression *value = shift_expression();
164 switch (next()) {
165 case '<':
166 return createBinaryExpression('<', value, relational_expression());
167 case '>':
168 return createBinaryExpression('>', value, relational_expression());
169 case Token_leq:
170 return createBinaryExpression(Expression::LtEqOp, value, relational_expression());
171 case Token_geq:
172 return createBinaryExpression(Expression::GtEqOp, value, relational_expression());
173 default:
174 prev();
175 return value;
176 }
177}
178
179Expression *ExpressionBuilder::shift_expression()
180{
181 Expression *value = additive_expression();
182 switch (next()) {
183 case Token_left_shift:
184 return createBinaryExpression(Expression::LShiftOp, value, shift_expression());
185 case Token_right_shift:
186 return createBinaryExpression(Expression::RShiftOp, value, shift_expression());
187 default:
188 prev();
189 return value;
190 }
191}
192
193Expression *ExpressionBuilder::additive_expression()
194{
195 Expression *value = multiplicative_expression();
196 switch (next()) {
197 case '+':
198 return createBinaryExpression('+', value, additive_expression());
199 case '-':
200 return createBinaryExpression('-', value, additive_expression());
201 default:
202 prev();
203 return value;
204 }
205}
206
207Expression *ExpressionBuilder::multiplicative_expression()
208{
209 Expression *value = unary_expression();
210 switch (next()) {
211 case '*':
212 return createBinaryExpression('*', value, multiplicative_expression());
213 case '%':
214 return createBinaryExpression('%', value, multiplicative_expression());
215 case '/':
216 return createBinaryExpression('/', value, multiplicative_expression());
217 default:
218 prev();
219 return value;
220 };
221}
222
223Expression *ExpressionBuilder::unary_expression()
224{
225 switch (next()) {
226 case '+':
227 return createUnaryExpression('+', unary_expression());
228 case '-':
229 return createUnaryExpression('-', unary_expression());
230 case '!':
231 return createUnaryExpression('!', unary_expression());
232 case '~':
233 return createUnaryExpression('~', unary_expression());
234 case Token_defined:
235 {
236 int identifierIndex = 0;
237 if (test(Token_identifier)) {
238 identifierIndex = i - 1;
239 } else if (test('(')) {
240 if (test(Token_identifier))
241 identifierIndex = i -1;
242 test(')');
243 }
244 return createMacroReference(MacroReference::DefinedRef, createTokenList(identifierIndex));
245 }
246 default:
247 prev();
248 return primary_expression();
249 }
250}
251
252bool ExpressionBuilder::unary_expression_lookup()
253{
254 Type t = lookup();
255 return (primary_expression_lookup()
256 || t == '+'
257 || t == '-'
258 || t == '!'
259 || t == '~'
260 || t == Token_defined);
261}
262
263Expression *ExpressionBuilder::primary_expression()
264{
265 Expression *value;
266 if (test('(')) {
267 if (moreTokens(1))
268 value = conditional_expression();
269 else
270 value = createIntLiteral(0); // Syntax error.
271 test(')');
272 } else {
273 next();
274 bool ok;
275 int val = QString::fromLatin1(lexem()).toInt(&ok, 0);
276 if(ok)
277 value = createIntLiteral(val);
278 else
279 value = createMacroReference(MacroReference::ValueRef, createTokenList(i -1));
280 }
281 return value;
282}
283
284bool ExpressionBuilder::primary_expression_lookup()
285{
286 Type t = lookup();
287 return (t == Token_identifier
288 || t == Token_number_literal
289/* || t == PP_FLOATING_LITERAL*/
290 || t == '(');
291}
292/*
293 Creates a tokenList containing one token
294*/
295TokenList ExpressionBuilder::createTokenList(int tokenIndex) const
296{
297 return TokenList(m_tokenList.tokenContainer(tokenIndex),
298 QVector<int>() << m_tokenList.containerIndex(tokenIndex));
299}
300/*
301 Node cration helper functions
302*/
303UnaryExpression *ExpressionBuilder::createUnaryExpression(int op, Expression *expression)
304{
305 return new (m_memoryPool->allocate(sizeof(UnaryExpression))) UnaryExpression(op, expression);
306}
307
308BinaryExpression *ExpressionBuilder::createBinaryExpression(int op, Expression *leftExpresson, Expression *rightExpression)
309{
310 return new (m_memoryPool->allocate(sizeof(BinaryExpression))) BinaryExpression(op, leftExpresson, rightExpression);
311}
312
313ConditionalExpression *ExpressionBuilder::createConditionalExpression(Expression *condition, Expression *leftExpression, Expression *rightExpression)
314{
315 return new (m_memoryPool->allocate(sizeof(ConditionalExpression))) ConditionalExpression(condition, leftExpression, rightExpression);
316}
317
318MacroReference *ExpressionBuilder::createMacroReference(MacroReference::Type type, TokenEngine::TokenList token)
319{
320 return new (m_memoryPool->allocate(sizeof(MacroReference))) MacroReference(token, type);
321}
322
323IntLiteral *ExpressionBuilder::createIntLiteral(const int arg)
324{
325 return new (m_memoryPool->allocate(sizeof(IntLiteral))) IntLiteral(arg);
326}
327
328}
329
330QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.