Eneboo - Documentación para desarrolladores
src/qsa/src/engine/qslexer.h
Ir a la documentación de este archivo.
00001 /****************************************************************************
00002 ** $Id: qslexer.h  1.1.5   edited 2006-02-23T15:39:57$
00003 **
00004 ** Copyright (C) 2001-2006 Trolltech AS.  All rights reserved.
00005 **
00006 ** This file is part of the Qt Script for Applications framework (QSA).
00007 **
00008 ** This file may be distributed and/or modified under the terms of the
00009 ** GNU General Public License version 2 as published by the Free Software
00010 ** Foundation and appearing in the file LICENSE.GPL included in the
00011 ** packaging of this file.
00012 **
00013 ** Licensees holding a valid Qt Script for Applications license may use
00014 ** this file in accordance with the Qt Script for Applications License
00015 ** Agreement provided with the Software.
00016 **
00017 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00018 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00019 **
00020 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
00021 **   information about QSA Commercial License Agreements.
00022 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00023 **
00024 ** Contact info@trolltech.com if any conditions of this licensing are
00025 ** not clear to you.
00026 **
00027 *****************************************************************************/
00028 
00029 #ifndef QSLEXER_H
00030 #define QSLEXER_H
00031 
00032 #include <qintdict.h>
00033 #include <qptrlist.h>
00034 #include <qstring.h>
00035 #include <qlocale.h>
00036 
00037 class QSLexer
00038 {
00039 public:
00040   enum State {
00041     Start,
00042     Identifier,
00043     InIdentifier,
00044     InSingleLineComment,
00045     InMultiLineComment,
00046     InNum,
00047     InNum0,
00048     InHex,
00049     InOctal,
00050     InDecimal,
00051     InExponentIndicator,
00052     InExponent,
00053     Hex,
00054     Octal,
00055     Number,
00056     String,
00057     Eof,
00058     InString,
00059     InEscapeSequence,
00060     InHexEscape,
00061     InUnicodeEscape,
00062     Other,
00063     Bad,
00064     KeywordNumber
00065   };
00066 
00067   enum ParenthesesState {
00068     IgnoreParentheses,
00069     CountParentheses,
00070     BalancedParentheses
00071   };
00072 
00073   QSLexer();
00074   ~QSLexer();
00075 
00076   static QSLexer *lexer() {
00077     return lx;
00078   }
00079 
00080   void setCode(const QString &c, int id, int lineno = 0);
00081   int lex();
00082 
00083   int lineNo() const {
00084     return yylineno + 1;
00085   }
00086 
00087   int sourceId() const {
00088     return sid;
00089   }
00090 
00091   bool prevTerminator() const {
00092     return terminator;
00093   }
00094 
00095   QString pattern, flags;
00096 
00097   bool scanRegExp();
00098 
00099   State lexerState() const {
00100     return state;
00101   }
00102 
00103   QString errorMessage() const {
00104     return errmsg;
00105   }
00106   void setErrorMessage(const QString &err) {
00107     errmsg = err;
00108   }
00109   void setErrorMessage(const char *err) {
00110     setErrorMessage(QString::fromLatin1(err));
00111   }
00112 
00113 private:
00114   int yylineno;
00115   bool done;
00116   char *buffer8;
00117   QChar *buffer16;
00118   uint size8, size16;
00119   uint pos8, pos16;
00120   bool terminator;
00121   bool restrKeyword;
00122   // encountered delimiter like "'" and "}" on last run
00123   bool delimited;
00124   int stackToken;
00125 
00126   State state;
00127   void setDone(State s) {
00128     state = s;
00129     done = TRUE;
00130   }
00131 
00132   uint pos;
00133 
00134   bool isWhiteSpace() const {
00135     return (current == ' ' || current == '\t' ||
00136             current == 0x0b || current == 0x0c);
00137   }
00138 
00139   bool isLineTerminator() const {
00140     return (current == '\n' || current == '\r');
00141   }
00142 
00143   bool isHexDigit(ushort c) const {
00144     return ((c >= '0' && c <= '9') ||
00145             (c >= 'a' && c <= 'f') ||
00146             (c >= 'A' && c <= 'F'));
00147   }
00148 
00149   bool isOctalDigit(ushort c) const {
00150     return (c >= '0' && c <= '7');
00151   }
00152 
00153   ushort singleEscape(ushort c) const {
00154     switch (c) {
00155       case 'b':
00156         return 0x08;
00157       case 't':
00158         return 0x09;
00159       case 'n':
00160         return 0x0A;
00161       case 'v':
00162         return 0x0B;
00163       case 'f':
00164         return 0x0C;
00165       case 'r':
00166         return 0x0D;
00167       case '"':
00168         return 0x22;
00169       case '\'':
00170         return 0x27;
00171       case '\\':
00172         return 0x5C;
00173       default:
00174         return c;
00175     }
00176   }
00177 
00178   ushort convertOctal(ushort c1, ushort c2,
00179                       ushort c3) const {
00180     return ((c1 - '0') * 64 + (c2 - '0') * 8 + c3 - '0');
00181   }
00182 
00183 public:
00184   static uchar convertHex(ushort c) {
00185     if (c >= '0' && c <= '9')
00186       return static_cast<uchar>(c - '0');
00187     else if (c >= 'a' && c <= 'f')
00188       return static_cast<uchar>(c - 'a' + 10);
00189     else
00190       return static_cast<uchar>(c - 'A' + 10);
00191   }
00192 
00193   static uchar convertHex(ushort c1, ushort c2) {
00194     return ((convertHex(c1) << 4) + convertHex(c2));
00195   }
00196 
00197   static QChar convertUnicode(ushort c1, ushort c2,
00198                               ushort c3, ushort c4) {
00199     return QChar((convertHex(c3) << 4) + convertHex(c4),
00200                  (convertHex(c1) << 4) + convertHex(c2));
00201   }
00202 
00203   static bool isIdentLetter(ushort c) {
00204     /* TODO: allow other legitimate unicode chars */
00205     return ((c >= 'a' && c <= 'z') ||
00206             (c >= 'A' && c <= 'Z') ||
00207             (c == '$' || c == '_'));
00208   }
00209 
00210   static bool isDecimalDigit(ushort c) {
00211     return (c >= '0' && c <= '9');
00212   }
00213 
00214   void clearUstr() {
00215     if (ustrHash.count() > 401)
00216       ustrHash.clear();
00217     ustrList.clear();
00218   }
00219 
00220 private:
00221 
00222   static QSLexer *lx;
00223   static int sid;
00224 
00225   QIntDict<QString> ustrHash;
00226   QPtrList<QString> ustrList;
00227 
00228   uint hashUstr(QChar *s, uint len) {
00229     uint hash = 0;
00230     for (int i = 0; i < len; ++i) {
00231       hash += s[i].unicode();
00232       hash += (hash << 10);
00233       hash ^= (hash >> 6);
00234     }
00235     hash += (hash << 3);
00236     hash ^= (hash >> 11);
00237     hash += (hash << 15);
00238     return hash;
00239   }
00240 
00241   const QString *newUstr(QChar *s, uint len) {
00242     QString *us = 0;
00243     if (len < 50) {
00244       uint hash = hashUstr(s, len);
00245       us = ustrHash.find(hash);
00246       if (!us) {
00247         us = new QString(s, len);
00248         ustrHash.insert(hash, us);
00249       }
00250     } else {
00251       us = new QString(s, len);
00252       ustrList.append(us);
00253     }
00254     return us;
00255   }
00256 
00257   void syncProhibitAutomaticSemicolon() {
00258     if (parenthesesState == BalancedParentheses) {
00259       // we have seen something like "if (foo)", which means we should
00260       // never insert an automatic semicolon at this point, since it would
00261       // then be expanded into an empty statement (ECMA-262 7.9.1)
00262       prohibitAutomaticSemicolon = true;
00263       parenthesesState = IgnoreParentheses;
00264     } else {
00265       prohibitAutomaticSemicolon = false;
00266     }
00267   }
00268 
00269   const QChar *code;
00270   uint length;
00271   int yycolumn;
00272   int bol;
00273 
00274   // current and following unicode characters
00275   ushort current, next1, next2, next3;
00276 
00277   QString errmsg;
00278   QLocale localeC;
00279 
00280   ParenthesesState parenthesesState;
00281   int parenthesesCount;
00282   bool prohibitAutomaticSemicolon;
00283 };
00284 
00285 #endif
 Todo Clases Namespaces Archivos Funciones Variables 'typedefs' Enumeraciones Valores de enumeraciones Propiedades Amigas 'defines'