'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();
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
