1
/*************************************************************************************
2
* Copyright (C) 2008 by Aleix Pol <aleixpol@kde.org> *
4
* This program is free software; you can redistribute it and/or *
5
* modify it under the terms of the GNU General Public License *
6
* as published by the Free Software Foundation; either version 2 *
7
* of the License, or (at your option) any later version. *
9
* This program is distributed in the hope that it will be useful, *
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12
* GNU General Public License for more details. *
14
* You should have received a copy of the GNU General Public License *
15
* along with this program; if not, write to the Free Software *
16
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA *
17
*************************************************************************************/
20
#include "expressionparser.h"
21
#include <KLocalizedString>
24
ExpLexer::ExpLexer(const QString &source)
25
: AbstractLexer(source), m_pos(0)
26
, m_realRx("^-?((\\.[0-9]+)|[0-9]+(\\.[0-9]+)?)(e-?[0-9]+)?", Qt::CaseSensitive, QRegExp::RegExp2)
29
QString ExpLexer::escape(const QString& str)
32
ret.replace('&', "&");
33
ret.replace('<', "<");
34
ret.replace('>', ">");
35
ret.replace('\'', "'");
36
ret.replace('"', """);
40
void ExpLexer::getToken()
43
const QString& a=m_source;
44
for(; pos<a.length() && a[pos].isSpace(); pos++) {}
50
ret.type = ExpressionTable::EOF_SYMBOL;
51
} else if(a.length()>pos+1 && a[pos]=='/' && a[pos+1]=='/') {
52
ret.type=ExpressionTable::tComment;
54
for(; a.length()>pos; pos++) {
55
if((a.length()>pos+1 && a[pos]=='/' && a[pos+1]=='/') || a[pos]=='\n') {
56
pos+= a[pos]=='\n' ? 1 : 2;
60
ret.val=a.mid(oldpos, pos-oldpos);
61
} else if(a.length()>pos+1 && m_longOperators.contains(a.mid(pos, 2))) {
62
ret.type=m_longOperators[a.mid(pos, 2)];
64
} else if(m_operators.contains(a[pos])) {
65
ret.type=m_operators[a[pos]];
67
} else if(a[pos]=='"') {
72
for(; pos<a.size() && (a[pos]!='"' || escaping); pos++)
73
escaping=a[pos]=='\\';
76
m_err += i18n("Unexpectedly arrived to the end of the input");
78
ret.type=ExpressionTable::tString;
79
ret.val="<cs>"+escape(a.mid(posini, pos-posini))+"</cs>";
81
} else if(a[pos].decompositionTag()==QChar::Super) {
83
for(int i=pos; i<a.count() && a[i].decompositionTag()==QChar::Super; i++) {
84
ret.type = ExpressionTable::tPow;
85
super+=a[i].decomposition()[0];
89
m_tokens.append(TOKEN(ExpressionTable::tPow, pos, QString(), 0));
90
ret=TOKEN(ExpressionTable::tVal, oldpos, "<cn>"+super+"</cn>", pos-oldpos);
91
} else if(a[pos].isLetter()) {
92
for(; pos<a.length() && (a[pos]=='_' || a[pos].isLetter() || (a[pos].isNumber() && a[pos].decompositionTag()==QChar::NoDecomposition)); pos++){
95
ret.type= ExpressionTable::tId;
96
Q_ASSERT(!ret.val.isEmpty());
97
} else if(m_realRx.indexIn(a, pos, QRegExp::CaretAtOffset)==pos) {
98
ret.val = m_realRx.cap();
101
if(!m_realRx.cap(2).isEmpty() || !m_realRx.cap(3).isEmpty() || !m_realRx.cap(4).isEmpty())
102
attrib+=" type='real'";
104
Q_ASSERT(!ret.val.isEmpty());
106
ret.val = QString("<cn%1>%2</cn>").arg(attrib).arg(ret.val);
107
ret.type= ExpressionTable::tVal;
109
pos += m_realRx.matchedLength();
112
m_err=i18n("Unknown token %1", a[pos]);
114
ret.len = pos-oldpos;
115
m_tokens.append(ret);
117
// printQueue(m_tokens);