Rough implementation of ASTPrinter complete with nasty shared_ptr syntax :)
This commit is contained in:
parent
c5f981321c
commit
d909e546f2
18
headers/ASTPrinter.h
Normal file
18
headers/ASTPrinter.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Expression.h"
|
||||||
|
#include <string>
|
||||||
|
#include <initializer_list>
|
||||||
|
|
||||||
|
class ASTPrinter : public Visitor<std::string>
|
||||||
|
{
|
||||||
|
std::string visitBinaryExpr(BinaryExpr<std::string>* expression) override;
|
||||||
|
// std::string visitGroupingExpr(GroupingExpr<std::string> expression);
|
||||||
|
std::string visitLiteralExpr(LiteralExpr<std::string>* expression) override;
|
||||||
|
std::string visitUnaryExpr(UnaryExpr<std::string>* expression) override;
|
||||||
|
public:
|
||||||
|
int test = 10;
|
||||||
|
std::string print(Expr<std::string>* expr);
|
||||||
|
private:
|
||||||
|
std::string parenthesize(std::string name, std::vector<std::shared_ptr<Expr<std::string> > > exprs);
|
||||||
|
|
||||||
|
};
|
||||||
@ -5,45 +5,74 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Lexer.h"
|
#include "Lexer.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct Visitor;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
struct Expr{
|
struct Expr{
|
||||||
virtual ~Expr()
|
virtual T accept(Visitor<T>* visitor) = 0;
|
||||||
{
|
virtual ~Expr(){}
|
||||||
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BinaryExpr : Expr
|
template <typename T>
|
||||||
|
struct BinaryExpr : Expr<T>
|
||||||
{
|
{
|
||||||
const Expr left;
|
const std::shared_ptr<Expr<T> > left;
|
||||||
const Token oper;
|
const Token oper;
|
||||||
const Expr right;
|
const std::shared_ptr<Expr<T> > right;
|
||||||
|
|
||||||
BinaryExpr(Expr left, Token oper, Expr right) : left(left), oper(oper), right(right)
|
BinaryExpr(std::shared_ptr<Expr<T> > left, Token oper, std::shared_ptr<Expr<T> > right) : left(left), oper(oper), right(right)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
T accept(Visitor<T>* visitor) override{
|
||||||
struct GroupingExpr : Expr
|
return visitor->visitBinaryExpr(this);
|
||||||
{
|
|
||||||
const Expr expression;
|
|
||||||
|
|
||||||
GroupingExpr(Expr expression) : expression(expression)
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
struct LiteralExpr : Expr
|
//template <typename T>
|
||||||
|
//struct GroupingExpr : Expr<T>, Visitor<T>
|
||||||
|
//{
|
||||||
|
// Expr<T> expression;
|
||||||
|
//
|
||||||
|
// GroupingExpr(Expr<T> expression) : expression(expression)
|
||||||
|
// {
|
||||||
|
// }
|
||||||
|
// T accept(Visitor<T> visitor){
|
||||||
|
// return visitor.visitGroupingExpr(this);
|
||||||
|
// }
|
||||||
|
//};
|
||||||
|
template <typename T>
|
||||||
|
struct LiteralExpr : Expr<T>
|
||||||
{
|
{
|
||||||
const std::string value;
|
const std::string value;
|
||||||
|
|
||||||
LiteralExpr(std::string value) : value(value)
|
LiteralExpr(std::string value) : value(value)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
T accept(Visitor<T>* visitor) override{
|
||||||
struct UnaryExpr : Expr
|
return visitor->visitLiteralExpr(this);
|
||||||
{
|
|
||||||
const Token oper;
|
|
||||||
const Expr right;
|
|
||||||
|
|
||||||
UnaryExpr(Token oper, Expr right) : oper(oper), right(right)
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
template <typename T>
|
||||||
|
struct UnaryExpr : Expr<T>
|
||||||
|
{
|
||||||
|
const Token oper;
|
||||||
|
const std::shared_ptr<Expr<T> > right;
|
||||||
|
|
||||||
|
UnaryExpr(Token oper, std::shared_ptr<Expr<T> > right) : oper(oper), right(right)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
T accept(Visitor<T>* visitor) override{
|
||||||
|
return visitor->visitUnaryExpr(this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
////
|
||||||
|
template <typename T>
|
||||||
|
struct Visitor
|
||||||
|
{
|
||||||
|
virtual T visitBinaryExpr(BinaryExpr<T>* expression) = 0;
|
||||||
|
// virtual T visitGroupingExpr(GroupingExpr<T> expression){};
|
||||||
|
virtual T visitLiteralExpr(LiteralExpr<T>* expression) = 0;
|
||||||
|
virtual T visitUnaryExpr(UnaryExpr<T>* expression) = 0;
|
||||||
|
};
|
||||||
|
|||||||
@ -37,4 +37,16 @@ std::string trim(const std::string& str) {
|
|||||||
|
|
||||||
// Extract the trimmed substring
|
// Extract the trimmed substring
|
||||||
return str.substr(start, end - start + 1);
|
return str.substr(start, end - start + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string replaceSubstring(const std::string& str, const std::string& findSubstring, const std::string& replacement) {
|
||||||
|
std::string result = str;
|
||||||
|
size_t startPos = result.find(findSubstring);
|
||||||
|
|
||||||
|
while (startPos != std::string::npos) {
|
||||||
|
result.replace(startPos, findSubstring.length(), replacement);
|
||||||
|
startPos = result.find(findSubstring, startPos + replacement.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
43
source/ASTPrinter.cpp
Normal file
43
source/ASTPrinter.cpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
//
|
||||||
|
// Created by Bobby Lucero on 5/23/23.
|
||||||
|
//
|
||||||
|
#include "../headers/ASTPrinter.h"
|
||||||
|
|
||||||
|
|
||||||
|
std::string ASTPrinter::visitBinaryExpr(BinaryExpr<std::string>* expression){
|
||||||
|
std::cout << expression->left << std::endl;
|
||||||
|
return parenthesize(expression->oper.lexeme, std::vector<std::shared_ptr<Expr<std::string> > >{expression->left, expression->right});
|
||||||
|
}
|
||||||
|
|
||||||
|
//std::string ASTPrinter::visitGroupingExpr(GroupingExpr<std::string> expression){
|
||||||
|
// return "hi";
|
||||||
|
//}
|
||||||
|
std::string ASTPrinter::visitLiteralExpr(LiteralExpr<std::string>* expression){
|
||||||
|
return expression->value;
|
||||||
|
}
|
||||||
|
std::string ASTPrinter::visitUnaryExpr(UnaryExpr<std::string>* expression){
|
||||||
|
return parenthesize(expression->oper.lexeme, std::vector<std::shared_ptr<Expr<std::string> > >{expression->right});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ASTPrinter::print(Expr<std::string> *expr) {
|
||||||
|
return expr->accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ASTPrinter::parenthesize(std::string name, std::vector<std::shared_ptr<Expr<std::string> > > exprs) {
|
||||||
|
std::string builder;
|
||||||
|
|
||||||
|
builder += "(" + name;
|
||||||
|
|
||||||
|
for(std::shared_ptr<Expr<std::string> > expr : exprs)
|
||||||
|
{
|
||||||
|
std::cout << expr << std::endl;
|
||||||
|
|
||||||
|
builder += " ";
|
||||||
|
builder += expr->accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder += ")";
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,37 +1,44 @@
|
|||||||
//
|
//
|
||||||
// Created by Bobby Lucero on 5/21/23.
|
// Created by Bobby Lucero on 5/21/23.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
#include "../headers/bob.h"
|
#include "../headers/bob.h"
|
||||||
#include "../headers/Expression.h"
|
#include "../headers/Expression.h"
|
||||||
#include "../headers/Lexer.h"
|
#include "../headers/Lexer.h"
|
||||||
|
#include "../headers/ASTPrinter.h"
|
||||||
int main(){
|
int main(){
|
||||||
|
|
||||||
Bob bobLang;
|
Bob bobLang;
|
||||||
|
|
||||||
//bobLang.runFile("source.bob");
|
//bobLang.runFile("source.bob");
|
||||||
|
|
||||||
|
ASTPrinter printer;
|
||||||
|
|
||||||
Expr a;
|
std::shared_ptr<Expr<std::string> > expression = std::make_shared<BinaryExpr<std::string> >(
|
||||||
Expr b;
|
std::make_shared<UnaryExpr<std::string> >(
|
||||||
Token t = {PLUS, "+", 1};
|
Token{MINUS, "-", 0},
|
||||||
Token t2 = {MINUS, "-", 1};
|
std::make_shared<LiteralExpr<std::string> >("123")
|
||||||
BinaryExpr e = BinaryExpr(a, t, b);
|
),
|
||||||
|
Token{STAR, "*", 0},
|
||||||
|
std::make_shared<UnaryExpr<std::string> >(
|
||||||
|
Token{MINUS, "+", 0},
|
||||||
|
std::make_shared<LiteralExpr<std::string> >("987")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
std::shared_ptr<Expr> any = std::make_shared<BinaryExpr>(a, t, b);
|
// Expr<std::string>* e = new BinaryExpr<std::string>(
|
||||||
if(std::shared_ptr<BinaryExpr> binexpr = std::dynamic_pointer_cast<BinaryExpr>(any))
|
// new UnaryExpr<std::string>(Token{MINUS, "-", 0}, new LiteralExpr<std::string>("123")),
|
||||||
{
|
// Token{STAR, "*", 0},
|
||||||
std::cout << binexpr->oper.lexeme;
|
// new UnaryExpr<std::string>(Token{PLUS, "+", 0}, new LiteralExpr<std::string>("535"))
|
||||||
}
|
// );
|
||||||
|
LiteralExpr<std::string>* le = new LiteralExpr<std::string>("123");
|
||||||
|
|
||||||
any = std::make_shared<BinaryExpr>(a, t2, b);
|
std::cout << printer.print(expression.get());
|
||||||
if(std::shared_ptr<BinaryExpr> binexpr = std::dynamic_pointer_cast<BinaryExpr>(any))
|
|
||||||
{
|
|
||||||
std::cout << binexpr->oper.lexeme;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
bobLang.runPrompt();
|
//bobLang.runPrompt();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
48
testthing
48
testthing
@ -1,35 +1,51 @@
|
|||||||
struct BinaryExpr : Expr
|
template <typename T>
|
||||||
|
struct BinaryExpr : Expr<T>, Visitor<T>
|
||||||
{
|
{
|
||||||
const Expr left;
|
const Expr<T> left;
|
||||||
const Token oper;
|
const Token oper;
|
||||||
const Expr right;
|
const Expr<T> right;
|
||||||
|
|
||||||
BinaryExpr(Expr left, Token oper, Expr right) : left(left), oper(oper), right(right)
|
BinaryExpr(Expr<T> left, Token oper, Expr<T> right) : left(left), oper(oper), right(right)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
T accept(Visitor<T> visitor){
|
||||||
|
return visitor.visitBinaryExpr(this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
struct GroupingExpr : Expr
|
template <typename T>
|
||||||
|
struct GroupingExpr : Expr<T>, Visitor<T>
|
||||||
{
|
{
|
||||||
const Expr expression;
|
const Expr<T> expression;
|
||||||
|
|
||||||
GroupingExpr(Expr expression) : expression(expression)
|
GroupingExpr(Expr<T> expression) : expression(expression)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
T accept(Visitor<T> visitor){
|
||||||
|
return visitor.visitGroupingExpr(this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
struct LiteralExpr : Expr
|
template <typename T>
|
||||||
|
struct LiteralExpr : Expr<T>, Visitor<T>
|
||||||
{
|
{
|
||||||
const std::string value;
|
const std::string value;
|
||||||
|
|
||||||
LiteralExpr(std::string value) : value(value)
|
LiteralExpr(std::string value) : value(value)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
T accept(Visitor<T> visitor){
|
||||||
struct UnaryExpr : Expr
|
return visitor.visitLiteralExpr(this);
|
||||||
{
|
}
|
||||||
const Token oper;
|
};
|
||||||
const Expr right;
|
template <typename T>
|
||||||
|
struct UnaryExpr : Expr<T>, Visitor<T>
|
||||||
UnaryExpr(Token oper, Expr right) : oper(oper), right(right)
|
{
|
||||||
{
|
const Token oper;
|
||||||
|
const Expr<T> right;
|
||||||
|
|
||||||
|
UnaryExpr(Token oper, Expr<T> right) : oper(oper), right(right)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
T accept(Visitor<T> visitor){
|
||||||
|
return visitor.visitUnaryExpr(this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Binary file not shown.
@ -8,21 +8,29 @@
|
|||||||
|
|
||||||
void defineType(std::ofstream &out, std::string baseName, std::string className, std::string fieldList)
|
void defineType(std::ofstream &out, std::string baseName, std::string className, std::string fieldList)
|
||||||
{
|
{
|
||||||
out << "struct " << className << "Expr : " << baseName << "\n{\n";
|
out << "template <typename T>\n";
|
||||||
|
out << "struct " << className << "Expr : " << baseName << "<T>" << ", Visitor<T>" << "\n{\n";
|
||||||
std::vector<std::string> fields = splitString(fieldList, ", ");
|
std::vector<std::string> fields = splitString(fieldList, ", ");
|
||||||
for(std::string field : fields)
|
for(std::string field : fields)
|
||||||
{
|
{
|
||||||
out << " const " << trim(field) << ";\n";
|
std::cout << trim(field) << std::endl;
|
||||||
|
std::string fieldClass = splitString(trim(field), " ")[0];
|
||||||
|
std::string fieldName = splitString(trim(field), " ")[1];
|
||||||
|
fieldClass = trim(fieldClass) == "Expr" ? "Expr<T>" : trim(fieldClass);
|
||||||
|
out << " const " << fieldClass << " " << fieldName << ";\n";
|
||||||
}
|
}
|
||||||
|
fieldList = replaceSubstring(fieldList, "Expr", "Expr<T>");
|
||||||
out << "\n " << className << "Expr(" << fieldList << ") : ";
|
out << "\n " << className << "Expr(" << fieldList << ") : ";
|
||||||
|
|
||||||
std::string explicitDeclaration;
|
std::string explicitDeclaration;
|
||||||
for(std::string field : fields)
|
for(std::string field : fields)
|
||||||
{
|
{
|
||||||
std::string name = splitString(trim(field), " ")[1];
|
std::cout << trim(field) << std::endl;
|
||||||
|
std::string fieldClass = splitString(trim(field), " ")[0];
|
||||||
|
std::string fieldName = splitString(trim(field), " ")[1];
|
||||||
|
fieldClass = trim(fieldClass) == "Expr" ? "Expr<T>" : trim(fieldClass);
|
||||||
|
|
||||||
explicitDeclaration += trim(name) + "(" + trim(name) + "), ";
|
explicitDeclaration += trim(fieldName) + "(" + trim(fieldName) + "), ";
|
||||||
}
|
}
|
||||||
explicitDeclaration = trim(explicitDeclaration);
|
explicitDeclaration = trim(explicitDeclaration);
|
||||||
explicitDeclaration.pop_back();
|
explicitDeclaration.pop_back();
|
||||||
@ -31,6 +39,11 @@ void defineType(std::ofstream &out, std::string baseName, std::string className,
|
|||||||
|
|
||||||
out << "\n {\n";
|
out << "\n {\n";
|
||||||
out << " }\n";
|
out << " }\n";
|
||||||
|
|
||||||
|
out << " T accept(Visitor<T> visitor){\n";
|
||||||
|
out << " return visitor.visit" << className << "Expr(this);\n";
|
||||||
|
out << " }\n";
|
||||||
|
|
||||||
out << "};" << std::endl;
|
out << "};" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user