Я пытаюсь сделать базовый математический токенизатор/парсер в C++, который получает входную информацию от консоли, а затем ее токенизирует (в конечном счете переходит к ее анализу). Однако, когда я пробовал 5 * 5
, у меня была небольшая проблема:
Я бы получил желаемое обозначенное значение 53 -1 53
напечатанное на консоли, но после этого я также получил бесконечное количество -1
(он продолжал печать). В чем проблема?
main.cpp
#include <iostream>
#include <sstream>
#include "tokenizer.h"
int main(void){
std::cout << "Please enter a mathematical expression" << std::endl;
std::string line;
std::getline(std::cin, line);
std::istringstream input(line);
tokenizer t;
std::vector<token> tokens(t.getTokens(&input));
}
tokenizer.h
#include <vector>
#include <sstream>
#include "tokens.h"
class tokenizer{
public:
std::vector<token> getTokens(std::istringstream* input);
};
tokens.h
typedef const signed int token;
enum tokens{
mul = -1,
mDiv = -2,
add = -3,
sub = -4,
mPow = -5,
lparen = -6,
rparen = -7,
decpoint = -8
};
tokenizer.cpp
#include "tokenizer.h"
#include <iostream>
token getToken(int tok);
std::vector<token> tokenizer::getTokens(std::istringstream* input){
std::vector<token> tokens;
while(input){
int t = input->get();
if(!isspace(t)){
std::cout << getToken(t) << " "; // I added this line to see the values being added
tokens.push_back(getToken(t));
}
}
return tokens;
}
token getToken(int tok){
switch((char)tok){
case '*':
return tokens::mul;
case '/':
return tokens::mDiv;
case '+':
return tokens::add;
case '-':
return tokens::sub;
case '^':
return tokens::mPow;
case '(':
return tokens::lparen;
case ')':
return tokens::rparen;
case '.':
return tokens::decpoint;
}
return tok;
}
Указатель на std::istringstream
будет оцениваться как истинный даже после чтения всего ввода, если он не равен нулю.
null_ptr
?
Условие цикла в tokenizer::getTokens()
всегда будет оцениваться как true в вашем коде. Вы можете попробовать изменить while(input)
до while(input->good())
.