'How do I implement a _getch() function instead of a cin function? C++

I need help with a way to implement a _getch() function instead of a cin function in this Recursive-descent parsing calculator. I believe the program lays in this function ClassLexer() : m_stream{ std::cin } { } in the parser.h section of code. But due to the why the m_stream is implemented, i don't know how to replace it with the _getch() function.

Or maybe replace something in the tokenex.cpp file to get with a _getch() function in the fetch_next_token() function.

parser.h code:

#pragma once
#include <iostream>
#include <map>
#include <string>
#include <cctype>

using namespace std;

namespace Lexer
{
    using variable_t = std::map<std::string, double>;

    // Kind is for token type
    enum class Kind : char
    {
        end, print = ';', plus = '+', minus = '-',
        mul = '*', div = '/', assign = '=',
        p_open = '(', p_close = ')',
        number, variable
    };

    struct Token
    {
        Kind kind;
        std::string name;
        double number;
    };

    class ClassLexer
    {
    private:
        std::istream& m_stream;
        Token m_current_token;

    public:

        ClassLexer() : m_stream{ std::cin } { }

        Token& get_current_token();

        Token fetch_next_token();

        std::istream& get_next_char(char& chr);

    };
}

namespace Parser
{
    using namespace Lexer;

    class ClassParser
    {
    private:
        ClassLexer m_lexer;
        variable_t m_variable;

    public:
        double expr(bool bNextToken);
        double term(bool bNextToken);
        double prim(bool bNextToken);

        void calculate();

    };
}

Tokenex.cpp code:

#include "parser.h"

namespace Lexer
{
    std::istream& ClassLexer::get_next_char(char& chr)
    {
        while (this->m_stream.get(chr) &&
            (std::isblank(chr) || chr == '\n'));

        return this->m_stream;
    }

    Token& ClassLexer::get_current_token()
    {
        return this->m_current_token;
    }

    Token ClassLexer::fetch_next_token()
    {
        
        char lac = 0;

        
        this->get_next_char(lac);

        switch (lac)
        {
        case 0:
            this->m_current_token = { Kind::end };
            return this->m_current_token;

        case ';': case '+': case '-': case '*': case '/':
        case '=': case '(': case ')':
            this->m_current_token = { static_cast<Kind>(lac) };
            return this->m_current_token;

        case '0': case '1': case '2': case '3': case '4':
        case '5': case '6': case '7': case '8': case '9': case '.':
        {
        
            this->m_stream.putback(lac);

            this->m_stream >> this->m_current_token.number;

            this->m_current_token.kind = Kind::number;

            return this->m_current_token;
        }

        default:
        {
            if (std::isalpha(lac))
            {
                this->m_current_token.name = lac;

                while (this->m_stream.get(lac) &&
                    std::isalnum(lac))
                    this->m_current_token.name += lac;

                this->m_stream.putback(lac);

                this->m_current_token.kind = Kind::variable;
                return this->m_current_token;
            }
            else
            {
                this->m_current_token = { Kind::print };
                return this->m_current_token;
            }
        }

        } 

    } 
}

calcu.cpp code:

#include "parser.h"

namespace Parser
{
    using namespace Lexer;

    double ClassParser::prim(bool bNextToken)
    {
        if (bNextToken)
            this->m_lexer.fetch_next_token();

        switch (this->m_lexer.get_current_token().kind)
        {
        case Kind::number:
        {
            double v = this->m_lexer.get_current_token().number;

            
            this->m_lexer.fetch_next_token();

            return v;
        }

        case Kind::variable:
        {
            double& v = this->m_variable[this->m_lexer.get_current_token().name];

            if (this->m_lexer.fetch_next_token().kind == Kind::assign)
                v = this->expr(true);

            return v;

        }
        case Kind::minus:
            return -this->prim(true);

        case Kind::p_open:
        {
            double v = this->expr(true);

            if (this->m_lexer.get_current_token().kind != Kind::p_close)
            {
                std::cerr << "Syntax error:\')\' is expected" << std::endl;
            }

            
            this->m_lexer.fetch_next_token();

            return v;
        }

        default:
        {
            std::cerr << "Syntax Error" << std::endl;
            return 0;
        }

        } 

    } 

    double ClassParser::term(bool bNextToken)
    {
        double left = prim(bNextToken);

        switch (this->m_lexer.get_current_token().kind)
        {
        case Kind::mul:
            left *= this->prim(true); return left;

        case Kind::div:
            left /= this->prim(true); return left;

        default:
            return left;
        }
    }

    double ClassParser::expr(bool bNextToken)
    {
        double left = this->term(bNextToken);
        switch (this->m_lexer.get_current_token().kind)
        {
        case Kind::plus:
            left += this->term(true); return left;

        case Kind::minus:
            left -= this->term(true); return left;

        default:
            return left;
        }
    }

    void ClassParser::calculate()
    {
        for (this->m_lexer.fetch_next_token();
            this->m_lexer.get_current_token().kind != Kind::end;
            this->m_lexer.fetch_next_token())
        {
            std::cout << this->expr(false) << std::endl;
        }

    }
}

main.cpp code:

#include "parser.h"

#include <conio.h>


void test_parse()
{
    Parser::ClassParser parser;

    parser.calculate();

}

int main()
{
    test_parse();
}
c++


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source