tools/porting/src/rppexpressionbuilder.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 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 qt3to4 porting application of the Qt Toolkit.
       
     8 **
       
     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
       
    14 ** this package.
       
    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 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "rppexpressionbuilder.h"
       
    43 #include "tokens.h"
       
    44 #include "rpp.h"
       
    45 
       
    46 QT_BEGIN_NAMESPACE
       
    47 
       
    48 using namespace TokenEngine;
       
    49 namespace Rpp {
       
    50 
       
    51 ExpressionBuilder::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 
       
    58 Rpp::Expression *ExpressionBuilder::parse()
       
    59 {
       
    60     if(unary_expression_lookup())
       
    61         return conditional_expression();
       
    62     else
       
    63         return createIntLiteral(0);
       
    64 }
       
    65 Type ExpressionBuilder::next()
       
    66 {
       
    67     if(!hasNext())
       
    68         return Token_eof;
       
    69     return typeAt(i++);
       
    70 }
       
    71 
       
    72 inline 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 
       
    81 inline bool ExpressionBuilder::moreTokens(int delta)
       
    82 {
       
    83     return (i + delta < m_tokenList.count());
       
    84 }
       
    85 
       
    86 inline 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 
       
    92 Expression *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 
       
   107 Expression *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 
       
   115 Expression *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 
       
   123 Expression *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 
       
   131 Expression *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 
       
   139 Expression *ExpressionBuilder::AND_expression()
       
   140 {
       
   141     Expression *value = equality_expression();
       
   142     if (test('&'))
       
   143         return createBinaryExpression('&', value, AND_expression());
       
   144     return value;
       
   145 }
       
   146 
       
   147 Expression *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 
       
   161 Expression *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 
       
   179 Expression *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 
       
   193 Expression *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 
       
   207 Expression *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 
       
   223 Expression *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 
       
   252 bool 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 
       
   263 Expression *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 
       
   284 bool 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 */
       
   295 TokenList 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 */
       
   303 UnaryExpression *ExpressionBuilder::createUnaryExpression(int op, Expression *expression)
       
   304 {
       
   305     return new (m_memoryPool->allocate(sizeof(UnaryExpression))) UnaryExpression(op, expression);
       
   306 }
       
   307 
       
   308 BinaryExpression *ExpressionBuilder::createBinaryExpression(int op, Expression *leftExpresson, Expression *rightExpression)
       
   309 {
       
   310     return new (m_memoryPool->allocate(sizeof(BinaryExpression))) BinaryExpression(op, leftExpresson, rightExpression);
       
   311 }
       
   312 
       
   313 ConditionalExpression *ExpressionBuilder::createConditionalExpression(Expression *condition, Expression *leftExpression, Expression *rightExpression)
       
   314 {
       
   315     return new (m_memoryPool->allocate(sizeof(ConditionalExpression))) ConditionalExpression(condition, leftExpression, rightExpression);
       
   316 }
       
   317 
       
   318 MacroReference *ExpressionBuilder::createMacroReference(MacroReference::Type type, TokenEngine::TokenList token)
       
   319 {
       
   320     return new (m_memoryPool->allocate(sizeof(MacroReference))) MacroReference(token, type);
       
   321 }
       
   322 
       
   323 IntLiteral *ExpressionBuilder::createIntLiteral(const int arg)
       
   324 {
       
   325     return new (m_memoryPool->allocate(sizeof(IntLiteral))) IntLiteral(arg);
       
   326 }
       
   327 
       
   328 }
       
   329 
       
   330 QT_END_NAMESPACE