Equality and comparison

This commit is contained in:
Rafał Grodziński
2025-06-04 17:24:30 +09:00
parent 36e798ae3f
commit 4feeb0f8af
7 changed files with 118 additions and 10 deletions

View File

@@ -21,6 +21,24 @@ string Expression::toString() {
ExpressionBinary::ExpressionBinary(shared_ptr<Token> token, shared_ptr<Expression> left, shared_ptr<Expression> right):
Expression(Expression::Kind::BINARY), left(left), right(right) {
switch (token->getKind()) {
case Token::Kind::EQUAL:
operation = EQUAL;
break;
case Token::Kind::NOT_EQUAL:
operation = NOT_EQUAL;
break;
case Token::Kind::LESS:
operation = LESS;
break;
case Token::Kind::LESS_EQUAL:
operation = LESS_EQUAL;
break;
case Token::Kind::GREATER:
operation = GREATER;
break;
case Token::Kind::GREATER_EQUAL:
operation = GREATER_EQUAL;
break;
case Token::Kind::PLUS:
operation = ADD;
break;
@@ -55,16 +73,28 @@ shared_ptr<Expression> ExpressionBinary::getRight() {
string ExpressionBinary::toString() {
switch (operation) {
case EQUAL:
return "{= " + left->toString() + " " + right->toString() + "}";
case NOT_EQUAL:
return "{!= " + left->toString() + " " + right->toString() + "}";
case LESS:
return "{< " + left->toString() + " " + right->toString() + "}";
case LESS_EQUAL:
return "{<= " + left->toString() + " " + right->toString() + "}";
case GREATER:
return "{> " + left->toString() + " " + right->toString() + "}";
case GREATER_EQUAL:
return "{<= " + left->toString() + " " + right->toString() + "}";
case ADD:
return "<+ " + left->toString() + " " + right->toString() + ">";
return "{+ " + left->toString() + " " + right->toString() + "}";
case SUB:
return "<- " + left->toString() + " " + right->toString() + ">";
return "{- " + left->toString() + " " + right->toString() + "}";
case MUL:
return "<* " + left->toString() + " " + right->toString() + ">";
return "{* " + left->toString() + " " + right->toString() + "}";
case DIV:
return "</ " + left->toString() + " " + right->toString() + ">";
return "{/ " + left->toString() + " " + right->toString() + "}";
case MOD:
return "<% " + left->toString() + " " + right->toString() + ">";
return "{% " + left->toString() + " " + right->toString() + "}";
}
}

View File

@@ -47,6 +47,12 @@ public:
class ExpressionBinary: public Expression {
public:
enum Operation {
EQUAL,
NOT_EQUAL,
LESS,
LESS_EQUAL,
GREATER,
GREATER_EQUAL,
ADD,
SUB,
MUL,

View File

@@ -120,7 +120,7 @@ shared_ptr<Token> Lexer::nextToken() {
if (token != nullptr)
return token;
// logical
// comparison
token = match(Token::Kind::NOT_EQUAL, "!=", false);
if (token != nullptr)
return token;

View File

@@ -122,7 +122,33 @@ shared_ptr<StatementInvalid> Parser::matchStatementInvalid() {
// Expression
//
shared_ptr<Expression> Parser::nextExpression() {
return matchTerm();
return matchEquality();
}
shared_ptr<Expression> Parser::matchEquality() {
shared_ptr<Expression> expression = matchTerm();
if (expression == nullptr || !expression->isValid())
return expression;
while (tokens.at(currentIndex)->isOfKind(Token::tokensEquality)) {
// comaprison
expression = matchExpressionBinary(expression);
}
return expression;
}
shared_ptr<Expression> Parser::matchComparison() {
shared_ptr<Expression> expression = matchTerm();
if (expression == nullptr || !expression->isValid())
return expression;
while (tokens.at(currentIndex)->isOfKind(Token::tokensComparison)) {
// term
expression = matchExpressionBinary(expression);
}
return expression;
}
shared_ptr<Expression> Parser::matchTerm() {
@@ -130,7 +156,8 @@ shared_ptr<Expression> Parser::matchTerm() {
if (expression == nullptr || !expression->isValid())
return expression;
while (tokens.at(currentIndex)->isOfKind({Token::Kind::PLUS, Token::Kind::MINUS})) {
while (tokens.at(currentIndex)->isOfKind(Token::tokensTerm)) {
// factor
expression = matchExpressionBinary(expression);
}
@@ -142,7 +169,8 @@ shared_ptr<Expression> Parser::matchFactor() {
if (expression == nullptr || !expression->isValid())
return expression;
while (tokens.at(currentIndex)->isOfKind({Token::Kind::STAR, Token::Kind::SLASH, Token::Kind::PERCENT})) {
while (tokens.at(currentIndex)->isOfKind(Token::tokensFactor)) {
// unary
expression = matchExpressionBinary(expression);
}
@@ -196,7 +224,7 @@ shared_ptr<Expression> Parser::matchExpressionGrouping() {
shared_ptr<Expression> Parser::matchExpressionBinary(shared_ptr<Expression> left) {
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::tokensBinary)) {
currentIndex++;
shared_ptr<Expression> right = matchFactor();
if (right == nullptr) {

View File

@@ -22,6 +22,8 @@ private:
shared_ptr<StatementInvalid> matchStatementInvalid();
shared_ptr<Expression> nextExpression();
shared_ptr<Expression> matchEquality(); // =, !=
shared_ptr<Expression> matchComparison(); // <, <=, >, >=
shared_ptr<Expression> matchTerm(); // +, -
shared_ptr<Expression> matchFactor(); // *, /, %
shared_ptr<Expression> matchPrimary(); // integer, ()

View File

@@ -1,5 +1,41 @@
#include "Token.h"
vector<Token::Kind> Token::tokensEquality = {
Token::Kind::EQUAL,
Token::Kind::NOT_EQUAL
};
vector<Token::Kind> Token::tokensComparison = {
Token::Kind::LESS,
Token::Kind::LESS_EQUAL,
Token::Kind::GREATER,
Token::Kind::GREATER_EQUAL
};
vector<Token::Kind> Token::tokensTerm = {
Token::Kind::PLUS,
Token::Kind::MINUS
};
vector<Token::Kind> Token::tokensFactor = {
Token::Kind::STAR,
Token::Kind::SLASH,
Token::Kind::PERCENT
};
vector<Token::Kind> Token::tokensBinary = {
Token::Kind::EQUAL,
Token::Kind::NOT_EQUAL,
Token::Kind::LESS,
Token::Kind::LESS_EQUAL,
Token::Kind::GREATER,
Token::Kind::GREATER_EQUAL,
Token::Kind::PLUS,
Token::Kind::MINUS,
Token::Kind::STAR,
Token::Kind::SLASH,
Token::Kind::PERCENT
};
Token::Token(Kind kind, string lexme, int line, int column):
kind(kind), lexme(lexme), line(line), column(column) {
}

View File

@@ -45,6 +45,12 @@ private:
int column;
public:
static vector<Token::Kind> tokensEquality;
static vector<Token::Kind> tokensComparison;
static vector<Token::Kind> tokensTerm;
static vector<Token::Kind> tokensFactor;
static vector<Token::Kind> tokensBinary;
Token(Kind kind, string lexme, int line, int column);
Kind getKind();
string getLexme();