Изменения в версии 0.3

This commit is contained in:
SkrinVex
2025-12-25 12:48:19 +05:00
parent a3e44d6a58
commit 8ca31ea877
7 changed files with 315 additions and 119 deletions
+86 -51
View File
@@ -5,46 +5,46 @@ Parser::Parser(std::vector<Token> t) : tokens(t) {}
Token Parser::consume(TokenType type) {
if (tokens[pos].type == type) return tokens[pos++];
std::cerr << "Syntax Error: Expected token type " << (int)type
<< " but found '" << tokens[pos].value
<< "' on line " << tokens[pos].line << std::endl;
std::cerr << "Syntax Error: Expected token type " << (int)type
<< " but found '" << tokens[pos].value
<< "' on line " << tokens[pos].line << std::endl;
exit(1);
}
// Выражения (возвращают значение)
std::unique_ptr<Node> Parser::primary() {
if (tokens[pos].type == TokenType::NUMBER) return std::make_unique<NumberNode>(consume(TokenType::NUMBER).value);
if (tokens[pos].type == TokenType::STRING) return std::make_unique<NumberNode>(consume(TokenType::STRING).value);
// input()
if (tokens[pos].type == TokenType::INPUT) {
consume(TokenType::INPUT); consume(TokenType::LPAREN); consume(TokenType::RPAREN);
return std::make_unique<InputNode>();
if (tokens[pos].type == TokenType::NUMBER)
return std::make_unique<NumberNode>(consume(TokenType::NUMBER).value);
if (tokens[pos].type == TokenType::STRING_LITERAL)
return std::make_unique<StringNode>(consume(TokenType::STRING_LITERAL).value);
if (tokens[pos].type == TokenType::IDENTIFIER) {
std::string name = consume(TokenType::IDENTIFIER).value;
if (tokens[pos].type == TokenType::LPAREN) {
consume(TokenType::LPAREN);
consume(TokenType::RPAREN);
return std::make_unique<FuncCallNode>(name);
}
return std::make_unique<VarAccessNode>(name);
}
// round( expr )
if (tokens[pos].type == TokenType::INPUT) {
consume(TokenType::INPUT); consume(TokenType::LPAREN); consume(TokenType::RPAREN);
return std::make_unique<InputNode>();
}
if (tokens[pos].type == TokenType::ROUND) {
consume(TokenType::ROUND);
consume(TokenType::LPAREN);
auto node = expression();
consume(TokenType::RPAREN);
return std::make_unique<RoundNode>(std::move(node));
consume(TokenType::ROUND); consume(TokenType::LPAREN); auto n = expression(); consume(TokenType::RPAREN);
return std::make_unique<RoundNode>(std::move(n));
}
// random()
if (tokens[pos].type == TokenType::RANDOM) {
consume(TokenType::RANDOM); consume(TokenType::LPAREN); consume(TokenType::RPAREN);
return std::make_unique<RandomNode>();
}
if (tokens[pos].type == TokenType::LPAREN) {
consume(TokenType::LPAREN);
auto node = expression();
consume(TokenType::RPAREN);
return node;
consume(TokenType::LPAREN); auto n = expression(); consume(TokenType::RPAREN); return n;
}
std::cerr << "Error: Unexpected token '" << tokens[pos].value << "' in expression at line " << tokens[pos].line << std::endl;
std::cerr << "Error: Unexpected token '" << tokens[pos].value << "' line " << tokens[pos].line << std::endl;
exit(1);
}
@@ -66,46 +66,81 @@ std::unique_ptr<Node> Parser::expression() {
return node;
}
// Блоки кода
void Parser::block() {
// ИЗМЕНЕНИЕ: Возвращаем unique_ptr и используем make_unique
std::unique_ptr<BlockNode> Parser::parseBlock() {
consume(TokenType::LBRACE);
auto block = std::make_unique<BlockNode>(); // Здесь было make_shared
while (tokens[pos].type != TokenType::RBRACE && tokens[pos].type != TokenType::END) {
statement();
block->statements.push_back(statement());
}
consume(TokenType::RBRACE);
return block;
}
// Инструкции (заканчиваются ;)
void Parser::statement() {
if (tokens[pos].type == TokenType::PRINT) {
consume(TokenType::PRINT);
consume(TokenType::LPAREN);
std::unique_ptr<Node> Parser::statement() {
// 1. Объявление переменных
if (tokens[pos].type == TokenType::INT_KW || tokens[pos].type == TokenType::STRING_KW) {
std::string type = tokens[pos].value;
pos++;
std::string name = consume(TokenType::IDENTIFIER).value;
consume(TokenType::ASSIGN);
auto expr = expression();
consume(TokenType::RPAREN);
consume(TokenType::SEMICOLON);
auto pNode = std::make_unique<PrintNode>(std::move(expr));
pNode->eval();
return std::make_unique<VarDeclNode>(type, name, std::move(expr));
}
else if (tokens[pos].type == TokenType::FOX) {
consume(TokenType::FOX);
consume(TokenType::LPAREN); // fox (
consume(TokenType::RPAREN); // )
consume(TokenType::SEMICOLON); // ;
std::cout << " (\\_/) \n (o.o) \n (> <) OFOX!" << std::endl;
// 2. Объявление функций
if (tokens[pos].type == TokenType::VOID_KW) {
consume(TokenType::VOID_KW);
std::string name = consume(TokenType::IDENTIFIER).value;
consume(TokenType::LPAREN);
consume(TokenType::RPAREN);
// Тут магия: unique_ptr автоматически превратится в shared_ptr при создании FuncDefNode
auto body = parseBlock();
return std::make_unique<FuncDefNode>(name, std::move(body));
}
else if (tokens[pos].type == TokenType::LBRACE) {
block();
// 3. Команда PRINT
if (tokens[pos].type == TokenType::PRINT) {
consume(TokenType::PRINT); consume(TokenType::LPAREN);
auto expr = expression();
consume(TokenType::RPAREN); consume(TokenType::SEMICOLON);
return std::make_unique<PrintNode>(std::move(expr));
}
else {
// ОБРАБОТКА ОШИБОК: Если встретили слово, которое не является командой
std::cerr << "Runtime Error: Unknown command or function '" << tokens[pos].value
<< "' at line " << tokens[pos].line << std::endl;
exit(1);
if (tokens[pos].type == TokenType::FOX) {
consume(TokenType::FOX); consume(TokenType::LPAREN); consume(TokenType::RPAREN); consume(TokenType::SEMICOLON);
return std::make_unique<StringNode>("Fox says: Hello!");
}
if (tokens[pos].type == TokenType::IDENTIFIER) {
if (tokens[pos+1].type == TokenType::ASSIGN) {
std::string name = consume(TokenType::IDENTIFIER).value;
consume(TokenType::ASSIGN);
auto expr = expression();
consume(TokenType::SEMICOLON);
return std::make_unique<AssignNode>(name, std::move(expr));
}
if (tokens[pos+1].type == TokenType::LPAREN) {
std::string name = consume(TokenType::IDENTIFIER).value;
consume(TokenType::LPAREN); consume(TokenType::RPAREN); consume(TokenType::SEMICOLON);
return std::make_unique<FuncCallNode>(name);
}
}
// ИЗМЕНЕНИЕ: Просто возвращаем результат parseBlock, никаких преобразований не нужно
if (tokens[pos].type == TokenType::LBRACE) {
return parseBlock();
}
std::cerr << "Syntax Error: Unknown statement '" << tokens[pos].value << "' at line " << tokens[pos].line << std::endl;
exit(1);
}
void Parser::run() {
while (tokens[pos].type != TokenType::END) {
statement();
auto stmt = statement();
stmt->eval(globalContext);
}
}
}