File indexing completed on 2024-04-28 05:49:44

0001 /*
0002     SPDX-FileCopyrightText: 2023 Gabriel Barrantes <gabriel.barrantes.dev@outlook.com>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "kcalc_parser.h"
0007 #include "kcalc_token.h"
0008 #include "knumber/knumber.h"
0009 
0010 #include <QDebug>
0011 #include <QDomDocument>
0012 #include <QLocale>
0013 #include <QQueue>
0014 #include <QRegularExpression>
0015 #include <QRegularExpressionMatch>
0016 #include <QString>
0017 
0018 //------------------------------------------------------------------------------
0019 // Name: KCalcParser
0020 // Desc: constructor
0021 //------------------------------------------------------------------------------
0022 KCalcParser::KCalcParser()
0023 {
0024 }
0025 
0026 //------------------------------------------------------------------------------
0027 // Name: ~KCalcParser
0028 // Desc: destructor
0029 //------------------------------------------------------------------------------
0030 KCalcParser::~KCalcParser() = default;
0031 
0032 //------------------------------------------------------------------------------
0033 // Name: stringToToken
0034 // Desc: tries to find a valid token starting at index
0035 //------------------------------------------------------------------------------
0036 KCalcToken::TokenCode KCalcParser::stringToToken(const QString &buffer, int &index, int base)
0037 {
0038     qDebug() << "Converting string to Token ";
0039 
0040     int maxTokenLength = (index + 5 > buffer.size()) ? buffer.size() - index : 5;
0041     QString s = buffer.sliced(index, maxTokenLength);
0042 
0043     // TODO: change this to be switch table on the first char
0044     if (s.startsWith(SPACE_STR) || s.startsWith(THIN_SPACE_STR)) {
0045         index++;
0046         return KCalcToken::TokenCode::STUB;
0047     }
0048 
0049     if (s.startsWith(HEX_NUMBER_PREFIX_STR)) {
0050         QRegularExpressionMatch match;
0051         int numIndex = buffer.indexOf(QRegularExpression(QLatin1String("0x[0-9A-F]{1,}")), index, &match);
0052         if (numIndex == index) {
0053             token_KNumber_ = match.captured();
0054             if (match.captured().size() > 16) {
0055                 return KCalcToken::TokenCode::INVALID_TOKEN;
0056             }
0057             index += match.captured().size();
0058             return KCalcToken::TokenCode::KNUMBER;
0059         } else {
0060             return KCalcToken::TokenCode::INVALID_TOKEN;
0061         }
0062     }
0063 
0064     if (s.startsWith(BINARY_NUMBER_PREFIX_STR)) {
0065         QRegularExpressionMatch match;
0066         int numIndex = buffer.indexOf(QRegularExpression(QLatin1String("0b[0-1]{1,}")), index, &match);
0067         if (numIndex == index) {
0068             token_KNumber_ = match.captured();
0069             if (match.captured().size() > 64) {
0070                 return KCalcToken::TokenCode::INVALID_TOKEN;
0071             }
0072             index += match.captured().size();
0073             return KCalcToken::TokenCode::KNUMBER;
0074         } else {
0075             return KCalcToken::TokenCode::INVALID_TOKEN;
0076         }
0077     }
0078 
0079     if (s.startsWith(OCTAL_NUMBER_PREFIX_STR)) {
0080         QRegularExpressionMatch match;
0081         int numIndex = buffer.indexOf(QRegularExpression(QLatin1String("0[0-7]{1,}")), index, &match);
0082         if (numIndex == index) {
0083             token_KNumber_ = match.captured();
0084             if (match.captured().size() > 21) {
0085                 return KCalcToken::TokenCode::INVALID_TOKEN;
0086             }
0087             index += match.captured().size();
0088             return KCalcToken::TokenCode::KNUMBER;
0089         }
0090         // Code execution continues, since an entry could
0091         // start with a 0 but not be a valid octal number
0092         // being a number in base 10 or 16
0093     }
0094 
0095     if ((A_STR <= s.first(1) && s.first(1) <= F_STR) || (ZERO_STR <= s.first(1) && s.first(1) <= NINE_STR)) {
0096         int numIndex;
0097         QRegularExpressionMatch match;
0098         switch (base) {
0099         case 2:
0100             numIndex = buffer.indexOf(QRegularExpression(QLatin1String("[0-1]{1,}")), index, &match);
0101             token_KNumber_ = BINARY_NUMBER_PREFIX_STR;
0102             break;
0103         case 8:
0104             numIndex = buffer.indexOf(QRegularExpression(QLatin1String("[0-7]{1,21}")), index, &match);
0105             token_KNumber_ = OCTAL_NUMBER_PREFIX_STR;
0106             break;
0107         case 10:
0108             numIndex = buffer.indexOf(QRegularExpression(QLatin1String("(\\d+)([.,]\\d*)?(e([+-]?\\d+))?")), index, &match);
0109             token_KNumber_.clear();
0110             break;
0111         case 16:
0112             numIndex = buffer.indexOf(QRegularExpression(QLatin1String("[0-9A-F]{1,16}")), index, &match);
0113             token_KNumber_ = HEX_NUMBER_PREFIX_STR;
0114             break;
0115         default:
0116             break;
0117         }
0118         if (numIndex == index) {
0119             token_KNumber_ += match.captured();
0120             index += match.captured().size();
0121             return KCalcToken::TokenCode::KNUMBER;
0122         } else {
0123             return KCalcToken::TokenCode::INVALID_TOKEN;
0124         }
0125     }
0126 
0127     if (s.startsWith(PLUS_STR)) {
0128         index++;
0129         return KCalcToken::TokenCode::PLUS;
0130     }
0131     if (s.startsWith(HYPHEN_MINUS_STR) || s.startsWith(MINUS_SIGN_STR)) {
0132         index++;
0133         return KCalcToken::TokenCode::MINUS;
0134     }
0135     if (s.startsWith(EQUAL_STR)) {
0136         index++;
0137         return KCalcToken::TokenCode::EQUAL;
0138     }
0139     if (s.startsWith(SQUARE_STR)) {
0140         index++;
0141         return KCalcToken::TokenCode::SQUARE;
0142     }
0143     if (s.startsWith(CUBE_STR)) {
0144         index++;
0145         return KCalcToken::TokenCode::CUBE;
0146     }
0147     if (s.startsWith(POWER_STR)) {
0148         index++;
0149         return KCalcToken::TokenCode::POWER;
0150     }
0151     if (s.startsWith(POWER_ROOT_STR)) {
0152         index++;
0153         return KCalcToken::TokenCode::POWER_ROOT;
0154     }
0155     if (s.startsWith(EXP_10_STR)) {
0156         index++;
0157         return KCalcToken::TokenCode::EXP_10;
0158     }
0159     if (s.startsWith(PERCENTAGE_STR)) {
0160         index++;
0161         return KCalcToken::TokenCode::PERCENTAGE;
0162     }
0163     if (s.startsWith(PERMILLE_STR)) {
0164         index++;
0165         return KCalcToken::TokenCode::PERMILLE;
0166     }
0167     if (s.startsWith(I_STR)) {
0168         index++;
0169         return KCalcToken::TokenCode::I;
0170     }
0171     if (s.startsWith(DIVISION_STR) || s.startsWith(SLASH_STR) || s.startsWith(DIVISION_SLASH_STR)) {
0172         index++;
0173         return KCalcToken::TokenCode::DIVISION;
0174     }
0175     if (s.startsWith(GAMMA_STR)) {
0176         index++;
0177         return KCalcToken::TokenCode::GAMMA;
0178     }
0179     if (s.startsWith(SQUARE_ROOT_STR)) {
0180         index++;
0181         return KCalcToken::TokenCode::SQUARE_ROOT;
0182     }
0183     if (s.startsWith(OPENING_PARENTHESIS_STR)) {
0184         index++;
0185         return KCalcToken::TokenCode::OPENING_PARENTHESIS;
0186     }
0187     if (s.startsWith(CLOSING_PARENTHESIS_STR)) {
0188         index++;
0189         return KCalcToken::TokenCode::CLOSING_PARENTHESIS;
0190     }
0191     if (s.startsWith(INVERT_SIGN_STR)) {
0192         index++;
0193         return KCalcToken::TokenCode::INVERT_SIGN;
0194     }
0195 
0196     if (s.startsWith(MULTIPLICATION_STR) || s.startsWith(DOT_STR) || s.startsWith(ASTERISK_STR)) {
0197         index++;
0198         return KCalcToken::TokenCode::MULTIPLICATION;
0199     }
0200 
0201     if (s.startsWith(DEGREE_STR)) {
0202         index++;
0203         return KCalcToken::TokenCode::DEGREE;
0204     }
0205     if (s.startsWith(AND_STR)) {
0206         index++;
0207         return KCalcToken::TokenCode::AND;
0208     }
0209     if (s.startsWith(OR_STR)) {
0210         index++;
0211         return KCalcToken::TokenCode::OR;
0212     }
0213     if (s.startsWith(XOR_STR)) {
0214         index++;
0215         return KCalcToken::TokenCode::XOR;
0216     }
0217 
0218     if (s.startsWith(ASINH_STR)) {
0219         index += 5;
0220         return KCalcToken::TokenCode::ASINH;
0221     }
0222     if (s.startsWith(ACOSH_STR)) {
0223         index += 5;
0224         return KCalcToken::TokenCode::ACOSH;
0225     }
0226     if (s.startsWith(ATANH_STR)) {
0227         index += 5;
0228         return KCalcToken::TokenCode::ATANH;
0229     }
0230 
0231     if (s.startsWith(ASIN_STR)) {
0232         index += 4;
0233         switch (trigonometric_Mode_) {
0234         case RADIANS:
0235             return KCalcToken::TokenCode::ASIN_RAD;
0236             break;
0237         case GRADIANS:
0238             return KCalcToken::TokenCode::ASIN_GRAD;
0239             break;
0240         case DEGREES:
0241             return KCalcToken::TokenCode::ASIN_DEG;
0242             break;
0243         default:
0244             break;
0245         }
0246     }
0247     if (s.startsWith(ACOS_STR)) {
0248         index += 4;
0249         switch (trigonometric_Mode_) {
0250         case RADIANS:
0251             return KCalcToken::TokenCode::ACOS_RAD;
0252             break;
0253         case GRADIANS:
0254             return KCalcToken::TokenCode::ACOS_GRAD;
0255             break;
0256         case DEGREES:
0257             return KCalcToken::TokenCode::ACOS_DEG;
0258             break;
0259         default:
0260             break;
0261         }
0262     }
0263     if (s.startsWith(ATAN_STR)) {
0264         index += 4;
0265         switch (trigonometric_Mode_) {
0266         case RADIANS:
0267             return KCalcToken::TokenCode::ATAN_RAD;
0268             break;
0269         case GRADIANS:
0270             return KCalcToken::TokenCode::ATAN_GRAD;
0271             break;
0272         case DEGREES:
0273             return KCalcToken::TokenCode::ATAN_DEG;
0274             break;
0275         default:
0276             break;
0277         }
0278     }
0279 
0280     if (s.startsWith(SINH_STR)) {
0281         index += 4;
0282         return KCalcToken::TokenCode::SINH;
0283     }
0284     if (s.startsWith(COSH_STR)) {
0285         index += 4;
0286         return KCalcToken::TokenCode::COSH;
0287     }
0288     if (s.startsWith(TANH_STR)) {
0289         index += 4;
0290         return KCalcToken::TokenCode::TANH;
0291     }
0292 
0293     if (s.startsWith(SIN_STR)) {
0294         index += 3;
0295         switch (trigonometric_Mode_) {
0296         case RADIANS:
0297             return KCalcToken::TokenCode::SIN_RAD;
0298             break;
0299         case GRADIANS:
0300             return KCalcToken::TokenCode::SIN_GRAD;
0301             break;
0302         case DEGREES:
0303             return KCalcToken::TokenCode::SIN_DEG;
0304             break;
0305         default:
0306             break;
0307         }
0308     }
0309     if (s.startsWith(COS_STR)) {
0310         index += 3;
0311         switch (trigonometric_Mode_) {
0312         case RADIANS:
0313             return KCalcToken::TokenCode::COS_RAD;
0314             break;
0315         case GRADIANS:
0316             return KCalcToken::TokenCode::COS_GRAD;
0317             break;
0318         case DEGREES:
0319             return KCalcToken::TokenCode::COS_DEG;
0320             break;
0321         default:
0322             break;
0323         }
0324     }
0325     if (s.startsWith(TAN_STR)) {
0326         index += 3;
0327         switch (trigonometric_Mode_) {
0328         case RADIANS:
0329             return KCalcToken::TokenCode::TAN_RAD;
0330             break;
0331         case GRADIANS:
0332             return KCalcToken::TokenCode::TAN_GRAD;
0333             break;
0334         case DEGREES:
0335             return KCalcToken::TokenCode::TAN_DEG;
0336             break;
0337         default:
0338             break;
0339         }
0340     }
0341 
0342     if (s.startsWith(EXP_STR)) {
0343         index += 3;
0344         return KCalcToken::TokenCode::EXP;
0345     }
0346 
0347     if (s.startsWith(LOG_10_STR)) {
0348         index += 3;
0349         return KCalcToken::TokenCode::LOG_10;
0350     }
0351 
0352     if (s.startsWith(ANS_STR)) {
0353         index += 3;
0354         return KCalcToken::TokenCode::ANS;
0355     }
0356 
0357     if (s.startsWith(BINOMIAL_STR)) {
0358         index += 3;
0359         return KCalcToken::TokenCode::BINOMIAL;
0360     }
0361 
0362     if (s.startsWith(MODULO_STR)) {
0363         index += 3;
0364         return KCalcToken::TokenCode::MODULO;
0365     }
0366 
0367     if (s.startsWith(INTEGER_DIVISION_STR)) {
0368         index += 3;
0369         return KCalcToken::TokenCode::INTEGER_DIVISION;
0370     }
0371 
0372     if (s.startsWith(GRADIAN_STR)) {
0373         index += 3;
0374         return KCalcToken::TokenCode::GRADIAN;
0375     }
0376 
0377     if (s.startsWith(RADIAN_STR)) {
0378         index += 3;
0379         return KCalcToken::TokenCode::RADIAN;
0380     }
0381 
0382     if (s.startsWith(RSH_STR)) {
0383         index += 2;
0384         return KCalcToken::TokenCode::RSH;
0385     }
0386     if (s.startsWith(LSH_STR)) {
0387         index += 2;
0388         return KCalcToken::TokenCode::LSH;
0389     }
0390     if (s.startsWith(TWO_S_COMP_STR)) {
0391         index += 2;
0392         return KCalcToken::TokenCode::TWO_S_COMPLEMENT;
0393     }
0394 
0395     if (s.startsWith(RECIPROCAL_STR)) {
0396         index += 2;
0397         return KCalcToken::TokenCode::RECIPROCAL;
0398     }
0399     if (s.startsWith(LN_STR)) {
0400         index += 2;
0401         return KCalcToken::TokenCode::LN;
0402     }
0403 
0404     if (index + 2 <= buffer.size()) {
0405         s = buffer.sliced(index, 2);
0406         if (constantSymbolToValue_(s)) {
0407             index += 2;
0408             return KCalcToken::TokenCode::KNUMBER;
0409         }
0410     }
0411     if (s.startsWith(ONE_S_COMP_STR)) {
0412         index++;
0413         return KCalcToken::TokenCode::ONE_S_COMPLEMENT;
0414     }
0415     if (s.startsWith(FACTORIAL_STR)) {
0416         index++;
0417         return KCalcToken::TokenCode::FACTORIAL;
0418     }
0419     if (s.startsWith(DOUBLE_FACTORIAL_STR)) {
0420         index++;
0421         return KCalcToken::TokenCode::DOUBLE_FACTORIAL;
0422     }
0423 
0424     s = buffer.sliced(index, 1);
0425 
0426     if (constantSymbolToValue_(s)) {
0427         index++;
0428         return KCalcToken::TokenCode::KNUMBER;
0429     }
0430 
0431     parsing_Result_ = INVALID_TOKEN;
0432     return KCalcToken::TokenCode::INVALID_TOKEN;
0433 }
0434 
0435 //------------------------------------------------------------------------------
0436 // Name: stringToTokenQueue
0437 // Desc: parses string into the token Queue
0438 //------------------------------------------------------------------------------
0439 int KCalcParser::stringToTokenQueue(const QString &buffer, int base, QQueue<KCalcToken> &tokenQueue, int &errorIndex)
0440 {
0441     tokenQueue.clear();
0442     int buffer_index = 0;
0443     int buffer_size = buffer.size();
0444     qDebug() << "Parsing string to TokenQueue";
0445     qDebug() << "Buffer string to parse: " << buffer;
0446 
0447     KCalcToken::TokenCode tokenCode = KCalcToken::TokenCode::INVALID_TOKEN;
0448 
0449     if (buffer_size == 0) {
0450         errorIndex = -1;
0451         parsing_Result_ = EMPTY;
0452         return -1;
0453     }
0454 
0455     while (buffer_index < buffer_size) {
0456         tokenCode = KCalcToken::TokenCode::INVALID_TOKEN;
0457         KNumber operand;
0458 
0459         tokenCode = stringToToken(buffer, buffer_index, base);
0460 
0461         if (tokenCode == KCalcToken::TokenCode::INVALID_TOKEN) {
0462             parsing_Result_ = INVALID_TOKEN;
0463             errorIndex = buffer_index; // this indicates where the error was found
0464             return -1; // in the input string
0465         }
0466 
0467         if (tokenCode == KCalcToken::TokenCode::STUB) {
0468             continue;
0469         }
0470 
0471         if (tokenCode == KCalcToken::TokenCode::KNUMBER) {
0472             qDebug() << "String KNumber converted: " << token_KNumber_;
0473             token_KNumber_.replace(COMMA_STR, KNumber::decimalSeparator());
0474             token_KNumber_.replace(POINT_STR, KNumber::decimalSeparator());
0475             operand = KNumber(token_KNumber_);
0476 
0477             tokenQueue.enqueue(KCalcToken(operand, buffer_index));
0478         } else {
0479             tokenQueue.enqueue(KCalcToken(tokenCode, buffer_index));
0480             qDebug() << "KCalcToken converted with code: " << tokenCode;
0481         }
0482 
0483         qDebug() << "Parsing index after this previous step: " << buffer_index;
0484     }
0485 
0486     qDebug() << "Parsing done, index after parsing: " << buffer_index;
0487     parsing_Result_ = SUCCESS;
0488     return 0;
0489 }
0490 
0491 //------------------------------------------------------------------------------
0492 // Name: setTrigonometricMode
0493 // Desc:
0494 //------------------------------------------------------------------------------
0495 void KCalcParser::setTrigonometricMode(int mode)
0496 {
0497     trigonometric_Mode_ = mode;
0498 }
0499 
0500 //------------------------------------------------------------------------------
0501 // Name: getTrigonometricMode
0502 // Desc:
0503 //------------------------------------------------------------------------------
0504 int KCalcParser::getTrigonometricMode()
0505 {
0506     return trigonometric_Mode_;
0507 }
0508 
0509 //------------------------------------------------------------------------------
0510 // Name: getParsingResult
0511 // Desc:
0512 //------------------------------------------------------------------------------
0513 KCalcParser::ParsingResult KCalcParser::getParsingResult()
0514 {
0515     return parsing_Result_;
0516 }
0517 
0518 //------------------------------------------------------------------------------
0519 // Name: TokenToString
0520 // Desc:
0521 //------------------------------------------------------------------------------
0522 const QString KCalcParser::TokenToString(KCalcToken::TokenCode tokenCode)
0523 {
0524     switch (tokenCode) {
0525     case KCalcToken::TokenCode::DECIMAL_POINT:
0526         return DECIMAL_POINT_STR;
0527         break;
0528     case KCalcToken::TokenCode::PLUS:
0529         return PLUS_STR;
0530         break;
0531     case KCalcToken::TokenCode::MINUS:
0532         return HYPHEN_MINUS_STR;
0533         break;
0534     case KCalcToken::TokenCode::DIVISION:
0535         return DIVISION_STR;
0536         break;
0537     case KCalcToken::TokenCode::SLASH:
0538         return SLASH_STR;
0539         break;
0540     case KCalcToken::TokenCode::MULTIPLICATION:
0541         return MULTIPLICATION_STR;
0542         break;
0543     case KCalcToken::TokenCode::DOT:
0544         return DOT_STR;
0545         break;
0546     case KCalcToken::TokenCode::ASTERISK:
0547         return ASTERISK_STR;
0548         break;
0549     case KCalcToken::TokenCode::PERCENTAGE:
0550         return PERCENTAGE_STR;
0551         break;
0552     case KCalcToken::TokenCode::OPENING_PARENTHESIS:
0553         return OPENING_PARENTHESIS_STR;
0554         break;
0555     case KCalcToken::TokenCode::CLOSING_PARENTHESIS:
0556         return CLOSING_PARENTHESIS_STR;
0557         break;
0558     case KCalcToken::TokenCode::SQUARE:
0559         return SQUARE_STR;
0560         break;
0561     case KCalcToken::TokenCode::CUBE:
0562         return CUBE_STR;
0563         break;
0564     case KCalcToken::TokenCode::SQUARE_ROOT:
0565         return SQUARE_ROOT_STR;
0566         break;
0567     case KCalcToken::TokenCode::CUBIC_ROOT:
0568         return CUBIC_ROOT_STR;
0569         break;
0570     case KCalcToken::TokenCode::DEGREE:
0571         return DEGREE_STR;
0572         break;
0573     case KCalcToken::TokenCode::GRADIAN:
0574         return GRADIAN_STR;
0575         break;
0576     case KCalcToken::TokenCode::RADIAN:
0577         return RADIAN_STR;
0578         break;
0579     case KCalcToken::TokenCode::SIN:
0580     case KCalcToken::TokenCode::SIN_RAD:
0581     case KCalcToken::TokenCode::SIN_GRAD:
0582     case KCalcToken::TokenCode::SIN_DEG:
0583         return SIN_STR;
0584         break;
0585     case KCalcToken::TokenCode::COS:
0586     case KCalcToken::TokenCode::COS_RAD:
0587     case KCalcToken::TokenCode::COS_GRAD:
0588     case KCalcToken::TokenCode::COS_DEG:
0589         return COS_STR;
0590         break;
0591     case KCalcToken::TokenCode::TAN:
0592     case KCalcToken::TokenCode::TAN_RAD:
0593     case KCalcToken::TokenCode::TAN_GRAD:
0594     case KCalcToken::TokenCode::TAN_DEG:
0595         return TAN_STR;
0596         break;
0597     case KCalcToken::TokenCode::ASIN:
0598     case KCalcToken::TokenCode::ASIN_RAD:
0599     case KCalcToken::TokenCode::ASIN_DEG:
0600     case KCalcToken::TokenCode::ASIN_GRAD:
0601         return ASIN_STR;
0602         break;
0603     case KCalcToken::TokenCode::ACOS:
0604     case KCalcToken::TokenCode::ACOS_RAD:
0605     case KCalcToken::TokenCode::ACOS_DEG:
0606     case KCalcToken::TokenCode::ACOS_GRAD:
0607         return ACOS_STR;
0608         break;
0609     case KCalcToken::TokenCode::ATAN:
0610     case KCalcToken::TokenCode::ATAN_RAD:
0611     case KCalcToken::TokenCode::ATAN_DEG:
0612     case KCalcToken::TokenCode::ATAN_GRAD:
0613         return ATAN_STR;
0614         break;
0615     case KCalcToken::TokenCode::SINH:
0616         return SINH_STR;
0617         break;
0618     case KCalcToken::TokenCode::COSH:
0619         return COSH_STR;
0620         break;
0621     case KCalcToken::TokenCode::TANH:
0622         return TANH_STR;
0623         break;
0624     case KCalcToken::TokenCode::ASINH:
0625         return ASINH_STR;
0626         break;
0627     case KCalcToken::TokenCode::ACOSH:
0628         return ACOSH_STR;
0629         break;
0630     case KCalcToken::TokenCode::ATANH:
0631         return ATANH_STR;
0632         break;
0633     case KCalcToken::TokenCode::E:
0634         return E_STR;
0635         break;
0636     case KCalcToken::TokenCode::PI:
0637         return PI_STR;
0638         break;
0639     case KCalcToken::TokenCode::PHI:
0640         return PHI_STR;
0641         break;
0642     case KCalcToken::TokenCode::I:
0643         return I_STR;
0644         break;
0645     case KCalcToken::TokenCode::POS_INFINITY:
0646         return POS_INFINITY_STR;
0647         break;
0648     case KCalcToken::TokenCode::NEG_INFINITY:
0649         return NEG_INFINITY_STR;
0650         break;
0651     case KCalcToken::TokenCode::VACUUM_PERMITIVITY:
0652         return VACUUM_PERMITIVITY_STR;
0653         break;
0654     case KCalcToken::TokenCode::VACUUM_PERMEABILITY:
0655         return VACUUM_PERMEABILITY_STR;
0656         break;
0657     case KCalcToken::TokenCode::VACUUM_IMPEDANCE:
0658         return VACUUM_IMPEDANCE_STR;
0659         break;
0660     case KCalcToken::TokenCode::PLANCK_S_CONSTANT:
0661         return PLANCK_S_CONSTANT_STR;
0662         break;
0663     case KCalcToken::TokenCode::PLANCK_OVER_2PI:
0664         return PLANCK_S_OVER_2PI_STR;
0665         break;
0666     case KCalcToken::TokenCode::EXP:
0667         return EXP_STR;
0668         break;
0669     case KCalcToken::TokenCode::EXP_10:
0670         return EXP_10_STR;
0671         break;
0672     case KCalcToken::TokenCode::POWER:
0673         return POWER_STR;
0674         break;
0675     case KCalcToken::TokenCode::POWER_ROOT:
0676         return POWER_ROOT_STR;
0677         break;
0678     case KCalcToken::TokenCode::FACTORIAL:
0679         return FACTORIAL_STR;
0680         break;
0681     case KCalcToken::TokenCode::DOUBLE_FACTORIAL:
0682         return DOUBLE_FACTORIAL_STR;
0683         break;
0684     case KCalcToken::TokenCode::GAMMA:
0685         return GAMMA_STR;
0686         break;
0687     case KCalcToken::TokenCode::INVERT_SIGN:
0688         return INVERT_SIGN_STR;
0689         break;
0690     case KCalcToken::TokenCode::LN:
0691         return LN_STR;
0692         break;
0693     case KCalcToken::TokenCode::LOG_10:
0694         return LOG_10_STR;
0695         break;
0696     case KCalcToken::TokenCode::RECIPROCAL:
0697         return RECIPROCAL_STR;
0698         break;
0699     case KCalcToken::TokenCode::BINOMIAL:
0700         return THIN_SPACE_STR + BINOMIAL_STR + THIN_SPACE_STR;
0701         break;
0702     case KCalcToken::TokenCode::MODULO:
0703         return THIN_SPACE_STR + MODULO_STR + THIN_SPACE_STR;
0704         break;
0705     case KCalcToken::TokenCode::INTEGER_DIVISION:
0706         return THIN_SPACE_STR + INTEGER_DIVISION_STR + THIN_SPACE_STR;
0707         break;
0708     case KCalcToken::TokenCode::AND:
0709         return THIN_SPACE_STR + AND_STR + THIN_SPACE_STR;
0710         break;
0711     case KCalcToken::TokenCode::OR:
0712         return THIN_SPACE_STR + OR_STR + THIN_SPACE_STR;
0713         break;
0714     case KCalcToken::TokenCode::XOR:
0715         return THIN_SPACE_STR + XOR_STR + THIN_SPACE_STR;
0716         break;
0717     case KCalcToken::TokenCode::ONE_S_COMPLEMENT:
0718         return ONE_S_COMP_STR;
0719         break;
0720     case KCalcToken::TokenCode::TWO_S_COMPLEMENT:
0721         return TWO_S_COMP_STR;
0722         break;
0723     case KCalcToken::TokenCode::RSH:
0724         return THIN_SPACE_STR + RSH_STR + THIN_SPACE_STR;
0725         break;
0726     case KCalcToken::TokenCode::LSH:
0727         return THIN_SPACE_STR + LSH_STR + THIN_SPACE_STR;
0728         break;
0729     case KCalcToken::TokenCode::ANS:
0730         return THIN_SPACE_STR + ANS_STR + THIN_SPACE_STR;
0731         break;
0732     case KCalcToken::TokenCode::EQUAL:
0733         return EQUAL_STR;
0734         break;
0735     default:
0736         break;
0737     }
0738     return ERROR_STR;
0739 }
0740 
0741 int KCalcParser::loadConstants(const QDomDocument &doc)
0742 {
0743     QDomNode n = doc.documentElement().firstChild();
0744     constant_ constant;
0745 
0746     while (!n.isNull()) {
0747         QDomElement e = n.toElement();
0748         if (!e.isNull() && e.tagName() == QLatin1String("constant")) {
0749             constant.value = e.attributeNode(QStringLiteral("value")).value();
0750             constant.symbol = e.attributeNode(QStringLiteral("symbol")).value();
0751 
0752             constants_.append(constant);
0753         }
0754         n = n.nextSibling();
0755     }
0756 
0757     return 0;
0758 }
0759 
0760 //------------------------------------------------------------------------------
0761 // Name: constantSymbolToValue_
0762 // Desc: tries to find a given constant in the stored constants list, returns
0763 //       true if found, loads value in token_KNumber_
0764 //------------------------------------------------------------------------------
0765 bool KCalcParser::constantSymbolToValue_(const QString &constantSymbol)
0766 {
0767     QList<constant_>::const_iterator i;
0768     for (i = constants_.constBegin(); i != constants_.constEnd(); ++i) {
0769         if (i->symbol == constantSymbol) {
0770             token_KNumber_ = i->value;
0771             return true;
0772         }
0773     }
0774 
0775     return false;
0776 }