Warning, /education/analitza/analitza/exp.g is written in an unsupported language. File is not indexed.
0001 %parser ExpressionTable 0002 %decl expressionparser.h 0003 %impl expressionparser.cpp 0004 0005 %expect 0 0006 0007 --%token tAssoc "associative operator" 0008 %token tAdd "+" 0009 %token tSub "-" 0010 %token tMul "*" 0011 %token tAssig ":=" 0012 %token tLimits ".." 0013 %token tDiv "/" 0014 %token tPow "^" 0015 %token tUniPow "²" 0016 %token tId "identifier" 0017 %token tLambda "->" 0018 %token tQm "?" 0019 %token tComa "," 0020 %token tLpr "(" 0021 %token tRpr ")" 0022 %token tLcb "{" 0023 %token tRcb "}" 0024 %token tLsp "[" 0025 %token tRsp "]" 0026 %token tPipe "|" 0027 %token tVal "value" 0028 %token tEq "=" 0029 %token tLt "<" 0030 %token tGt ">" 0031 %token tLeq ">=" 0032 %token tGeq "<=" 0033 %token tNeq "!=" 0034 %token tColon ":" 0035 %token tAt "@" 0036 %token tComment "//Comment//" 0037 %token tString "abc" 0038 0039 0040 %left tComa 0041 %left tLambda 0042 %left otherwise_prec 0043 %left tQm 0044 %left tEq tNeq tLt tLeq tGt tGeq 0045 %left tSub tAdd 0046 %left tMul tDiv 0047 %left uminus_prec 0048 %left tPow 0049 %left tUniPow 0050 %left tPipe 0051 0052 %start Program 0053 0054 /: 0055 /************************************************************************************* 0056 * Copyright (C) 2008 by Aleix Pol <aleixpol@kde.org> * 0057 * * 0058 * This program is free software; you can redistribute it and/or * 0059 * modify it under the terms of the GNU General Public License * 0060 * as published by the Free Software Foundation; either version 2 * 0061 * of the License, or (at your option) any later version. * 0062 * * 0063 * This program is distributed in the hope that it will be useful, * 0064 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0065 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0066 * GNU General Public License for more details. * 0067 * * 0068 * You should have received a copy of the GNU General Public License * 0069 * along with this program; if not, write to the Free Software * 0070 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 0071 *************************************************************************************/ 0072 0073 #ifndef EXPRESSIONPARSER_H 0074 #define EXPRESSIONPARSER_H 0075 0076 #include <QtCore/QStringList> 0077 #include <QtCore/QVector> 0078 #include "expressiontable_p.h" 0079 #include "analitzaexport.h" 0080 class AbstractLexer; 0081 0082 class ANALITZA_EXPORT ExpressionParser : protected $table 0083 { 0084 public: 0085 ExpressionParser(); 0086 ~ExpressionParser(); 0087 0088 bool parse(AbstractLexer *lexer); 0089 0090 bool isCorrect() const { return m_err.isEmpty(); } 0091 int errorLineNumber() const { return m_errorLineNumber; } 0092 QStringList error() const { return m_err; } 0093 QString mathML() const { return m_exp; } 0094 QStringList comments() const { return m_comments; } 0095 0096 private: 0097 void reallocateStack(); 0098 0099 inline QString &sym(int index) 0100 { return m_symStack[m_tos + index - 1]; } 0101 0102 int m_tos; 0103 QVector<int> m_stateStack; 0104 QVector<QString> m_symStack; 0105 int m_errorLineNumber; 0106 QStringList m_err; 0107 QString m_exp; 0108 QStringList m_comments; 0109 }; 0110 0111 #endif 0112 0113 :/ 0114 0115 /. 0116 /************************************************************************************* 0117 * Copyright (C) 2008 by Aleix Pol <aleixpol@kde.org> * 0118 * * 0119 * This program is free software; you can redistribute it and/or * 0120 * modify it under the terms of the GNU General Public License * 0121 * as published by the Free Software Foundation; either version 2 * 0122 * of the License, or (at your option) any later version. * 0123 * * 0124 * This program is distributed in the hope that it will be useful, * 0125 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0126 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0127 * GNU General Public License for more details. * 0128 * * 0129 * You should have received a copy of the GNU General Public License * 0130 * along with this program; if not, write to the Free Software * 0131 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 0132 *************************************************************************************/ 0133 0134 0135 0136 #include <QtCore/QDebug> 0137 #include "expressionparser.h" 0138 #include "abstractlexer.h" 0139 #include "operator.h" 0140 #include <QCoreApplication> 0141 0142 ExpressionParser::ExpressionParser() 0143 {} 0144 0145 ExpressionParser::~ExpressionParser() 0146 {} 0147 0148 QString funcToTag(const QString& name) 0149 { 0150 if(Analitza::Operator::toOperatorType(name)!=Analitza::Operator::none) 0151 return QString("<%1 />").arg(name); 0152 else 0153 return "<ci type='function'>"+name+"</ci>"; 0154 } 0155 0156 void ExpressionParser::reallocateStack() 0157 { 0158 int size = m_stateStack.size(); 0159 if (size == 0) 0160 size = 128; 0161 else 0162 size <<= 1; 0163 0164 m_symStack.resize(size); 0165 m_stateStack.resize(size); 0166 } 0167 0168 bool ExpressionParser::parse(AbstractLexer *lexer) 0169 { 0170 const int INITIAL_STATE = 0; 0171 int yytoken = -1; 0172 0173 reallocateStack(); 0174 0175 m_tos = 0; 0176 m_stateStack[++m_tos] = INITIAL_STATE; 0177 0178 for(;;) { 0179 const int state = m_stateStack.at(m_tos); 0180 if (yytoken == -1 && - TERMINAL_COUNT != action_index [state]) { 0181 yytoken = lexer->lex(); 0182 while(yytoken==tComment) { 0183 //TODO: Add mathml comment 0184 m_comments.append(lexer->current.val); 0185 yytoken = lexer->lex(); 0186 } 0187 0188 if(!lexer->error().isEmpty()) { 0189 m_err += lexer->error(); 0190 return false; 0191 } 0192 } 0193 int act = t_action (state, yytoken); 0194 if (act == ACCEPT_STATE) 0195 return true; 0196 else if (act > 0) { 0197 if (++m_tos == m_stateStack.size()) 0198 reallocateStack(); 0199 m_stateStack[m_tos] = act; 0200 yytoken = -1; 0201 } else if (act < 0) { 0202 int r = - act - 1; 0203 0204 m_tos -= rhs [r]; 0205 act = m_stateStack.at(m_tos++); 0206 switch (r) { 0207 ./ 0208 0209 Program ::= ;/. case $rule_number: ./ 0210 Program ::= Declaration ;/. case $rule_number: ./ 0211 Program ::= Expression ; 0212 /. 0213 case $rule_number: 0214 m_exp = "<math>"+sym(1)+"</math>"; 0215 break; 0216 ./ 0217 0218 Declaration ::= Id tAssig Expression ; /. case $rule_number: sym(1) = "<declare><ci>"+sym(1)+"</ci>"+sym(3)+"</declare>"; break; ./ 0219 0220 -- primary 0221 Id ::= tId; /. case $rule_number: ./ 0222 String ::= tString; /. case $rule_number: ./ 0223 Number ::= tVal; /. case $rule_number: ./ 0224 UniPow ::= tUniPow; 0225 /. 0226 case $rule_number: 0227 sym(1) = lexer->current.val; 0228 break; 0229 ./ 0230 0231 Value ::= Number; 0232 Value ::= String; 0233 Value ::= Id; 0234 /. 0235 case $rule_number: 0236 sym(1) = "<ci>"+sym(1)+"</ci>"; 0237 break; 0238 ./ 0239 0240 PrimaryExpression ::= Value | BlockExpression; 0241 0242 SubscriptExpression ::= PrimaryExpressionExt tLsp Expression tRsp; --vect[2+2] 0243 /. 0244 case $rule_number: 0245 sym(1) = "<apply><selector />"+sym(3)+sym(1)+"</apply>"; 0246 break; 0247 ./ 0248 0249 PrimaryExpressionExt ::= tLpr Expression tRpr; 0250 /. 0251 case $rule_number: 0252 sym(1) = sym(2); 0253 break; 0254 ./ 0255 0256 PrimaryExpressionExt ::= PrimaryExpression | SubscriptExpression | FunctionCall; 0257 Expression ::= PrimaryExpressionExt; 0258 0259 -- function 0260 FunctionId ::= tLpr Expression tRpr; /. case $rule_number: sym(1)=sym(2); break; ./ 0261 FunctionId ::= Id; /. case $rule_number: sym(1)=funcToTag(sym(1)); break; ./ 0262 0263 Expression ::= FunctionId PrimaryExpression ; /. case $rule_number: sym(1) = "<apply>"+sym(1)+sym(2)+"</apply>"; break; ./ 0264 FunctionCall ::= FunctionId tLpr FBody tRpr ; /. case $rule_number: sym(1) = "<apply>"+sym(1)+sym(3)+"</apply>"; break; ./ 0265 FunctionCall ::= FunctionId tLpr tRpr ; /. case $rule_number: sym(1) = "<apply>"+sym(1)+ "</apply>"; break; ./ 0266 0267 PipedCall ::= Expression tPipe FunctionId; /. case $rule_number: sym(1) = "<apply>"+sym(3)+sym(1)+"</apply>"; break; ./ 0268 PipedCall ::= Expression tPipe LambdaExpression; /. case $rule_number: sym(1) = "<apply>"+sym(3)+sym(1)+"</apply>"; break; ./ 0269 Expression ::= PipedCall | LambdaExpression; 0270 0271 -- function's body 0272 FBody ::= Parameters ; 0273 0274 FBody ::= Parameters tColon BVars; 0275 /. 0276 case $rule_number: 0277 sym(1).prepend(sym(3)); 0278 break; 0279 ./ 0280 0281 FBody ::= Parameters tColon BVars tEq Limits; 0282 /. 0283 case $rule_number: 0284 sym(1)=sym(3)+sym(5)+sym(1); 0285 break; 0286 ./ 0287 0288 FBody ::= Parameters tColon BVars tAt Expression; 0289 /. 0290 case $rule_number: 0291 sym(1)=sym(3)+"<domainofapplication>"+sym(5)+"</domainofapplication>"+sym(1); 0292 break; 0293 ./ 0294 0295 -- block 0296 BlockExpression ::= Id tLcb tRcb ; 0297 /. 0298 case $rule_number: 0299 sym(1) = '<'+sym(1)+" />"; 0300 break; 0301 ./ 0302 0303 BlockExpression ::= Id tLcb Parameters tRcb ; 0304 /. 0305 case $rule_number: 0306 sym(1) = '<'+sym(1)+'>'+sym(3)+"</"+sym(1)+'>'; 0307 break; 0308 ./ 0309 0310 -- lambda 0311 LambdaExpression ::= BVars tLambda Expression ; 0312 /. 0313 case $rule_number: 0314 sym(1) = "<lambda>"+sym(1)+sym(3)+"</lambda>"; 0315 break; 0316 ./ 0317 0318 -- unary constructions 0319 Expression ::= tSub Expression %prec uminus_prec ; 0320 /. 0321 case $rule_number: 0322 sym(1) = "<apply><minus />"+sym(2)+"</apply>"; 0323 break; 0324 ./ 0325 0326 Expression ::= tQm Expression %prec otherwise_prec ; 0327 /. 0328 case $rule_number: 0329 sym(1) = "<otherwise>"+sym(2)+"</otherwise>"; 0330 break; 0331 ./ 0332 0333 -- binary constructions 0334 Expression ::= Expression tAdd Expression ; /. case $rule_number: sym(1) = "<apply><plus />" +sym(1)+sym(3)+"</apply>"; break; ./ 0335 Expression ::= Expression tSub Expression ; /. case $rule_number: sym(1) = "<apply><minus />" +sym(1)+sym(3)+"</apply>"; break; ./ 0336 Expression ::= Expression tMul Expression ; /. case $rule_number: sym(1) = "<apply><times />" +sym(1)+sym(3)+"</apply>"; break; ./ 0337 Expression ::= Expression tDiv Expression ; /. case $rule_number: sym(1) = "<apply><divide />"+sym(1)+sym(3)+"</apply>"; break; ./ 0338 Expression ::= Expression tPow Expression ; /. case $rule_number: sym(1) = "<apply><power />" +sym(1)+sym(3)+"</apply>"; break; ./ 0339 Expression ::= Expression tEq Expression ; /. case $rule_number: sym(1) = "<apply><eq />" +sym(1)+sym(3)+"</apply>"; break; ./ 0340 Expression ::= Expression tLeq Expression ; /. case $rule_number: sym(1) = "<apply><leq />" +sym(1)+sym(3)+"</apply>"; break; ./ 0341 Expression ::= Expression tGeq Expression ; /. case $rule_number: sym(1) = "<apply><geq />" +sym(1)+sym(3)+"</apply>"; break; ./ 0342 Expression ::= Expression tLt Expression ; /. case $rule_number: sym(1) = "<apply><lt />" +sym(1)+sym(3)+"</apply>"; break; ./ 0343 Expression ::= Expression tGt Expression ; /. case $rule_number: sym(1) = "<apply><gt />" +sym(1)+sym(3)+"</apply>"; break; ./ 0344 Expression ::= Expression tNeq Expression ; /. case $rule_number: sym(1) = "<apply><neq />" +sym(1)+sym(3)+"</apply>"; break; ./ 0345 Expression ::= Number PrimaryExpressionExt; /. case $rule_number: sym(1) = "<apply><times />" +sym(1)+sym(2)+"</apply>"; break; ./ 0346 Expression ::= Expression UniPow; /. case $rule_number: sym(1) = "<apply><power />" +sym(1)+sym(2)+"</apply>"; break; ./ 0347 0348 Expression ::= Expression tQm Expression ; /. case $rule_number: sym(1) = "<piece>"+sym(3)+sym(1)+"</piece>"; break; ./ 0349 0350 -- parameters 0351 Parameters ::= Expression ; 0352 Parameters ::= Parameters tComa Expression ; 0353 /. 0354 case $rule_number: 0355 sym(1) += sym(3); 0356 break; 0357 ./ 0358 0359 -- bvars 0360 BVars ::= BValue; 0361 BVars ::= tLpr BVarList tRpr ; 0362 /. 0363 case $rule_number: 0364 sym(1) = sym(2); 0365 break; 0366 ./ 0367 0368 BValue ::= Id; 0369 /. 0370 case $rule_number: 0371 sym(1) = "<bvar><ci>"+sym(1)+"</ci></bvar>"; 0372 break; 0373 ./ 0374 0375 BVarList ::= BValue tComa BValue; 0376 /. 0377 case $rule_number: 0378 sym(1) += sym(3); 0379 break; 0380 ./ 0381 0382 BVarList ::= BVarList tComa BValue; 0383 /. 0384 case $rule_number: 0385 sym(1) += sym(3); 0386 break; 0387 ./ 0388 0389 Limits ::= PrimaryExpressionExt tLimits PrimaryExpressionExt; 0390 /. 0391 case $rule_number: 0392 sym(1) = "<uplimit>"+sym(3)+"</uplimit><downlimit>"+sym(1)+"</downlimit>"; 0393 break; 0394 ./ 0395 0396 /. 0397 } // switch 0398 m_stateStack[m_tos] = nt_action(act, lhs[r] - TERMINAL_COUNT); 0399 } else { 0400 int ers = state; 0401 int shifts = 0; 0402 int reduces = 0; 0403 int expected_tokens[3]; 0404 for (int tk = 0; tk < TERMINAL_COUNT; ++tk) { 0405 int k = t_action(ers, tk); 0406 0407 if (! k) 0408 continue; 0409 else if (k < 0) 0410 ++reduces; 0411 else if (spell[tk]) { 0412 if (shifts < 3) 0413 expected_tokens[shifts] = tk; 0414 ++shifts; 0415 } 0416 } 0417 0418 m_errorLineNumber = lexer->lineNumber(); 0419 int tokFoundType=lexer->current.type; 0420 QString error; 0421 0422 if (shifts && shifts<3) { 0423 QString tokFound(spell[tokFoundType]); 0424 QStringList expectedTokens; 0425 for (int s = 0; s < shifts; ++s) { 0426 expectedTokens += '\''+QLatin1String(spell[expected_tokens[s]])+'\''; 0427 } 0428 error=QCoreApplication::translate("error message", "Expected %1 instead of '%2'").arg(expectedTokens.join(QCoreApplication::tr(", ")), tokFound); 0429 } else if(tokFoundType==tLpr) { 0430 error=QCoreApplication::tr("Missing right parenthesis"); 0431 } else if(tokFoundType==tRpr || tokFoundType==tRcb) { 0432 error=QCoreApplication::tr("Unbalanced right parenthesis"); 0433 } else 0434 if(tokFoundType==tId) 0435 error=QCoreApplication::tr("Unexpected token identifier: %1").arg(lexer->current.val); 0436 else 0437 error=QCoreApplication::tr("Unexpected token %1").arg(spell[tokFoundType]); 0438 m_err.append(error); 0439 return false; 0440 } 0441 } 0442 0443 return false; 0444 } 0445 0446 ./