File indexing completed on 2024-04-28 03:40:41
0001 /************************************************************************************* 0002 * Copyright (C) 2008 by Aleix Pol <aleixpol@kde.org> * 0003 * * 0004 * This program is free software; you can redistribute it and/or * 0005 * modify it under the terms of the GNU General Public License * 0006 * as published by the Free Software Foundation; either version 2 * 0007 * of the License, or (at your option) any later version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, * 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0012 * GNU General Public License for more details. * 0013 * * 0014 * You should have received a copy of the GNU General Public License * 0015 * along with this program; if not, write to the Free Software * 0016 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 0017 *************************************************************************************/ 0018 0019 #include "explexer.h" 0020 #include "expressionparser.h" 0021 0022 #include <QDebug> 0023 #include <QCoreApplication> 0024 #include <QRegExp> 0025 0026 ExpLexer::ExpLexer(const QString &source) 0027 : AbstractLexer(source), m_pos(0) 0028 , m_realRx("^-?((\\.[0-9]+)|[0-9]+(\\.[0-9]+)?)(e-?[0-9]+)?", Qt::CaseSensitive, QRegExp::RegExp2) 0029 {} 0030 0031 QString ExpLexer::escape(const QString& str) 0032 { 0033 QString ret=str; 0034 ret.replace('&', QLatin1String("&")); 0035 ret.replace('<', QLatin1String("<")); 0036 ret.replace('>', QLatin1String(">")); 0037 ret.replace('\'', QLatin1String("'")); 0038 ret.replace('"', QLatin1String(""")); 0039 return ret; 0040 } 0041 0042 void ExpLexer::getToken() 0043 { 0044 int& pos=m_pos; 0045 const QString& a=m_source; 0046 for(; pos<a.length() && a[pos].isSpace(); pos++) {} 0047 0048 int oldpos=pos; 0049 TOKEN ret(-1, pos); 0050 0051 if(pos>=a.length()) { 0052 ret.type = ExpressionTable::EOF_SYMBOL; 0053 } else if(a.length()>pos+1 && a[pos]=='/' && a[pos+1]=='/') { 0054 ret.type=ExpressionTable::tComment; 0055 pos+=2; 0056 for(; a.length()>pos; pos++) { 0057 if((a.length()>pos+1 && a[pos]=='/' && a[pos+1]=='/') || a[pos]=='\n') { 0058 pos+= a[pos]=='\n' ? 1 : 2; 0059 break; 0060 } 0061 } 0062 ret.val=a.mid(oldpos, pos-oldpos); 0063 } else if(a.length()>pos+1 && m_longOperators.contains(a.mid(pos, 2))) { 0064 ret.type=m_longOperators[a.mid(pos, 2)]; 0065 pos+=2; 0066 } else if(m_operators.contains(a[pos])) { 0067 ret.type=m_operators[a[pos]]; 0068 pos++; 0069 } else if(a[pos]=='"') { 0070 bool escaping=false; 0071 pos++; 0072 int posini=pos; 0073 0074 for(; pos<a.size() && (a[pos]!='"' || escaping); pos++) 0075 escaping=a[pos]=='\\'; 0076 0077 if(pos>=a.size()) 0078 m_err += QCoreApplication::tr("Unexpectedly arrived to the end of the input"); 0079 0080 ret.type=ExpressionTable::tString; 0081 ret.val="<cs>"+escape(a.mid(posini, pos-posini))+"</cs>"; 0082 pos++; 0083 } else if(a[pos].decompositionTag()==QChar::Super) { 0084 QString super; 0085 for(int i=pos; i<a.size() && a[i].decompositionTag()==QChar::Super; i++) { 0086 super+=a[i].decomposition()[0]; 0087 } 0088 pos+=super.size(); 0089 ret.type = ExpressionTable::tUniPow; 0090 ret.val = "<cn>"+super+"</cn>"; 0091 } else if(a[pos].isLetter()) { 0092 for(; pos<a.length() && (a[pos]=='_' || a[pos].isLetter() || (a[pos].isNumber() && a[pos].decompositionTag()==QChar::NoDecomposition)); pos++){ 0093 ret.val += a[pos]; 0094 } 0095 ret.type= ExpressionTable::tId; 0096 Q_ASSERT(!ret.val.isEmpty()); 0097 } else if(m_realRx.indexIn(a, pos, QRegExp::CaretAtOffset)==pos) { 0098 ret.val = m_realRx.cap(); 0099 0100 QString attrib; 0101 if(!m_realRx.cap(2).isEmpty() || !m_realRx.cap(3).isEmpty() || !m_realRx.cap(4).isEmpty()) 0102 attrib+=QLatin1String(" type='real'"); 0103 0104 Q_ASSERT(!ret.val.isEmpty()); 0105 0106 ret.val = QStringLiteral("<cn%1>%2</cn>").arg(attrib, ret.val); 0107 ret.type= ExpressionTable::tVal; 0108 0109 pos += m_realRx.matchedLength(); 0110 } else { 0111 ret.val=QString(); 0112 m_err=QCoreApplication::tr("Unknown token %1").arg(a[pos]); 0113 } 0114 ret.len = pos-oldpos; 0115 m_tokens.append(ret); 0116 0117 // printQueue(m_tokens); 0118 }