【发布时间】:2021-12-28 19:30:40
【问题描述】:
我尝试像编译器一样从用户的输入中读取标记。 标记化工作正常,但是当输出所有标记时,我想在它们全部发出后换行。
这是我的代码:
#include <iostream>
#include <map>
#include <vector>
//import for using std::getline()
#include <string>
//DIGITs
const std::string DIGITS = "0123456789";
const std::string WHITESPACE = " \t\n\r";
//TOKENS
const std::string TT_INT = "INT";
const std::string TT_FLOAT = "FLOAT";
const std::string TT_PLUS = "PLUS";
const std::string TT_MINUS = "MINUS";
const std::string TT_MUL = "MUL";
const std::string TT_DIV = "DIV";
const std::string TT_LPAREN = "LPAREN";
const std::string TT_RPAREN = "RPAREN";
const std::string TT_INVALID_NUMBER = "INVALID_NUMBER_LITERAL";
class Token{
public:
std::string type;
std::string value;
void repr(){
std::cout << type << ":" << "value" << "\n";
}
};
class Lexer{
public:
std::string text;
int position = -1;
std::string current_char;
void advance(){
this->position += 1;
this->current_char = this->text[this->position];
}
void make_digit(std::string *type, std::string *value){
//if its number or floating point
std::string digit = "";
int is_float = 0;
while(DIGITS.find(this->current_char) != std::string::npos || this->current_char == "."){
digit += this->current_char;
if(this->current_char == "."){
is_float += 1;
}
this->advance();
}
*value = digit;
if(is_float == 0){
*type = TT_INT;
} else if((0 < is_float) && (is_float < 2)){
*type = TT_FLOAT;
} else {
*type = TT_INVALID_NUMBER;
}
}
std::vector<std::string> make_tokens(){
std::vector<std::string> tokens;
this->advance();
while (!(this->text.length() <= this->position))
{
if(WHITESPACE.find(this->current_char) != std::string::npos){
//dont add a token
this->advance();
} else if(DIGITS.find(this->current_char) != std::string::npos){
std::string type;
std::string value;
this->make_digit(&type, &value);
tokens.push_back(type);
tokens.push_back(value);
} else if(this->current_char == "+"){
tokens.push_back(TT_PLUS);
tokens.push_back(this->current_char);
this->advance();
} else if(this->current_char == "-"){
tokens.push_back(TT_MINUS);
tokens.push_back(this->current_char);
this->advance();
} else if(this->current_char == "*"){
tokens.push_back(TT_MUL);
tokens.push_back(this->current_char);
this->advance();
} else if(this->current_char == "/"){
tokens.push_back(TT_DIV);
tokens.push_back(this->current_char);
this->advance();
} else if(this->current_char == "("){
tokens.push_back(TT_LPAREN);
tokens.push_back(this->current_char);
this->advance();
} else if(this->current_char == ")"){
tokens.push_back(TT_RPAREN);
tokens.push_back(this->current_char);
this->advance();
} else {
//nothing
this->advance();
}
}
return tokens;
}
};
int main(){
//previous: true
while(std::getline(std::cin, input)){
std::string input;
//previous: std::cin >> input;
//fix
std::getline(std::cin, input);
Lexer mylexer;
mylexer.text = input;
int x = 0;
std::vector<std::string> output = mylexer.make_tokens();
for (int i = 0; i < output.size(); i += 2){
std::cout << output.at(i) << ":" << output.at(i + 1) << std::endl;
}
std::cout << "\n";
}
};
输入 1 + 2 时
我的预期
1 + 2
INT:1
PLUS:+
INT:2
here is the cursor
我得到了什么
1 + 2
INT:1
PLUS:+
INT:2
here is the cursor
在最后删除换行符时,我得到了这个,但是当输入第二个输入行时,它全部在一起,没有空行,这不是我想要的
1 + 2
INT:1
PLUS:+
INT:2
here is the cursor
但我希望它看起来像这样
1 + 2
INT:1
PLUS:+
INT:2
3 + 4
INT:3
PLUS:+
INT:4
谁能解释这种奇怪的行为是什么? 我错过了什么吗?请注意,我没有太多 C++ 经验。 我正在使用 clang-cl.exe 编译 Windows。我还想知道使用 MSYS2 g++.exe 编译时 throw_bad_array_new_lengthv 错误意味着什么
【问题讨论】:
-
建议:如果您遇到循环问题,请从程序中删除除循环之外的所有内容。一旦所有的噪音都消失了,问题的根源通常是显而易见的。使用minimal reproducible example 获取灵感。
-
您正在输出两个新行。首先你转储
std::endl,它会换行。然后你输出\n输出另一个。摆脱\n -
@joe 但我不明白为什么它甚至会重复 3 次,因为我想它不在循环中。另请参阅我的编辑
-
当我按原样运行代码时,出现运行时错误。所以某处的逻辑存在错误。
-
@RemyLebeau 哪个错误信息?编辑:是因为用 g++ 编译吗?