File indexing completed on 2024-04-28 04:36:07

0001 /* 
0002  * Copyright 2005, 2006 Jakob Petsovits <jpetso@gmx.at>
0003  * Based on QMake Parser Copyright 2006 Andreas Pakulat <apaku@gmx.de>
0004  *
0005  * This program is free software; you can redistribute it and/or
0006  * modify it under the terms of the GNU General Public License
0007  * as published by the Free Software Foundation; either version 2
0008  * of the License, or (at your option) any later version.
0009  *
0010  * This program is distributed in the hope that it will be useful,
0011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013  * GNU General Public License for more details.
0014  *
0015  * You should have received a copy of the GNU General Public License
0016  * along with this program; if not, write to the Free Software
0017  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
0018  * 02110-1301, USA.
0019  */
0020 
0021 #include "factlexer.h"
0022 
0023 #include <QString>
0024 #include <QStringList>
0025 #include <QDebug>
0026 #include "factparser.h"
0027 #include <kdev-pg-location-table.h>
0028 #include <kdev-pg-token-stream.h>
0029 
0030 using namespace fact;
0031 
0032 Lexer::Lexer( Parser* _parser, const QString& content ):
0033         m_content( content ), m_parser( _parser ),
0034         m_curpos( 0 ), m_contentSize( m_content.size() ),
0035         m_tokenBegin( 0 ), m_tokenEnd( 0 )
0036 {
0037     pushState( ErrorState );
0038     pushState( DefaultState );
0039 }
0040 
0041 int Lexer::state() const
0042 {
0043     return mState.top();
0044 }
0045 
0046 void Lexer::pushState( int state )
0047 {
0048     mState.push( state );
0049 }
0050 
0051 void Lexer::popState()
0052 {
0053     mState.pop();
0054 }
0055 
0056 int Lexer::nextTokenKind()
0057 {
0058     int token = Parser::Token_INVALID;
0059     if ( m_curpos >= m_contentSize )
0060     {
0061         return 0;
0062     }
0063     QChar* it = m_content.data();
0064     it += m_curpos;
0065 
0066     // Ignore whitespace
0067     while ( m_curpos < m_contentSize && ( it->isSpace() ) )
0068     {
0069         if (it->unicode() == '\n') {
0070             createNewline(m_curpos);
0071         }
0072         ++it;
0073         ++m_curpos;
0074     }
0075 
0076     switch ( state() )
0077     {
0078         case DefaultState:
0079             m_tokenBegin = m_curpos;
0080             if ( m_curpos < m_contentSize )
0081             {
0082                 if ( it->isLetter() )
0083                 {
0084                     QString identifier;
0085                     while ( m_curpos < m_contentSize && ( it->isLetter() || it->isDigit() ) && !it->isSpace() ) {
0086                         identifier.append(*it);
0087                         ++it;
0088                         ++m_curpos;
0089                     }
0090                     m_curpos--;
0091                     QChar* it1 = m_content.data();
0092                     it1 += m_curpos;
0093 
0094                     if ( identifier == "if" ) {
0095                         token = Parser::Token_IF;
0096                     } else if ( identifier == "else" ) {
0097                         token = Parser::Token_ELSE;
0098                     } else if ( identifier == "var" ) {
0099                         token = Parser::Token_VAR;
0100                     } else if ( identifier == "function" ) {
0101                         token = Parser::Token_FUNCTION;
0102                     } else if ( identifier == "return" ) {
0103                         token = Parser::Token_RETURN;
0104                     } else {
0105                         token = Parser::Token_IDENTIFIER;
0106                     }
0107                 }
0108                 else if ( it->isDigit() )
0109                 {
0110                     token = Parser::Token_NUMBER;
0111                     while ( m_curpos < m_contentSize && ( it->isDigit() ) ) {
0112                         ++it;
0113                         ++m_curpos;
0114                     }
0115                     --m_curpos;
0116                 }
0117                 else
0118                 {
0119                     switch ( it->unicode() )
0120                     {
0121                         case ',':
0122                             token = Parser::Token_COMMA;
0123                             break;
0124                         case ';':
0125                             token = Parser::Token_SEMICOLON;
0126                             break;
0127                         case '(':
0128                             token = Parser::Token_LPAREN;
0129                             break;
0130                         case ')':
0131                             token = Parser::Token_RPAREN;
0132                             break;
0133                         case '{':
0134                             token = Parser::Token_LBRACE;
0135                             break;
0136                         case '}':
0137                             token = Parser::Token_RBRACE;
0138                             break;
0139                         case '=':
0140                         {
0141                             QChar* c2 = m_curpos < m_contentSize ? it + 1 : 0 ;
0142                             if ( c2 && c2->unicode() == '=' )
0143                             {
0144                                 m_curpos++;
0145                                 token = Parser::Token_EQUAL;
0146                             } else {
0147                                 token = Parser::Token_ASSIGN;
0148                             }
0149                             break;
0150                         }
0151                         case '*':
0152                             token = Parser::Token_STAR;
0153                             break;
0154                         case '-':
0155                             token = Parser::Token_MINUS;
0156                             break;
0157                         default:
0158                             break;
0159                     }
0160                 }
0161             }
0162             break;
0163         default:
0164             token = Parser::Token_INVALID;
0165             break;
0166     }
0167     if ( m_curpos >= m_contentSize )
0168     {
0169         return 0;
0170     }
0171     m_tokenEnd = m_curpos;
0172     m_curpos++;
0173     return token;
0174 }
0175 
0176 qint64 Lexer::tokenBegin() const
0177 {
0178   return m_tokenBegin;
0179 }
0180 
0181 qint64 Lexer::tokenEnd() const
0182 {
0183   return m_tokenEnd;
0184 }
0185 
0186 void Lexer::createNewline( int pos )
0187 {
0188     if( m_parser )
0189         m_parser->tokenStream->locationTable()->newline( pos );
0190 }
0191 // kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on