From 45409c781a9e35df68c43b1e2f028d30bf90c0a0 Mon Sep 17 00:00:00 2001 From: Patrick Schönberger Date: Wed, 28 Jul 2021 09:07:53 +0200 Subject: Initial commit --- src/MyListener.h | 64 +++++++++++++ src/main.cpp | 50 ++++++++++ src/repr.h | 155 +++++++++++++++++++++++++++++++ src/repr_get.h | 154 +++++++++++++++++++++++++++++++ src/toc.h | 274 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 697 insertions(+) create mode 100644 src/MyListener.h create mode 100644 src/main.cpp create mode 100644 src/repr.h create mode 100644 src/repr_get.h create mode 100644 src/toc.h (limited to 'src') diff --git a/src/MyListener.h b/src/MyListener.h new file mode 100644 index 0000000..433fa7a --- /dev/null +++ b/src/MyListener.h @@ -0,0 +1,64 @@ +#include "TocBaseListener.h" + +#include + +using namespace std; + +class MyListener : public TocBaseListener { + void enterVarDecl(TocParser::VarDeclContext * ctx) { + cout + << ctx->var()->type()->getText() + << " " + << ctx->var()->varName()->getText(); + + if (ctx->var()->expr() != nullptr) { + cout << " = "; + } + } + void exitVarDecl(TocParser::VarDeclContext * ctx) { + cout << ";" << endl; + } + + void enterFuncDecl(TocParser::FuncDeclContext * ctx) { + cout + << ctx->type()->getText() + << " " + << ctx->funcName()->getText() + << "("; + + if (ctx->parameter()->firstParameter() != nullptr) { + cout + << ctx->parameter()->firstParameter()->var()->type()->getText() + << " " + << ctx->parameter()->firstParameter()->var()->varName()->getText(); + } + + for (auto * p : ctx->parameter()->additionalParameter()) { + cout + << ", " + << p->var()->type()->getText() + << " " + << p->var()->varName()->getText(); + } + + cout + << ")"; + } + + void enterBody(TocParser::BodyContext * ctx) { + cout + << "{" << endl; + } + void exitBody(TocParser::BodyContext * ctx) { + cout + << "}" << endl; + } + + void enterIfCond(TocParser::IfCondContext * ctx) { + cout + << "if ("; + enterExpr(ctx->expr()); + cout + << ")"; + } +}; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..a7742ac --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,50 @@ +#include +#include + +#include "TocLexer.h" +#include "TocParser.h" + +#include "toc.h" +#include "repr.h" +#include "repr_get.h" + +using namespace antlr4; + + +int main(int argc, const char * argv[]) { + std::ifstream ifs("test.toc"); + + ANTLRInputStream input(ifs); + + TocLexer lexer(&input); + CommonTokenStream tokens(&lexer); + + TocParser parser(&tokens); + TocParser::ProgContext * prog = parser.prog(); + tree::ParseTree * tree = prog; + + if (parser.getNumberOfSyntaxErrors() > 0) { + std::cerr << "Parsing error" << std::endl; + return 1; + } + + std::string s = tree->toStringTree(&parser) + "\n"; + + //std::cout << "Parse Tree: " << s << std::endl; + + //toc(std::cout, prog); + + //std::ofstream ofs("output.c"); + //toc(ofs, prog); + //ofs.close(); + + Program prg = getProgram(prog); + std::cout << "Variables:\n"; + for (auto v : prg.variables) + std::cout << " " << v.name << endl; + std::cout << "Functions:\n"; + for (auto f : prg.functions) + std::cout << " " << f.name << endl; + + return 0; +} \ No newline at end of file diff --git a/src/repr.h b/src/repr.h new file mode 100644 index 0000000..ce176ef --- /dev/null +++ b/src/repr.h @@ -0,0 +1,155 @@ +#pragma once + +#include +#include +#include + +#include "TocParser.h" + +using namespace std; + +struct Type; +struct Variable; +struct Body; +struct Function; +struct Struct; +struct Program; +struct CallExpr; +struct LiteralExpr; +struct VariableExpr; +struct BracketsExpr; +struct OperatorExpr; +struct DotExpr; +struct Expr; +struct IfStmt; +struct WhileStmt; +struct ReturnStmt; +struct AssignStmt; +struct Stmt; + + +struct Type { + std::string name; +}; + +struct Variable { + std::string name; + Type type; +}; + +struct Body { + std::vector variables; + std::vector statements; +}; + +struct Function { + std::string name; + std::vector parameters; + Body body; +}; + +struct Struct { + std::string name; + std::vector members; + std::vector methods; +}; + +struct Program { + std::vector variables; + std::vector structs; + std::vector functions; +}; + +enum class ExprType { + Call, Literal, Variable, Brackets, Operator, Dot +}; + +struct CallExpr { + Function function; + std::vector arguments; +}; + +struct LiteralExpr { + int i; +}; + +struct VariableExpr { + std::string name; +}; + +struct BracketsExpr { + BracketsExpr() {} + BracketsExpr(const BracketsExpr &) {} + BracketsExpr & operator=(const BracketsExpr &) {return *this;}; + std::unique_ptr lexpr; + std::unique_ptr rexpr; +}; + +enum class OperatorType { + Plus, Minus, Multiply, Divide, + Equals, NotEquals, + LessThan, GreaterThan +}; + +struct OperatorExpr { + OperatorExpr() {} + OperatorExpr(const OperatorExpr &) {} + OperatorExpr & operator=(const OperatorExpr &) {return *this;}; + std::unique_ptr lexpr; + std::unique_ptr rexpr; + OperatorType type; +}; + +struct DotExpr { + DotExpr() {} + DotExpr(const DotExpr &) {} + DotExpr & operator=(const DotExpr &) {return *this;}; + std::unique_ptr lexpr; + std::string name; +}; + +struct Expr { + ExprType type; + + CallExpr _call; + LiteralExpr _literal; + VariableExpr _variable; + BracketsExpr _brackets; + OperatorExpr _operator; + DotExpr _dot; +}; + +enum class StmtType { + If, While, Return, Assign, Expr +}; + +struct IfStmt { + Expr condition; + Body body; +}; + +struct WhileStmt { + Expr condition; + Body body; +}; + +struct ReturnStmt { + Expr expr; +}; + +struct AssignStmt { + Expr lexpr; + Expr rexpr; +}; + +struct Stmt { + StmtType type; + + IfStmt _if; + WhileStmt _while; + ReturnStmt _return; + AssignStmt _assign; + Expr _expr; +}; + + diff --git a/src/repr_get.h b/src/repr_get.h new file mode 100644 index 0000000..67ff40f --- /dev/null +++ b/src/repr_get.h @@ -0,0 +1,154 @@ +#pragma once + +#include "repr.h" + +Type getType(TocParser::TypeContext * ctx); +Variable getVariable(TocParser::VarContext * ctx); +Body getBody(TocParser::BodyContext * ctx); +Function getFunction(TocParser::FuncContext * ctx); +Struct getStruct(TocParser::StructDeclContext * ctx); +Program getProgram(TocParser::ProgContext * ctx); +OperatorExpr getOperatorExpr(TocParser::OperatorExprContext * ctx); +Expr getExpression(TocParser::ExprContext * ctx); +Stmt getStmt(TocParser::StmtContext * ctx); + +Type getType(TocParser::TypeContext * ctx) { + Type result; + result.name = ctx->typeName()->NAME()->toString(); + return result; +} +Variable getVariable(TocParser::VarContext * ctx) { + Variable result; + result.name = ctx->varName()->NAME()->toString(); + result.type = getType(ctx->type()); + return result; +} +Body getBody(TocParser::BodyContext * ctx) { + Body result; + for (auto s : ctx->stmt()) { + if (s->varDecl() != nullptr) { + result.variables.push_back(getVariable(s->varDecl()->var())); + } + else { + result.statements.push_back(getStmt(s)); + } + } + return result; +} +Function getFunction(TocParser::FuncContext * ctx) { + Function result; + result.name = ctx->funcName()->NAME()->toString(); + if (ctx->parameter()->firstParameter() != nullptr) { + result.parameters.push_back(getVariable(ctx->parameter()->firstParameter()->var())); + for (auto p : ctx->parameter()->additionalParameter()) + result.parameters.push_back(getVariable(p->var())); + } + result.body = getBody(ctx->body()); + return result; +} +Struct getStruct(TocParser::StructDeclContext * ctx) { + Struct result; + result.name = ctx->structName()->NAME()->toString(); + for (auto m : ctx->structMember()) { + if (m->structVar() != nullptr) { + result.members.push_back(getVariable(m->structVar()->var())); + } + if (m->structMethod() != nullptr) { + result.methods.push_back(getFunction(m->structMethod()->func())); + } + } + return result; +} +Program getProgram(TocParser::ProgContext * ctx) { + Program result; + for (auto d : ctx->decl()) { + if (d->varDecl() != nullptr) { + result.variables.push_back(getVariable(d->varDecl()->var())); + } + if (d->funcDecl() != nullptr) { + result.functions.push_back(getFunction(d->funcDecl()->func())); + } + if (d->structDecl() != nullptr) { + result.structs.push_back(getStruct(d->structDecl())); + } + } + return result; +} +OperatorExpr getOperatorExpr(TocParser::OperatorExprContext * ctx) { + OperatorExpr result; + //result.lexpr = getExpr(ctx->binaryOperator()->nonOpExpr(0)); + //result.rexpr = getExpr(ctx->binaryOperator()->nonOpExpr(1)); + std::string op = ctx->binaryOperator()->BINARY_OPERATOR(0)->toString(); + if (op == "+") result.type = OperatorType::Plus; + if (op == "-") result.type = OperatorType::Minus; + if (op == "*") result.type = OperatorType::Multiply; + if (op == "/") result.type = OperatorType::Divide; + if (op == "==") result.type = OperatorType::Equals; + if (op == "!=") result.type = OperatorType::NotEquals; + if (op == "<") result.type = OperatorType::LessThan; + if (op == ">") result.type = OperatorType::GreaterThan; + return result; +} +Expr getExpr(TocParser::ExprContext * ctx) { + Expr result; + if (ctx->funcCall() != nullptr) { + result.type = ExprType::Call; + for (auto e : ctx->funcCall()->expr()) + result._call.arguments.push_back(getExpr(e)); + //result._call.function = ctx->funcCall()->funcName(); + } + if (ctx->literal() != nullptr) { + result.type = ExprType::Literal; + result._literal.i = atoi(ctx->literal()->INTLIT()->toString().c_str()); + } + if (ctx->identifier() != nullptr) { + result.type = ExprType::Variable; + result._variable.name = ctx->identifier()->varName()->NAME()->toString(); + } + if (ctx->subscript() != nullptr) { + result.type = ExprType::Brackets; + //result._brackets.lexpr = getExpr(ctx->subscript()->nonSubscriptExpr()); + result._brackets.rexpr = std::make_unique(getExpr(ctx->subscript()->expr())); + } + if (ctx->memberAccess() != nullptr) { + result.type = ExprType::Dot; + //result._dot.lexpr = ctx->memberAccess()->identifier(0); + result._dot.name = ctx->memberAccess()->identifier(1)->varName()->NAME()->toString(); + } + if (ctx->operatorExpr() != nullptr) { + result.type = ExprType::Operator; + result._operator = getOperatorExpr(ctx->operatorExpr()); + } + return result; +} +Stmt getStmt(TocParser::StmtContext * ctx) { + Stmt result; + if (ctx->conditional() != nullptr) { + result.type = StmtType::If; + result._if.condition = getExpr(ctx->conditional()->ifCond()->expr()); + result._if.body = getBody(ctx->conditional()->ifCond()->body()); + } + if (ctx->loop() != nullptr) { + result.type = StmtType::While; + result._while.condition = getExpr(ctx->loop()->whileLoop()->expr()); + result._while.body = getBody(ctx->loop()->whileLoop()->body()); + } + if (ctx->assignment() != nullptr) { + result.type = StmtType::Assign; + //result._assign.lexpr = getExpr(ctx->assignment()->); + result._assign.rexpr = getExpr(ctx->assignment()->expr()); + } + if (ctx->returnStmt() != nullptr) { + result.type = StmtType::Return; + result._return.expr = getExpr(ctx->returnStmt()->expr()); + } + if (ctx->expr() != nullptr) { + result.type = StmtType::Expr; + result._expr = getExpr(ctx->expr()); + } + if (ctx->varDecl() != nullptr && ctx->varDecl()->var()->expr() != nullptr) { + result.type = StmtType::Assign; + result._assign.rexpr = getExpr(ctx->varDecl()->var()->expr()); + } + return result; +} \ No newline at end of file diff --git a/src/toc.h b/src/toc.h new file mode 100644 index 0000000..b36d878 --- /dev/null +++ b/src/toc.h @@ -0,0 +1,274 @@ +#pragma once + +#include + +#include "TocParser.h" + +void toc(std::ostream & o, TocParser::ProgContext * ctx); +void toc(std::ostream & o, TocParser::VarDeclContext * ctx); +void toc(std::ostream & o, TocParser::FuncContext * ctx); +void toc(std::ostream & o, TocParser::StructDeclContext * ctx); +void toc(std::ostream & o, TocParser::BodyContext * ctx); +void toc(std::ostream & o, TocParser::StmtContext * ctx); +void toc(std::ostream & o, TocParser::IfCondContext * ctx); +void toc(std::ostream & o, TocParser::WhileLoopContext * ctx); +void toc(std::ostream & o, TocParser::AssignmentContext * ctx); +void toc(std::ostream & o, TocParser::ReturnStmtContext * ctx); +void toc(std::ostream & o, TocParser::ExprContext * ctx); +void toc(std::ostream & o, TocParser::NonOpExprContext * ctx); +void toc(std::ostream & o, TocParser::NonSubscriptExprContext * ctx); +void toc(std::ostream & o, TocParser::FuncCallContext * ctx); +void toc(std::ostream & o, TocParser::IdentifierContext * ctx); +void toc(std::ostream & o, TocParser::LiteralContext * ctx); +void toc(std::ostream & o, TocParser::SubscriptContext * ctx); +void toc(std::ostream & o, TocParser::MemberAccessContext * ctx); +void toc(std::ostream & o, TocParser::ParenExprContext * ctx); +void toc(std::ostream & o, TocParser::BinaryOperatorContext * ctx); + +void toc_stub(std::ostream & o, TocParser::FuncContext * ctx); +void toc_stub(std::ostream & o, TocParser::StructDeclContext * ctx); + + +void toc(std::ostream & o, TocParser::ProgContext * ctx) { + for (auto * decl : ctx->decl()) { + /**/ if (decl->structDecl() != nullptr) toc_stub(o, decl->structDecl()); + else if (decl->funcDecl() != nullptr) toc_stub(o, decl->funcDecl()->func()); + } + for (auto * decl : ctx->decl()) { + if (decl->varDecl() != nullptr) { + toc(o, decl->varDecl()); + o << ";\n"; + } + else if (decl->structDecl() != nullptr) toc(o, decl->structDecl()); + else if (decl->funcDecl() != nullptr) toc(o, decl->funcDecl()->func()); + } +} +void toc(std::ostream & o, TocParser::VarDeclContext * ctx) { + o + << ctx->var()->type()->getText() + << " " + << ctx->var()->varName()->getText(); + + if (ctx->var()->expr() != nullptr) { + o << " = "; + toc(o, ctx->var()->expr()); + } +} +void toc(std::ostream & o, TocParser::FuncContext * ctx) { + o + << ctx->type()->getText() + << " " + << ctx->funcName()->getText() + << "("; + + if (ctx->parameter()->firstParameter() != nullptr) { + o + << ctx->parameter()->firstParameter()->var()->type()->getText() + << " " + << ctx->parameter()->firstParameter()->var()->varName()->getText(); + + for (auto * par : ctx->parameter()->additionalParameter()) { + o + << ", " + << par->var()->type()->getText() + << " " + << par->var()->varName()->getText(); + } + } + + o << ")\n{\n"; + + toc(o, ctx->body()); + + o << "}\n"; +} +void toc(std::ostream & o, TocParser::StructDeclContext * ctx) { + o + << "typedef struct " + << ctx->structName()->getText() + << "\n{\n"; + + for (auto * member : ctx->structMember()) { + if (member->structVar() != nullptr) { + o + << member->structVar()->var()->type()->getText() + << " " + << member->structVar()->var()->varName()->getText() + << ";\n"; + } + } + o << "} " + << ctx->structName()->getText() + << ";\n"; + for (auto * member : ctx->structMember()) { + if (member->structMethod() != nullptr) { + o + << member->structMethod()->func()->type()->getText() + << " " + << ctx->structName()->getText() + << "_" + << member->structMethod()->func()->funcName()->getText() + << "(" + << ctx->structName()->getText() + << " * this"; + + if (member->structMethod()->func()->parameter()->firstParameter() != nullptr) { + o + << ", " + << member->structMethod()->func()->parameter()->firstParameter()->var()->type()->getText() + << " " + << member->structMethod()->func()->parameter()->firstParameter()->var()->varName()->getText(); + + for (auto * par : member->structMethod()->func()->parameter()->additionalParameter()) { + o + << ", " + << par->var()->type()->getText() + << " " + << par->var()->varName()->getText(); + } + } + + o << ")\n{\n"; + + toc(o, member->structMethod()->func()->body()); + + o << "}\n"; + } + } +} +void toc(std::ostream & o, TocParser::BodyContext * ctx) { + for (auto * stmt : ctx->stmt()) { + toc(o, stmt); + o << "\n"; + } +} +void toc(std::ostream & o, TocParser::StmtContext * ctx) { + /**/ if (ctx->varDecl() != nullptr) toc(o, ctx->varDecl()); + else if (ctx->conditional() != nullptr) toc(o, ctx->conditional()->ifCond()); + else if (ctx->loop() != nullptr) toc(o, ctx->loop()->whileLoop()); + else if (ctx->assignment() != nullptr) toc(o, ctx->assignment()); + else if (ctx->returnStmt() != nullptr) toc(o, ctx->returnStmt()); + else if (ctx->expr() != nullptr) toc(o, ctx->expr()); + + if (ctx->conditional() == nullptr && ctx->loop() == nullptr) + o << ";"; +} +void toc(std::ostream & o, TocParser::IfCondContext * ctx) { + o << "if ("; + toc(o, ctx->expr()); + o << ")\n{\n"; + toc(o, ctx->body()); + o << "}\n"; +} +void toc(std::ostream & o, TocParser::WhileLoopContext * ctx) { + o << "while ("; + toc(o, ctx->expr()); + o << ")\n{\n"; + toc(o, ctx->body()); + o << "}\n"; +} +void toc(std::ostream & o, TocParser::AssignmentContext * ctx) { + toc(o, ctx->identifier()); + o << " = "; + toc(o, ctx->expr()); +} +void toc(std::ostream & o, TocParser::ReturnStmtContext * ctx) { + o << "return "; + toc(o, ctx->expr()); +} +void toc(std::ostream & o, TocParser::ExprContext * ctx) { + /**/ if (ctx->funcCall() != nullptr) toc(o, ctx->funcCall()); + else if (ctx->identifier() != nullptr) toc(o, ctx->identifier()); + else if (ctx->literal() != nullptr) toc(o, ctx->literal()); + else if (ctx->subscript() != nullptr) toc(o, ctx->subscript()); + else if (ctx->memberAccess() != nullptr) toc(o, ctx->memberAccess()); + else if (ctx->parenExpr() != nullptr) toc(o, ctx->parenExpr()); + else if (ctx->operatorExpr() != nullptr) toc(o, ctx->operatorExpr()->binaryOperator()); +} +void toc(std::ostream & o, TocParser::NonOpExprContext * ctx) { + /**/ if (ctx->funcCall() != nullptr) toc(o, ctx->funcCall()); + else if (ctx->identifier() != nullptr) toc(o, ctx->identifier()); + else if (ctx->literal() != nullptr) toc(o, ctx->literal()); + else if (ctx->subscript() != nullptr) toc(o, ctx->subscript()); + else if (ctx->memberAccess() != nullptr) toc(o, ctx->memberAccess()); + else if (ctx->parenExpr() != nullptr) toc(o, ctx->parenExpr()); +} +void toc(std::ostream & o, TocParser::NonSubscriptExprContext * ctx) { + /**/ if (ctx->funcCall() != nullptr) toc(o, ctx->funcCall()); + else if (ctx->identifier() != nullptr) toc(o, ctx->identifier()); + else if (ctx->memberAccess() != nullptr) toc(o, ctx->memberAccess()); + else if (ctx->parenExpr() != nullptr) toc(o, ctx->parenExpr()); +} +void toc(std::ostream & o, TocParser::FuncCallContext * ctx) { + o + << ctx->funcName()->getText() + << "("; + for (int i = 0; i < ctx->expr().size(); i++) { + if (i != 0) o << ", "; + toc(o, ctx->expr(i)); + } + o << ")"; +} +void toc(std::ostream & o, TocParser::IdentifierContext * ctx) { + o << ctx->getText(); +} +void toc(std::ostream & o, TocParser::LiteralContext * ctx) { + if (ctx->INTLIT() != nullptr) o << ctx->INTLIT()->getText(); +} +void toc(std::ostream & o, TocParser::SubscriptContext * ctx) { + toc(o, ctx->nonSubscriptExpr()); + o << "["; + toc(o, ctx->expr()); + o << "]"; +} +void toc(std::ostream & o, TocParser::MemberAccessContext * ctx) { + toc(o, ctx->identifier(0)); + o << "."; + toc(o, ctx->identifier(1)); +} +void toc(std::ostream & o, TocParser::ParenExprContext * ctx) { + o << "("; + toc(o, ctx->expr()); + o << ")"; +} +void toc(std::ostream & o, TocParser::BinaryOperatorContext * ctx) { + for (int i = 0; i < ctx->BINARY_OPERATOR().size(); i++) { + toc(o, ctx->nonOpExpr(i)); + o + << " " + << ctx->BINARY_OPERATOR(i)->getText() + << " "; + toc(o, ctx->nonOpExpr(i + 1)); + } +} + +void toc_stub(std::ostream & o, TocParser::FuncContext * ctx) { + o + << ctx->type()->getText() + << " " + << ctx->funcName()->getText() + << "("; + + if (ctx->parameter()->firstParameter() != nullptr) { + o + << ctx->parameter()->firstParameter()->var()->type()->getText() + << " " + << ctx->parameter()->firstParameter()->var()->varName()->getText(); + + for (auto * par : ctx->parameter()->additionalParameter()) { + o + << ", " + << par->var()->type()->getText() + << " " + << par->var()->varName()->getText(); + } + } + + o << ");\n"; +} +void toc_stub(std::ostream & o, TocParser::StructDeclContext * ctx) { + o + << "struct " + << ctx->structName()->getText() + << ";\n"; +} -- cgit v1.2.3