Refactored expressions

This commit is contained in:
Rafał Grodziński
2025-06-04 15:55:27 +09:00
parent 0e62b4ed50
commit 36e798ae3f
3 changed files with 74 additions and 70 deletions

View File

@@ -24,6 +24,26 @@ public:
virtual string toString(); virtual string toString();
}; };
class ExpressionLiteral: public Expression {
private:
int64_t integer = 0;
public:
ExpressionLiteral(shared_ptr<Token> token);
int64_t getInteger();
string toString() override;
};
class ExpressionGrouping: public Expression {
private:
shared_ptr<Expression> expression;
public:
ExpressionGrouping(shared_ptr<Expression> expression);
shared_ptr<Expression> getExpression();
string toString() override;
};
class ExpressionBinary: public Expression { class ExpressionBinary: public Expression {
public: public:
enum Operation { enum Operation {
@@ -47,26 +67,6 @@ public:
string toString() override; string toString() override;
}; };
class ExpressionLiteral: public Expression {
private:
int64_t integer = 0;
public:
ExpressionLiteral(shared_ptr<Token> token);
int64_t getInteger();
string toString() override;
};
class ExpressionGrouping: public Expression {
private:
shared_ptr<Expression> expression;
public:
ExpressionGrouping(shared_ptr<Expression> expression);
shared_ptr<Expression> getExpression();
string toString() override;
};
class ExpressionInvalid: public Expression { class ExpressionInvalid: public Expression {
private: private:
shared_ptr<Token> token; shared_ptr<Token> token;

View File

@@ -111,7 +111,6 @@ shared_ptr<Statement> Parser::matchStatementExpression() {
else if (!expression->isValid()) else if (!expression->isValid())
return make_shared<StatementInvalid>(tokens.at(currentIndex)); return make_shared<StatementInvalid>(tokens.at(currentIndex));
currentIndex++;
return make_shared<StatementExpression>(expression); return make_shared<StatementExpression>(expression);
} }
@@ -123,89 +122,94 @@ shared_ptr<StatementInvalid> Parser::matchStatementInvalid() {
// Expression // Expression
// //
shared_ptr<Expression> Parser::nextExpression() { shared_ptr<Expression> Parser::nextExpression() {
return matchExpressionInvalid(); return matchTerm();
} }
/*shared_ptr<Expression> Parser::term() { shared_ptr<Expression> Parser::matchTerm() {
shared_ptr<Expression> expression = factor(); shared_ptr<Expression> expression = matchFactor();
if (!expression->isValid()) if (expression == nullptr || !expression->isValid())
return expression; return expression;
while (tokens.at(currentIndex)->isOfKind({Token::Kind::PLUS, Token::Kind::MINUS})) { while (tokens.at(currentIndex)->isOfKind({Token::Kind::PLUS, Token::Kind::MINUS})) {
expression = matchBinary(expression); expression = matchExpressionBinary(expression);
} }
return expression; return expression;
} }
shared_ptr<Expression> Parser::factor() { shared_ptr<Expression> Parser::matchFactor() {
shared_ptr<Expression> expression = primary(); shared_ptr<Expression> expression = matchPrimary();
if (!expression->isValid()) if (expression == nullptr || !expression->isValid())
return expression; return expression;
while (tokens.at(currentIndex)->isOfKind({Token::Kind::STAR, Token::Kind::SLASH, Token::Kind::PERCENT})) { while (tokens.at(currentIndex)->isOfKind({Token::Kind::STAR, Token::Kind::SLASH, Token::Kind::PERCENT})) {
expression = matchBinary(expression); expression = matchExpressionBinary(expression);
} }
return expression; return expression;
} }
shared_ptr<Expression> Parser::primary() { shared_ptr<Expression> Parser::matchPrimary() {
{ shared_ptr<Expression> expression;
shared_ptr<Expression> expression = matchInteger();
if (expression->isValid())
return expression;
}
{ expression = matchExpressionLiteral();
shared_ptr<Expression> expression = matchGrouping(); if (expression != nullptr)
if (expression->isValid()) return expression;
return expression;
} expression = matchExpressionGrouping();
if (expression != nullptr)
return expression;
return make_shared<Expression>(Expression::Kind::INVALID, tokens.at(currentIndex), nullptr, nullptr); return nullptr;
} }
shared_ptr<Expression> Parser::matchInteger() { shared_ptr<Expression> Parser::matchExpressionLiteral() {
Token token = tokens.at(currentIndex); shared_ptr<Token> token = tokens.at(currentIndex);
if (token.getKind() == Token::Kind::INTEGER) { if (token->isOfKind({Token::Kind::INTEGER})) {
currentIndex++; currentIndex++;
return make_shared<Expression>(Expression::Kind::LITERAL, token, nullptr, nullptr); return make_shared<ExpressionLiteral>(token);
} }
return make_shared<Expression>(Expression::Kind::INVALID, token, nullptr, nullptr); return nullptr;
} }
shared_ptr<Expression> Parser::matchGrouping() { shared_ptr<Expression> Parser::matchExpressionGrouping() {
Token token = tokens.at(currentIndex); shared_ptr<Token> token = tokens.at(currentIndex);
if (token.getKind() == Token::Kind::LEFT_PAREN) { if (token->getKind() == Token::Kind::LEFT_PAREN) {
currentIndex++; currentIndex++;
shared_ptr<Expression> expression = term(); shared_ptr<Expression> expression = matchTerm();
// has grouped expression failed? // has grouped expression failed?
if (!expression->isValid()) if (expression == nullptr) {
return matchExpressionInvalid();
} else if(!expression->isValid()) {
return expression; return expression;
if (tokens.at(currentIndex)->getKind() == Token::Kind::RIGHT_PAREN) { } else if (tokens.at(currentIndex)->getKind() == Token::Kind::RIGHT_PAREN) {
currentIndex++; currentIndex++;
return make_shared<Expression>(Expression::Kind::GROUPING, token, expression, nullptr); return make_shared<ExpressionGrouping>(expression);
} else {
return matchExpressionInvalid();
} }
} }
return make_shared<Expression>(Expression::Kind::INVALID, token, nullptr, nullptr); return nullptr;
} }
shared_ptr<Expression> Parser::matchBinary(shared_ptr<Expression> left) { shared_ptr<Expression> Parser::matchExpressionBinary(shared_ptr<Expression> left) {
Token token = tokens.at(currentIndex); shared_ptr<Token> token = tokens.at(currentIndex);
if (token.isOfKind({Token::Kind::PLUS, Token::Kind::MINUS, Token::Kind::STAR, Token::Kind::SLASH, Token::Kind::PERCENT})) { if (token->isOfKind({Token::Kind::PLUS, Token::Kind::MINUS, Token::Kind::STAR, Token::Kind::SLASH, Token::Kind::PERCENT})) {
currentIndex++; currentIndex++;
shared_ptr<Expression> right = factor(); shared_ptr<Expression> right = matchFactor();
// Has right expression failed? if (right == nullptr) {
if (!right->isValid()) return matchExpressionInvalid();
} else if (!right->isValid()) {
return right; return right;
return make_shared<Expression>(Expression::Kind::BINARY, token, left, right); } else {
return make_shared<ExpressionBinary>(token, left, right);
}
} }
return make_shared<Expression>(Expression::Kind::INVALID, token, nullptr, nullptr); return nullptr;
}*/ }
shared_ptr<ExpressionInvalid> Parser::matchExpressionInvalid() { shared_ptr<ExpressionInvalid> Parser::matchExpressionInvalid() {
return make_shared<ExpressionInvalid>(tokens.at(currentIndex)); return make_shared<ExpressionInvalid>(tokens.at(currentIndex));

View File

@@ -22,13 +22,13 @@ private:
shared_ptr<StatementInvalid> matchStatementInvalid(); shared_ptr<StatementInvalid> matchStatementInvalid();
shared_ptr<Expression> nextExpression(); shared_ptr<Expression> nextExpression();
/*shared_ptr<Expression> term(); // +, - shared_ptr<Expression> matchTerm(); // +, -
shared_ptr<Expression> factor(); // *, /, % shared_ptr<Expression> matchFactor(); // *, /, %
shared_ptr<Expression> primary(); // integer, () shared_ptr<Expression> matchPrimary(); // integer, ()
shared_ptr<Expression> matchInteger(); shared_ptr<Expression> matchExpressionLiteral();
shared_ptr<Expression> matchGrouping(); shared_ptr<Expression> matchExpressionGrouping();
shared_ptr<Expression> matchBinary(shared_ptr<Expression> left);*/ shared_ptr<Expression> matchExpressionBinary(shared_ptr<Expression> left);
shared_ptr<ExpressionInvalid> matchExpressionInvalid(); shared_ptr<ExpressionInvalid> matchExpressionInvalid();
bool matchesTokenKinds(vector<Token::Kind> kinds); bool matchesTokenKinds(vector<Token::Kind> kinds);