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:
parent
b08205c03f
commit
40579ca508
|
|
@ -1 +1 @@
|
||||||
1+2
|
1 / (74 - 63 + !1) - 74 * 2 / -0.7e+10
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue