/****************************************************************************
** $Id: qslexer.h,v 1.1 2006/09/05 11:55:58 petrm1am Exp $
**
** Copyright (C) 2001-2006 Trolltech AS.  All rights reserved.
**
** This file is part of the Qt Script for Applications framework (QSA).
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** Licensees holding a valid Qt Script for Applications license may use
** this file in accordance with the Qt Script for Applications License
** Agreement provided with the Software.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
**   information about QSA Commercial License Agreements.
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
*****************************************************************************/

#ifndef QSLEXER_H
#define QSLEXER_H

#include <qstring.h>

class QSLexer {
public:
    QSLexer();
    ~QSLexer();
    static QSLexer *lexer() { return lx; }

    void setCode( const QString &c, int id, int lineno=0 );
    int lex();

    int lineNo() const { return yylineno + 1; }
    int sourceId() const { return sid; }

    bool prevTerminator() const { return terminator; }

    enum State { Start,
		 Identifier,
		 InIdentifier,
		 InSingleLineComment,
		 InMultiLineComment,
		 InNum,
		 InNum0,
		 InHex,
		 InOctal,
		 InDecimal,
		 InExponentIndicator,
		 InExponent,
		 Hex,
		 Octal,
		 Number,
		 String,
		 Eof,
		 InString,
		 InEscapeSequence,
		 InHexEscape,
		 InUnicodeEscape,
		 Other,
		 Bad };

    bool scanRegExp();
    QString pattern, flags;

    State lexerState() const { return state; }

    QString errorMessage() const { return errmsg; }
    void setErrorMessage( const QString &err ) { errmsg = err; }
    void setErrorMessage( const char *err ) { setErrorMessage(QString::fromLatin1(err)); }

private:
    int yylineno;
    bool done;
    char *buffer8;
    QChar *buffer16;
    uint size8, size16;
    uint pos8, pos16;
    bool terminator;
    bool restrKeyword;
    // encountered delimiter like "'" and "}" on last run
    bool delimited;
    int stackToken;

    State state;
    void setDone( State s );
    uint pos;
    void shift( uint p );
    int lookupKeyword( const char * );

    bool isWhiteSpace() const;
    bool isLineTerminator() const;
    bool isHexDigit( ushort c ) const;
    bool isOctalDigit( ushort c ) const;

    int matchPunctuator( ushort c1, ushort c2,
			 ushort c3, ushort c4 );
    ushort singleEscape( ushort c ) const;
    ushort convertOctal( ushort c1, ushort c2,
			 ushort c3 ) const;
public:
    static unsigned char convertHex( ushort c1 );
    static unsigned char convertHex( ushort c1, ushort c2 );
    static QChar convertUnicode( ushort c1, ushort c2,
				 ushort c3, ushort c4 );
    static bool isIdentLetter( ushort c );
    static bool isDecimalDigit( ushort c );

private:

    static QSLexer *lx;
    static int sid;

    void record8( ushort c);
    void record16( QChar c );

    const QChar *code;
    uint length;
    int yycolumn;
    int bol;     // begin of line

    // current and following unicode characters
    ushort current, next1, next2, next3;

    struct keyword {
	const char *name;
	int token;
    };

    QString errmsg;
};

#endif
