bool isDouble(char *&ch) { States state = start; while (true) { switch (state) { case start: { if (isSign(*ch)) state = sign; else if (isdigit(*ch)) state = intPart; else return false; break; } case sign:{ if (isdigit(*ch)) state = intPart; else return false; break; } case intPart: { if (isdigit(*ch)) break; else if (*ch == '.') state = point; else if (isExponent(*ch)) state = exponent; else return true; break; } case point: { if (isdigit(*ch)) state = frctPart; else return false; break; } case frctPart: { if (isdigit(*ch)) break; else if (isExponent(*ch)) state = exponent; else return true; break; } case exponent: { if (isSign(*ch)) state = expSign; else if (isdigit(*ch)) state = expValue; else return false; break; } case expSign: { if (isdigit(*ch)) state = expValue; else return false; break; } case expValue: { if (isdigit(*ch)) break; else return true; break; } } ch++; } }
bool Tokenizer::consumeNumber(std::streambuf::int_type ch) { int count = 0; if (isSign(ch)) { bool number = false; while (!eof()) { ++count; auto nch = mpInput->get(); if (isWhitespace(nch)) continue; number = isDecimalDigit(nch); break; } if (count) mpInput->clear(); for (int i = 0; i < count; ++i) mpInput->unget(); if (!number) return false; } absorbed(ch); mpCurrent->addChar(ch); for (int i = 0; i < count; ++i) { auto nch = mpInput->get(); absorbed(nch); mpCurrent->addChar(nch); } bool bDot = false; if (isDot(ch)) { bDot = true; mpCurrent->setType(Token::TYPE_REAL_LITERAL); } else { mpCurrent->setType(Token::TYPE_INTEGER_LITERAL); if (!eof() && isZero(ch)) { ch = mpInput->get(); if (isHexIndicator(ch)) { if (eof()) { mpMessageCollector->addMessage( Message::SEVERITY_ERROR, Message::t_invalidIntegerLiteral, mpSourceId, mpCurrent->line(), mpCurrent->beginColumn()); mpCurrent.reset(); return false; } mpCurrent->addChar(ch); absorbed(ch); while (!eof()) { ch = mpInput->get(); if (isNonHexicalLetter(ch) || isUnderscore(ch) || isDot(ch)) { mpMessageCollector->addMessage(Message::SEVERITY_ERROR, Message::t_invalidIntegerLiteral, mpSourceId, mpCurrent->line(), mpCurrent->beginColumn()); mpCurrent.reset(); return false; } if (!isHexicalDigit(ch)) { mpInput->clear(); mpInput->unget(); break; } absorbed(ch); mpCurrent->addChar(ch); } mpCurrent->setEndColumn(column()); return true; } for (;;) { if ( isLetter(ch) || isDot(ch) || isNonOctalDecimalDigit(ch) || isUnderscore(ch)) { mpMessageCollector->addMessage( Message::SEVERITY_ERROR, Message::t_invalidIntegerLiteral, mpSourceId, mpCurrent->line(), mpCurrent->beginColumn()); mpCurrent.reset(); return false; } if (!isOctalDigit(ch)) { mpInput->clear(); mpInput->unget(); break; } absorbed(ch); mpCurrent->addChar(ch); if (eof()) { break; } ch = mpInput->get(); } mpCurrent->setEndColumn(column()); return true; } } bool bExponent = false; while (!eof()) { ch = mpInput->get(); if (isExponent(ch)) { if (bExponent) { mpMessageCollector->addMessage( Message::SEVERITY_ERROR, Message::t_invalidIntegerLiteral, mpSourceId, mpCurrent->line(), mpCurrent->beginColumn()); mpCurrent.reset(); return false; } bExponent = true; mpCurrent->setType(Token::TYPE_REAL_LITERAL); absorbed(ch); mpCurrent->addChar(ch); ch = mpInput->get(); if (isSign(ch)) { mpCurrent->setType(Token::TYPE_REAL_LITERAL); absorbed(ch); mpCurrent->addChar(ch); } else { mpInput->clear(); mpInput->unget(); } continue; } if (isLetter(ch) || isUnderscore(ch)) { mpMessageCollector->addMessage( Message::SEVERITY_ERROR, Message::t_invalidIntegerLiteral, mpSourceId, mpCurrent->line(), mpCurrent->beginColumn()); mpCurrent.reset(); return false; } if (isDot(ch)) { if (bExponent || bDot) { mpMessageCollector->addMessage( Message::SEVERITY_ERROR, Message::t_invalidIntegerLiteral, mpSourceId, mpCurrent->line(), mpCurrent->beginColumn()); mpCurrent.reset(); return false; } bDot = true; mpCurrent->setType(Token::TYPE_REAL_LITERAL); absorbed(ch); mpCurrent->addChar(ch); continue; } if (!isDecimalDigit(ch)) { mpInput->clear(); mpInput->unget(); break; } absorbed(ch); mpCurrent->addChar(ch); } mpCurrent->setEndColumn(column()); return true; }