Basic expression parsing
This commit is contained in:
@@ -1,14 +1,95 @@
|
|||||||
#include "Expression.h"
|
#include "Expression.h"
|
||||||
|
|
||||||
ExpressionInvalid Expression::Invalid = ExpressionInvalid();
|
std::shared_ptr<Expression> Expression::Invalid = std::make_shared<Expression>(Expression::Kind::INVALID, Token::Invalid, nullptr, nullptr);
|
||||||
|
|
||||||
std::string ExpressionInvalid::toString() {
|
Expression::Expression(Kind kind, Token token, shared_ptr<Expression> left, shared_ptr<Expression> right) {
|
||||||
return "Invalid";
|
switch (kind) {
|
||||||
|
case LITERAL:
|
||||||
|
setupLiteral(token);
|
||||||
|
break;
|
||||||
|
case BINARY:
|
||||||
|
setupBinary(token, left, right);
|
||||||
|
break;
|
||||||
|
case INVALID:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*ExpressionInteger::ExpressionInteger(Token token) {
|
void Expression::setupLiteral(Token token) {
|
||||||
|
bool isKindValid = token.isOneOf({Token::Kind::INTEGER});
|
||||||
|
if (!isKindValid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
kind = LITERAL;
|
||||||
|
integer = stoi(token.getLexme());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ExpressionInteger::toString() {
|
void Expression::setupBinary(Token token, shared_ptr<Expression> left, shared_ptr<Expression> right) {
|
||||||
return "INTEGER";
|
bool isKindValid = token.isOneOf({Token::Kind::PLUS, Token::Kind::MINUS, Token::Kind::STAR, Token::Kind::SLASH, Token::Kind::PERCENT});
|
||||||
}*/
|
bool isLeftValid = left != nullptr && left->getKind() != Kind::INVALID;
|
||||||
|
bool isRightValid = right != nullptr && right->getKind() != Kind::INVALID;
|
||||||
|
|
||||||
|
if (!isKindValid || !isLeftValid || !isRightValid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
kind = BINARY;
|
||||||
|
|
||||||
|
switch (token.getKind()) {
|
||||||
|
case Token::Kind::PLUS:
|
||||||
|
operation = ADD;
|
||||||
|
break;
|
||||||
|
case Token::Kind::MINUS:
|
||||||
|
operation = SUB;
|
||||||
|
break;
|
||||||
|
case Token::Kind::STAR:
|
||||||
|
operation = MUL;
|
||||||
|
break;
|
||||||
|
case Token::Kind::SLASH:
|
||||||
|
operation = DIV;
|
||||||
|
break;
|
||||||
|
case Token::Kind::PERCENT:
|
||||||
|
operation = MOD;
|
||||||
|
break;
|
||||||
|
case Token::Kind::INVALID:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->left = left;
|
||||||
|
this->right = right;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expression::Kind Expression::getKind() {
|
||||||
|
return kind;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Expression::operator==(Expression const& other) {
|
||||||
|
return kind == other.kind;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Expression::operator!=(Expression const& other) {
|
||||||
|
return kind != other.kind;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Expression::toString() {
|
||||||
|
switch (kind) {
|
||||||
|
case LITERAL:
|
||||||
|
return to_string(integer);
|
||||||
|
case BINARY:
|
||||||
|
switch (operation) {
|
||||||
|
case ADD:
|
||||||
|
return "<+ " + left->toString() + " " + right->toString() + ">";
|
||||||
|
case SUB:
|
||||||
|
return "<- " + left->toString() + " " + right->toString() + ">";
|
||||||
|
case MUL:
|
||||||
|
return "<* " + left->toString() + " " + right->toString() + ">";
|
||||||
|
case DIV:
|
||||||
|
return "</ " + left->toString() + " " + right->toString() + ">";
|
||||||
|
case MOD:
|
||||||
|
return "<% " + left->toString() + " " + right->toString() + ">";
|
||||||
|
case NONE:
|
||||||
|
return "NONE";
|
||||||
|
}
|
||||||
|
case INVALID:
|
||||||
|
return "INVALID";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,23 +3,43 @@
|
|||||||
|
|
||||||
#include "Token.h"
|
#include "Token.h"
|
||||||
|
|
||||||
class ExpressionInvalid;
|
using namespace std;
|
||||||
|
|
||||||
class Expression {
|
class Expression {
|
||||||
public:
|
public:
|
||||||
static ExpressionInvalid Invalid;
|
enum Kind {
|
||||||
|
LITERAL,
|
||||||
|
BINARY,
|
||||||
|
INVALID
|
||||||
|
};
|
||||||
|
|
||||||
virtual std::string toString() = 0;
|
enum Operation {
|
||||||
};
|
ADD,
|
||||||
|
SUB,
|
||||||
|
MUL,
|
||||||
|
DIV,
|
||||||
|
MOD,
|
||||||
|
NONE
|
||||||
|
};
|
||||||
|
|
||||||
class ExpressionInvalid {
|
private:
|
||||||
|
Kind kind = INVALID;
|
||||||
|
int64_t integer = 0;
|
||||||
|
Operation operation = NONE;
|
||||||
|
shared_ptr<Expression> left = nullptr;
|
||||||
|
shared_ptr<Expression> right = nullptr;
|
||||||
|
|
||||||
};
|
void setupLiteral(Token token);
|
||||||
|
void setupBinary(Token token, shared_ptr<Expression> left, shared_ptr<Expression> right);
|
||||||
|
|
||||||
/*class ExpressionInteger: Expression {
|
|
||||||
public:
|
public:
|
||||||
ExpressionInteger(Token token);
|
Expression(Kind kind, Token token, shared_ptr<Expression> left, shared_ptr<Expression> right);
|
||||||
std::string toString() override;
|
Kind getKind();
|
||||||
};*/
|
bool operator==(Expression const& other);
|
||||||
|
bool operator!=(Expression const& other);
|
||||||
|
string toString();
|
||||||
|
|
||||||
|
static shared_ptr<Expression> Invalid;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,24 +1,61 @@
|
|||||||
#include "Parser.h"
|
#include "Parser.h"
|
||||||
|
|
||||||
Parser::Parser(std::vector<Token> tokens) : tokens(tokens) {
|
Parser::Parser(vector<Token> tokens): tokens(tokens) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Expression Parser::getExpression() {
|
shared_ptr<Expression> Parser::getExpression() {
|
||||||
return term();
|
return term();
|
||||||
}*/
|
}
|
||||||
|
|
||||||
/*Expression Parser::term() {
|
shared_ptr<Expression> Parser::term() {
|
||||||
|
shared_ptr<Expression> expression = factor();
|
||||||
|
|
||||||
}*/
|
while (tokens.at(currentIndex).isOneOf({Token::Kind::PLUS, Token::Kind::MINUS})) {
|
||||||
|
expression = matchBinary(expression);
|
||||||
|
}
|
||||||
|
|
||||||
/*Expression Parser::primary() {
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
}*/
|
shared_ptr<Expression> Parser::factor() {
|
||||||
|
shared_ptr<Expression> expression = primary();
|
||||||
|
|
||||||
Expression Parser::matchInteger() {
|
while (tokens.at(currentIndex).isOneOf({Token::Kind::STAR, Token::Kind::SLASH, Token::Kind::PERCENT})) {
|
||||||
//Token token = tokens.at(currentIndex);
|
expression = matchBinary(expression);
|
||||||
//if (token.getKind() == Token::Kind::INTEGER)
|
}
|
||||||
// ExpressionInteger(token);
|
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<Expression> Parser::primary() {
|
||||||
|
shared_ptr<Expression> expression = Expression::Invalid;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if((expression = matchInteger()) != Expression::Invalid)
|
||||||
|
break;
|
||||||
|
|
||||||
|
} while(false);
|
||||||
|
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<Expression> Parser::matchInteger() {
|
||||||
|
Token token = tokens.at(currentIndex);
|
||||||
|
if (token.getKind() == Token::Kind::INTEGER) {
|
||||||
|
currentIndex++;
|
||||||
|
return make_shared<Expression>(Expression::Kind::LITERAL, token, nullptr, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Expression::Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<Expression> Parser::matchBinary(shared_ptr<Expression> left) {
|
||||||
|
Token token = tokens.at(currentIndex);
|
||||||
|
if (token.isOneOf({Token::Kind::PLUS, Token::Kind::MINUS, Token::Kind::STAR, Token::Kind::SLASH, Token::Kind::PERCENT})) {
|
||||||
|
currentIndex++;
|
||||||
|
shared_ptr<Expression> right = factor();
|
||||||
|
return make_shared<Expression>(Expression::Kind::BINARY, token, left, right);
|
||||||
|
}
|
||||||
|
|
||||||
return Expression::Invalid;
|
return Expression::Invalid;
|
||||||
}
|
}
|
||||||
16
src/Parser.h
16
src/Parser.h
@@ -5,19 +5,23 @@
|
|||||||
#include "Token.h"
|
#include "Token.h"
|
||||||
#include "Expression.h"
|
#include "Expression.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
class Parser {
|
class Parser {
|
||||||
private:
|
private:
|
||||||
std::vector<Token> tokens;
|
vector<Token> tokens;
|
||||||
int currentIndex = 0;
|
int currentIndex = 0;
|
||||||
|
|
||||||
//Expression term();
|
shared_ptr<Expression> term(); // +, -
|
||||||
//Expression primary();
|
shared_ptr<Expression> factor(); // *, /, %
|
||||||
|
shared_ptr<Expression> primary();
|
||||||
|
|
||||||
Expression matchInteger();
|
shared_ptr<Expression> matchInteger();
|
||||||
|
shared_ptr<Expression> matchBinary(shared_ptr<Expression> left);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Parser(std::vector<Token> tokens);
|
Parser(vector<Token> tokens);
|
||||||
//Expression getExpression();
|
shared_ptr<Expression> getExpression();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -21,6 +21,15 @@ bool Token::operator!=(Token const& other) {
|
|||||||
return kind != other.kind;
|
return kind != other.kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Token::isOneOf(std::vector<Kind> kinds) {
|
||||||
|
for (Kind &kind : kinds) {
|
||||||
|
if (kind == this->kind)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
std::string Token::toString() {
|
std::string Token::toString() {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case PLUS:
|
case PLUS:
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ public:
|
|||||||
std::string getLexme();
|
std::string getLexme();
|
||||||
bool operator==(Token const& other);
|
bool operator==(Token const& other);
|
||||||
bool operator!=(Token const& other);
|
bool operator!=(Token const& other);
|
||||||
|
bool isOneOf(std::vector<Kind> kinds);
|
||||||
std::string toString();
|
std::string toString();
|
||||||
|
|
||||||
static Token Invalid;
|
static Token Invalid;
|
||||||
|
|||||||
12
src/main.cpp
12
src/main.cpp
@@ -1,7 +1,13 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "Lexer.h"
|
|
||||||
#include "Token.h"
|
#include "Token.h"
|
||||||
|
#include "Lexer.h"
|
||||||
|
|
||||||
|
#include "Expression.h"
|
||||||
|
#include "Parser.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
std::string readFile(std::string fileName) {
|
std::string readFile(std::string fileName) {
|
||||||
std::ifstream file(fileName.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
|
std::ifstream file(fileName.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
|
||||||
@@ -30,5 +36,9 @@ int main(int argc, char **argv) {
|
|||||||
std::cout << token.toString() << " ";
|
std::cout << token.toString() << " ";
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
Parser parser(tokens);
|
||||||
|
shared_ptr<Expression> expression = parser.getExpression();
|
||||||
|
cout << expression->toString() << endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user