Open tncks opened 2 months ago
class Scanner { char const * const m_end = nullptr; char const * m_next = nullptr; float m_number = 0.0f; void SkipWhitespace() throw() { while (m_next != m_end) { if (isspace(*m_next)) { ++m_next; } else { break; } } } Token ReadNumber() throw() { bool digit = false; bool point = false; unsigned divide = 1; m_number = 0.0f; for (char c = *m_next; m_next != m_end; c = *++m_next) { if ('0' <= c && '9' >= c) { digit = true; m_number = 10 * m_number + (c - '0'); if (point) { divide *= 10; } } else if ('.' == c) { point = true; } else { break; } } if (digit) { m_number /= divide; return Token::Number; } return Token::Invalid; } public: Scanner(Scanner const &) = delete; Scanner & operator=(Scanner const &) = delete; Scanner(char const * const begin, char const * const end) throw() : m_end(end), m_next(begin) {} float GetNumber() const throw() { return m_number; } Token Read() throw() { SkipWhitespace(); if (m_next == m_end) { return Token::EndOfFile; } char const c = *m_next; if ('+' == c) { ++m_next; return Token::Add; } if ('-' == c) { ++m_next; return Token::Subtract; } if ('*' == c) { ++m_next; return Token::Multiply; } if ('/' == c) { ++m_next; return Token::Divide; } if ('(' == c) { ++m_next; return Token::LeftParenthesis; } if (')' == c) { ++m_next; return Token::RightParenthesis; } if ('.' == c || '0' <= c && '9' >= c) { return ReadNumber(); } return Token::Invalid; } };