tncks / factorysetupsCompProjSunday

09 22 date, Sunday
0 stars 0 forks source link

Code_cpp_0922_reference1 #1

Open tncks opened 2 months ago

tncks commented 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;
  }
};