File indexing completed on 2024-04-28 03:40:41
0001 0002 #line 115 "exp.g" 0003 0004 /************************************************************************************* 0005 * Copyright (C) 2008 by Aleix Pol <aleixpol@kde.org> * 0006 * * 0007 * This program is free software; you can redistribute it and/or * 0008 * modify it under the terms of the GNU General Public License * 0009 * as published by the Free Software Foundation; either version 2 * 0010 * of the License, or (at your option) any later version. * 0011 * * 0012 * This program is distributed in the hope that it will be useful, * 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0015 * GNU General Public License for more details. * 0016 * * 0017 * You should have received a copy of the GNU General Public License * 0018 * along with this program; if not, write to the Free Software * 0019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 0020 *************************************************************************************/ 0021 0022 0023 #include "expressionparser.h" 0024 #include <QDebug> 0025 #include "abstractlexer.h" 0026 #include "operator.h" 0027 #include <QCoreApplication> 0028 0029 ExpressionParser::ExpressionParser() 0030 {} 0031 0032 ExpressionParser::~ExpressionParser() 0033 {} 0034 0035 QString funcToTag(const QString& name) 0036 { 0037 if(Analitza::Operator::toOperatorType(name)!=Analitza::Operator::none) 0038 return QStringLiteral("<%1 />").arg(name); 0039 else 0040 return "<ci type='function'>"+name+"</ci>"; 0041 } 0042 0043 void ExpressionParser::reallocateStack() 0044 { 0045 int size = m_stateStack.size(); 0046 if (size == 0) 0047 size = 128; 0048 else 0049 size <<= 1; 0050 0051 m_symStack.resize(size); 0052 m_stateStack.resize(size); 0053 } 0054 0055 bool ExpressionParser::parse(AbstractLexer *lexer) 0056 { 0057 const int INITIAL_STATE = 0; 0058 int yytoken = -1; 0059 0060 reallocateStack(); 0061 0062 m_tos = 0; 0063 m_stateStack[++m_tos] = INITIAL_STATE; 0064 0065 for(;;) { 0066 const int state = m_stateStack.at(m_tos); 0067 if (yytoken == -1 && - TERMINAL_COUNT != action_index [state]) { 0068 yytoken = lexer->lex(); 0069 while(yytoken==tComment) { 0070 //TODO: Add mathml comment 0071 m_comments.append(lexer->current.val); 0072 yytoken = lexer->lex(); 0073 } 0074 0075 if(!lexer->error().isEmpty()) { 0076 m_err += lexer->error(); 0077 return false; 0078 } 0079 } 0080 int act = t_action (state, yytoken); 0081 if (act == ACCEPT_STATE) 0082 return true; 0083 else if (act > 0) { 0084 if (++m_tos == m_stateStack.size()) 0085 reallocateStack(); 0086 m_stateStack[m_tos] = act; 0087 yytoken = -1; 0088 } else if (act < 0) { 0089 int r = - act - 1; 0090 0091 m_tos -= rhs [r]; 0092 act = m_stateStack.at(m_tos++); 0093 switch (r) { 0094 0095 #line 209 "exp.g" 0096 case 0: 0097 #line 210 "exp.g" 0098 case 1: 0099 #line 212 "exp.g" 0100 0101 case 2: 0102 m_exp = "<math>"+sym(1)+"</math>"; 0103 break; 0104 0105 #line 218 "exp.g" 0106 case 3: sym(1) = "<declare><ci>"+sym(1)+"</ci>"+sym(3)+"</declare>"; break; 0107 #line 221 "exp.g" 0108 case 4: 0109 #line 222 "exp.g" 0110 case 5: 0111 #line 223 "exp.g" 0112 case 6: 0113 #line 225 "exp.g" 0114 0115 case 7: 0116 sym(1) = lexer->current.val; 0117 break; 0118 0119 #line 234 "exp.g" 0120 0121 case 10: 0122 sym(1) = "<ci>"+sym(1)+"</ci>"; 0123 break; 0124 0125 #line 243 "exp.g" 0126 0127 case 13: 0128 sym(1) = "<apply><selector />"+sym(3)+sym(1)+"</apply>"; 0129 break; 0130 0131 #line 250 "exp.g" 0132 0133 case 14: 0134 sym(1) = sym(2); 0135 break; 0136 0137 #line 260 "exp.g" 0138 case 19: sym(1)=sym(2); break; 0139 #line 261 "exp.g" 0140 case 20: sym(1)=funcToTag(sym(1)); break; 0141 #line 263 "exp.g" 0142 case 21: sym(1) = "<apply>"+sym(1)+sym(2)+"</apply>"; break; 0143 #line 264 "exp.g" 0144 case 22: sym(1) = "<apply>"+sym(1)+sym(3)+"</apply>"; break; 0145 #line 265 "exp.g" 0146 case 23: sym(1) = "<apply>"+sym(1)+ "</apply>"; break; 0147 #line 267 "exp.g" 0148 case 24: sym(1) = "<apply>"+sym(3)+sym(1)+"</apply>"; break; 0149 #line 268 "exp.g" 0150 case 25: sym(1) = "<apply>"+sym(3)+sym(1)+"</apply>"; break; 0151 #line 275 "exp.g" 0152 0153 case 29: 0154 sym(1).prepend(sym(3)); 0155 break; 0156 0157 #line 282 "exp.g" 0158 0159 case 30: 0160 sym(1)=sym(3)+sym(5)+sym(1); 0161 break; 0162 0163 #line 289 "exp.g" 0164 0165 case 31: 0166 sym(1)=sym(3)+"<domainofapplication>"+sym(5)+"</domainofapplication>"+sym(1); 0167 break; 0168 0169 #line 297 "exp.g" 0170 0171 case 32: 0172 sym(1) = '<'+sym(1)+" />"; 0173 break; 0174 0175 #line 304 "exp.g" 0176 0177 case 33: 0178 sym(1) = '<'+sym(1)+'>'+sym(3)+"</"+sym(1)+'>'; 0179 break; 0180 0181 #line 312 "exp.g" 0182 0183 case 34: 0184 sym(1) = "<lambda>"+sym(1)+sym(3)+"</lambda>"; 0185 break; 0186 0187 #line 320 "exp.g" 0188 0189 case 35: 0190 sym(1) = "<apply><minus />"+sym(2)+"</apply>"; 0191 break; 0192 0193 #line 327 "exp.g" 0194 0195 case 36: 0196 sym(1) = "<otherwise>"+sym(2)+"</otherwise>"; 0197 break; 0198 0199 #line 334 "exp.g" 0200 case 37: sym(1) = "<apply><plus />" +sym(1)+sym(3)+"</apply>"; break; 0201 #line 335 "exp.g" 0202 case 38: sym(1) = "<apply><minus />" +sym(1)+sym(3)+"</apply>"; break; 0203 #line 336 "exp.g" 0204 case 39: sym(1) = "<apply><times />" +sym(1)+sym(3)+"</apply>"; break; 0205 #line 337 "exp.g" 0206 case 40: sym(1) = "<apply><divide />"+sym(1)+sym(3)+"</apply>"; break; 0207 #line 338 "exp.g" 0208 case 41: sym(1) = "<apply><power />" +sym(1)+sym(3)+"</apply>"; break; 0209 #line 339 "exp.g" 0210 case 42: sym(1) = "<apply><eq />" +sym(1)+sym(3)+"</apply>"; break; 0211 #line 340 "exp.g" 0212 case 43: sym(1) = "<apply><leq />" +sym(1)+sym(3)+"</apply>"; break; 0213 #line 341 "exp.g" 0214 case 44: sym(1) = "<apply><geq />" +sym(1)+sym(3)+"</apply>"; break; 0215 #line 342 "exp.g" 0216 case 45: sym(1) = "<apply><lt />" +sym(1)+sym(3)+"</apply>"; break; 0217 #line 343 "exp.g" 0218 case 46: sym(1) = "<apply><gt />" +sym(1)+sym(3)+"</apply>"; break; 0219 #line 344 "exp.g" 0220 case 47: sym(1) = "<apply><neq />" +sym(1)+sym(3)+"</apply>"; break; 0221 #line 345 "exp.g" 0222 case 48: sym(1) = "<apply><times />" +sym(1)+sym(2)+"</apply>"; break; 0223 #line 346 "exp.g" 0224 case 49: sym(1) = "<apply><power />" +sym(1)+sym(2)+"</apply>"; break; 0225 #line 348 "exp.g" 0226 case 50: sym(1) = "<piece>"+sym(3)+sym(1)+"</piece>"; break; 0227 #line 353 "exp.g" 0228 0229 case 52: 0230 sym(1) += sym(3); 0231 break; 0232 0233 #line 362 "exp.g" 0234 0235 case 54: 0236 sym(1) = sym(2); 0237 break; 0238 0239 #line 369 "exp.g" 0240 0241 case 55: 0242 sym(1) = "<bvar><ci>"+sym(1)+"</ci></bvar>"; 0243 break; 0244 0245 #line 376 "exp.g" 0246 0247 case 56: 0248 sym(1) += sym(3); 0249 break; 0250 0251 #line 383 "exp.g" 0252 0253 case 57: 0254 sym(1) += sym(3); 0255 break; 0256 0257 #line 390 "exp.g" 0258 0259 case 58: 0260 sym(1) = "<uplimit>"+sym(3)+"</uplimit><downlimit>"+sym(1)+"</downlimit>"; 0261 break; 0262 0263 #line 396 "exp.g" 0264 0265 } // switch 0266 m_stateStack[m_tos] = nt_action(act, lhs[r] - TERMINAL_COUNT); 0267 } else { 0268 int ers = state; 0269 int shifts = 0; 0270 int reduces = 0; 0271 int expected_tokens[3]; 0272 for (int tk = 0; tk < TERMINAL_COUNT; ++tk) { 0273 int k = t_action(ers, tk); 0274 0275 if (! k) 0276 continue; 0277 else if (k < 0) 0278 ++reduces; 0279 else if (spell[tk]) { 0280 if (shifts < 3) 0281 expected_tokens[shifts] = tk; 0282 ++shifts; 0283 } 0284 } 0285 0286 m_errorLineNumber = lexer->lineNumber(); 0287 int tokFoundType=lexer->current.type; 0288 QString error; 0289 0290 if (shifts && shifts<3) { 0291 QString tokFound(spell[tokFoundType]); 0292 QStringList expectedTokens; 0293 for (int s = 0; s < shifts; ++s) { 0294 expectedTokens += '\''+QLatin1String(spell[expected_tokens[s]])+'\''; 0295 } 0296 error=QCoreApplication::translate("error message", "Expected %1 instead of '%2'").arg(expectedTokens.join(QCoreApplication::tr(", ")), tokFound); 0297 } else if(tokFoundType==tLpr) { 0298 error=QCoreApplication::tr("Missing right parenthesis"); 0299 } else if(tokFoundType==tRpr || tokFoundType==tRcb) { 0300 error=QCoreApplication::tr("Unbalanced right parenthesis"); 0301 } else 0302 if(tokFoundType==tId) 0303 error=QCoreApplication::tr("Unexpected token identifier: %1").arg(lexer->current.val); 0304 else 0305 error=QCoreApplication::tr("Unexpected token %1").arg(spell[tokFoundType]); 0306 m_err.append(error); 0307 return false; 0308 } 0309 } 0310 0311 return false; 0312 } 0313