fix: Pratt parser NUD/LED akışı, Token* slicing, null guard

- ParserToken artık Token* tutuyor (object slicing önlendi)
- parseNullDenotation atom'ları tüketip ilerliyor
- parseExpression while döngüsü currentToken() ile çalışıyor
- IR: null Left/Right ve null ASTNode girişi korumalı
- source.sqt: 1/(74-63+!1)-74*2/-0.7e+10 başarıyla parse ediliyor
This commit is contained in:
abdussamedulutas 2026-05-26 00:03:19 +03:00
parent b08205c03f
commit 40579ca508
3 changed files with 10 additions and 7 deletions

View File

@ -1 +1 @@
1+2 1 / (74 - 63 + !1) - 74 * 2 / -0.7e+10

View File

@ -51,6 +51,7 @@ public:
std::vector<IROpData> IROpDatas; std::vector<IROpData> IROpDatas;
int parse(ASTNode* ast) { int parse(ASTNode* ast) {
if (!ast) return 0;
switch (ast->kind) { switch (ast->kind) {
case ASTKind::BinaryExpression: case ASTKind::BinaryExpression:
return parseBinaryExpr((BinaryExpressionNode*)ast); return parseBinaryExpr((BinaryExpressionNode*)ast);
@ -131,8 +132,8 @@ public:
default: return 0; default: return 0;
} }
int left = parse(bin->Left); int left = bin->Left ? parse(bin->Left) : 0;
int right = parse(bin->Right); int right = bin->Right ? parse(bin->Right) : 0;
IROpDatas.push_back({ IROpDatas.push_back({
op, op,

View File

@ -420,16 +420,14 @@ inline ASTNode* Parser::parseExpression(uint16_t precedence) {
if (!left) return nullptr; if (!left) return nullptr;
while (true) { while (true) {
auto next = lookahead(1); auto next = currentToken();
if (next.type == TokenType::RPAREN || if (next.type == TokenType::RPAREN ||
next.type == TokenType::SEMICOLON || next.type == TokenType::SEMICOLON ||
next.type == TokenType::RBRACE || next.type == TokenType::RBRACE ||
next.type == TokenType::COMMA) next.type == TokenType::COMMA)
break; break;
next = lookahead(1);
if (precedence < next.getPowerOperator()) { if (precedence < next.getPowerOperator()) {
nextToken();
left = parseLeftDenotation(left); left = parseLeftDenotation(left);
} else { } else {
break; break;
@ -472,8 +470,9 @@ inline ASTNode* Parser::parseNullDenotation() {
return bin; return bin;
} }
// Numeric literal — NUD does NOT advance; loop handles it // Numeric literal
if (ct.type == TokenType::NUMBER) { if (ct.type == TokenType::NUMBER) {
nextToken();
LiteralNode* lit = new LiteralNode(); LiteralNode* lit = new LiteralNode();
lit->lexerToken = ct.token; lit->lexerToken = ct.token;
lit->parserToken = ct; lit->parserToken = ct;
@ -482,6 +481,7 @@ inline ASTNode* Parser::parseNullDenotation() {
// String literal // String literal
if (ct.type == TokenType::STRING) { if (ct.type == TokenType::STRING) {
nextToken();
LiteralNode* lit = new LiteralNode(); LiteralNode* lit = new LiteralNode();
lit->lexerToken = ct.token; lit->lexerToken = ct.token;
lit->parserToken = ct; lit->parserToken = ct;
@ -490,6 +490,7 @@ inline ASTNode* Parser::parseNullDenotation() {
// Boolean / null literals // Boolean / null literals
if (ct.is({TokenType::KW_TRUE, TokenType::KW_FALSE, TokenType::KW_NULL})) { if (ct.is({TokenType::KW_TRUE, TokenType::KW_FALSE, TokenType::KW_NULL})) {
nextToken();
LiteralNode* lit = new LiteralNode(); LiteralNode* lit = new LiteralNode();
lit->lexerToken = ct.token; lit->lexerToken = ct.token;
lit->parserToken = ct; lit->parserToken = ct;
@ -498,6 +499,7 @@ inline ASTNode* Parser::parseNullDenotation() {
// Identifier // Identifier
if (ct.type == TokenType::IDENTIFIER) { if (ct.type == TokenType::IDENTIFIER) {
nextToken();
IdentifierNode* id = new IdentifierNode(); IdentifierNode* id = new IdentifierNode();
id->lexerToken = ct.token; id->lexerToken = ct.token;
id->parserToken = ct; id->parserToken = ct;