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 ./