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