求调:啥表达式输进去都是0
  • 板块灌水区
  • 楼主hdkghc
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/4/19 21:45
  • 上次更新2024/4/20 09:04:50
查看原帖
求调:啥表达式输进去都是0
346134
hdkghc楼主2024/4/19 21:45

RT,代码有点长~~,忍一下~~

enum class TokenType
{
	NUMBER = 3,
	PLUS,
	MINUS,
	MULTIPLY,
	DIVIDE,
	MOD,
	EQUAL,
	NOT_EQUAL,
	LESS_THAN,
	LESS_THAN_OR_EQUAL,
	GREATER_THAN,
	GREATER_THAN_OR_EQUAL,
	LOGICAL_AND,
	LOGICAL_OR,
	BITWISE_AND,
	BITWISE_OR,
	BITWISE_XOR,
	BITWISE_NOT,
	LEFT_SHIFT,
	RIGHT_SHIFT,
	INCREMENT,
	DECREMENT,
	PLUS_ASSIGN,
	MINUS_ASSIGN,
	MULTIPLY_ASSIGN,
	DIVIDE_ASSIGN,
	MOD_ASSIGN,
	BITWISE_AND_ASSIGN,
	BITWISE_OR_ASSIGN,
	BITWISE_XOR_ASSIGN,
	LEFT_SHIFT_ASSIGN,
	RIGHT_SHIFT_ASSIGN,
	LOGICAL_NOT,
	LOGICAL_NOT_ASSIGN,
	LPAREN,
	RPAREN,
	LBRACE,
	RBRACE,
	LSQUARE,
	RSQUARE,
	COMMA,
	SEMICOLON,
	COLON,
	DOT,
	ARROW,
	ELLIPSIS,
	QUESTION,
	INDENT,
	KEYWORD,
	IDENTIFIER,
	COMMENTLINE,
	PREPROCESSOR,
	CONNECT,
	STRING,
	CHARACTER,
	END
};
#include <iostream>
#include <string>
#include <cctype>
#include <unordered_set>
#include <stdexcept>

using namespace std;



struct Token
{
	TokenType type;
	string value;
	Token(){}
	Token(TokenType type, string value) : type(type), value(value) {}
};

class Lexer
{
public:
	Lexer(string input) : input(input), currentPos(0)
	{
		keywords = {"if", "else", "while", "for", "int", "float", "void", "return", "class", "struct", "namespace", "const", "static", "public", "private", "protected", "friend", "virtual", "override", "final", "template", "typename", "using", "new", "delete", "try", "catch", "throw", "sizeof"}; // 关键字集合
	}
	
	Token getNextToken()
	{
		while (currentPos < input.length())
		{
			char currentChar = input[currentPos];
			
			if (isspace(currentChar))
			{
				if (currentChar == '\t') // 判断是否为缩进符号
				{
					currentPos++;
					return Token{TokenType::INDENT, "\\t"};
				}
				currentPos++;
				continue;
			}
			
			if (isdigit(currentChar))
			{
				string number = getNumber();
				return Token{TokenType::NUMBER, number};
			}
			else if (isalpha(currentChar) || currentChar == '_')
			{
				return isKeywordOrIdentifier();
			}
			else
			{
				string str;
				switch (currentChar)
				{
				case '+':
					if (input[currentPos + 1] == '=')
					{
						currentPos += 2;
						return Token{TokenType::INCREMENT, "+="};
					}
					currentPos++;
					return Token{TokenType::PLUS, "+"};
				case '-':
					if (input[currentPos + 1] == '>')
					{
						currentPos += 2;
						return Token{TokenType::ARROW, "->"};
					}
					if (input[currentPos + 1] == '=')
					{
						currentPos += 2;
						return Token{TokenType::DECREMENT, "-="};
					}
					currentPos++;
					return Token{TokenType::MINUS, "-"};
				case '#':
					if (input[currentPos + 1] == '#')
					{
						currentPos += 2;
						return Token{TokenType::CONNECT, "##"};
					}
					currentPos++;
					return Token{TokenType::PREPROCESSOR, "#"};
				case '(':
					currentPos++;
					return Token{TokenType::LPAREN, "("};
				case ')':
					currentPos++;
					return Token{TokenType::RPAREN, ")"};
				case '[':
					currentPos++;
					return Token{TokenType::LSQUARE, "["};
				case ']':
					currentPos++;
					return Token{TokenType::RSQUARE, "]"};
				case '{':
					currentPos++;
					return Token{TokenType::LBRACE, "{"};
				case '}':
					currentPos++;
					return Token{TokenType::RBRACE, "}"};
				case ':':
					currentPos++;
					return Token{TokenType::COLON, ":"};
				case ';':
					currentPos++;
					return Token{TokenType::SEMICOLON, ";"};
				case '.':
					currentPos++;
					return Token{TokenType::DOT, "."};
				case '"':
					currentPos++;
					str = input.substr(currentPos, input.substr(currentPos).find_first_of('"') - currentPos + 1);
					return Token{TokenType::STRING, str};
				case '?':
					currentPos++;
					return Token{TokenType::QUESTION, "?"};
				case '*':
					if (input[currentPos + 1] == '=')
					{
						currentPos += 2;
						return Token{TokenType::MULTIPLY_ASSIGN, "*="};
					}
					currentPos++;
					return Token{TokenType::MULTIPLY, "*"};
				case '/':
					if (input[currentPos + 1] == '=')
					{
						currentPos += 2;
						return Token{TokenType::DIVIDE_ASSIGN, "/="};
					}
					if (input[currentPos + 1] == '/')
					{
						currentPos += 2;
						return Token{TokenType::COMMENTLINE, "//"};
					}
					currentPos++;
					return Token{TokenType::DIVIDE, "/"};
				case '%':
					if (input[currentPos + 1] == '=')
					{
						currentPos += 2;
						return Token{TokenType::MOD_ASSIGN, "%="};
					}
					currentPos++;
					return Token{TokenType::MOD, "%"};
					case '=':
						if (input[currentPos + 1] == '=')
						{
							currentPos += 2;
							return Token{TokenType::EQUAL, "=="};
						}
						currentPos++;
						return Token{TokenType::EQUAL, "="};
				case '!':
					if (input[currentPos + 1] == '=')
					{
						currentPos += 2;
						return Token{TokenType::NOT_EQUAL, "!="};
					}
					currentPos++;
					return Token{TokenType::LOGICAL_NOT, "!"};
				case '<':
					if (input[currentPos + 1] == '=')
					{
						currentPos += 2;
						return Token{TokenType::LESS_THAN_OR_EQUAL, "<="};
					}
					if (input[currentPos + 1] == '<')
					{
						if (input[currentPos + 2] == '=')
						{
							currentPos += 3;
							return Token{TokenType::LEFT_SHIFT_ASSIGN, "<<="};
						}
						currentPos += 2;
						return Token{TokenType::LEFT_SHIFT, "<<"};
					}
					currentPos++;
					return Token{TokenType::LESS_THAN, "<"};
				case '>':
					if (input[currentPos + 1] == '>')
					{
						if (input[currentPos + 2] == '=')
						{
							currentPos += 3;
							return Token{TokenType::RIGHT_SHIFT_ASSIGN, ">>="};
						}
						currentPos += 2;
						return Token{TokenType::RIGHT_SHIFT, ">>"};
					}
					if (input[currentPos + 1] == '=')
					{
						currentPos += 2;
						return Token{TokenType::GREATER_THAN_OR_EQUAL, ">="};
					}
					currentPos++;
					return Token{TokenType::GREATER_THAN, ">"};
					// 添加更多运算符的识别代码
				case '&':
					if (input[currentPos + 1] == '&')
					{
						currentPos += 2;
						return Token{TokenType::LOGICAL_AND, "&&"};
					}
					if (input[currentPos + 1] == '=')
					{
						currentPos += 2;
						return Token{TokenType::BITWISE_AND_ASSIGN, "&="};
					}
					currentPos++;
					return Token{TokenType::BITWISE_AND, "&"};
				case '|':
					if (input[currentPos + 1] == '|')
					{
						currentPos += 2;
						return Token{TokenType::LOGICAL_OR, "||"};
					}
					if (input[currentPos + 1] == '=')
					{
						currentPos += 2;
						return Token{TokenType::BITWISE_OR_ASSIGN, "|="};
					}
					currentPos++;
					return Token{TokenType::BITWISE_OR, "|"};
				case '^':
					if (input[currentPos + 1] == '=')
					{
						currentPos += 2;
						return Token{TokenType::BITWISE_XOR_ASSIGN, "^="};
					}
					currentPos++;
					return Token{TokenType::BITWISE_XOR, "^"};
				case '~':
					currentPos++;
					return Token{TokenType::BITWISE_NOT, "~"};
				default:
					throw runtime_error("Invalid character");
				}
			}
		}
		return Token{TokenType::END, ""};
	}
	
	string getNumber()
	{
		string number;
		while (currentPos < input.length() && isdigit(input[currentPos]))
		{
			number += input[currentPos];
			currentPos++;
		}
		return number;
	}
	
	Token isKeywordOrIdentifier()
	{
		string word;
		while (currentPos < input.length() && (isalnum(input[currentPos]) || input[currentPos] == '_' || input[currentPos] == '$'))
		{
			word += input[currentPos];
			currentPos++;
		}
		if (keywords.find(word) != keywords.end())
		{
			return Token{TokenType::KEYWORD, word};
		}
		else
		{
			return Token{TokenType::IDENTIFIER, word};
		}
	}
	
private:
	string input;
	size_t currentPos;
	unordered_set<string> keywords;
};

class Node
{
public:
	char op;
	int value;
	Node* left;
	Node* right;
	
	Node(char op, int value = 0, Node* left = nullptr, Node* right = nullptr) : op(op), value(value), left(left), right(right) {}
};

class Parser
{
public:
	Parser(Lexer& lexer) : lexer(lexer), currentToken(lexer.getNextToken()) {}
	
	
	
	void eat(TokenType tokenType)
	{
		if (currentToken.type == tokenType)
		{
			currentToken = lexer.getNextToken();
		}
		else
		{
			throw runtime_error("Syntax error: Unexpected token");
		}
	}
	Node* factor()
	{
		Token token = lexer.getNextToken();
		if (token.type == TokenType::NUMBER)
		{
			return new Node('\0', stoi(token.value));
		}
		else if (token.type == TokenType::LPAREN)
		{
			Node* node = expr();
			lexer.getNextToken();
			return node;
		}
		return nullptr;
	}
	
	Node* term()
	{
		Node* node = factor();
		
		while (currentToken.type == TokenType::MULTIPLY || currentToken.type == TokenType::DIVIDE)
		{
			Token op = currentToken;
			eat(op.type);
			Node* right = factor();
			node = new Node(op.value[0], 0, node, right);
		}
		
		return node;
	}
	
	Node* expr()
	{
		Node* node = term();
		
		while (currentToken.type == TokenType::PLUS || currentToken.type == TokenType::MINUS)
		{
			Token op = currentToken;
			eat(op.type);
			Node* right = term();
			node = new Node(op.value[0], 0, node, right);
		}
		
		return node;
	}
private:
	Lexer& lexer;
	Token currentToken;
};

int eval(Node* node)
{
	if (node == nullptr)
	{
		return 0;
	}
	
	cout << node->op << ' ' << node->value << endl;
	
	if (node->op == '\0') // Leaf node
	{
		return node->value;
	}
	
	int leftValue = eval(node->left);
	int rightValue = eval(node->right);
	
	switch (node->op)
	{
	case '+':
		return leftValue + rightValue;
	case '-':
		return leftValue - rightValue;
	case '*':
		return leftValue * rightValue;
	case '/':
		if (rightValue == 0)
		{
			throw runtime_error("Division by zero");
		}
		return leftValue / rightValue;
		default:
			throw runtime_error("Invalid operator");
	}
}

int main()
{
	string input;
	getline(cin, input);
	Lexer lexer(input);
	Token token;
	do
	{
		token = lexer.getNextToken();
		cout << "Token: " << (int)token.type << ' ' << token.value << endl;
	} while (token.type != TokenType::END);
	
	Parser p(lexer);
	cout << eval(p.expr()) << endl;
	return 0;
}
2024/4/19 21:45
加载中...