ASTPrinter now prints generated AST from parser

This commit is contained in:
Bobby Lucero 2023-05-27 02:05:06 -04:00
parent fc0d9137a5
commit a0ec4af169
11 changed files with 306 additions and 82 deletions

6
.idea/misc.xml generated
View File

@ -1,5 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CidrRootsConfiguration">
<sourceRoots>
<file path="$PROJECT_DIR$/headers" />
<file path="$PROJECT_DIR$/source" />
</sourceRoots>
</component>
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MakefileSettings">
<option name="linkedExternalProjectsSettings">

View File

@ -1,18 +1,18 @@
#pragma once
#include "Expression.h"
#include "TypeWrapper.h"
#include <string>
#include <initializer_list>
class ASTPrinter : public Visitor<std::string>
class ASTPrinter : public Visitor<std::shared_ptr<Object>>
{
std::string visitBinaryExpr(BinaryExpr<std::string>* expression) override;
std::string visitGroupingExpr(GroupingExpr<std::string>* expression) override;
std::string visitLiteralExpr(LiteralExpr<std::string>* expression) override;
std::string visitUnaryExpr(UnaryExpr<std::string>* expression) override;
std::shared_ptr<Object> visitBinaryExpr(BinaryExpr<std::shared_ptr<Object>>* expression) override;
std::shared_ptr<Object> visitGroupingExpr(GroupingExpr<std::shared_ptr<Object>>* expression) override;
std::shared_ptr<Object> visitLiteralExpr(LiteralExpr<std::shared_ptr<Object>>* expression) override;
std::shared_ptr<Object> visitUnaryExpr(UnaryExpr<std::shared_ptr<Object>>* expression) override;
public:
int test = 10;
std::string print(Expr<std::string>* expr);
std::shared_ptr<Object> print(Expr<std::shared_ptr<Object>>* expr);
private:
std::string parenthesize(std::string name, std::vector<std::shared_ptr<Expr<std::string>>> exprs);
std::shared_ptr<Object> parenthesize(std::string name, std::vector<std::shared_ptr<Expr<std::shared_ptr<Object>>>> exprs);
};

View File

@ -1,4 +1,5 @@
#pragma once
#include <utility>
#include <vector>
#include "Lexer.h"
#include "Expression.h"
@ -11,8 +12,27 @@ private:
int current = 0;
public:
Parser(std::vector<Token> tokens) : tokens(tokens){};
explicit Parser(std::vector<Token> tokens) : tokens(std::move(tokens)){};
std::shared_ptr<Expr<std::shared_ptr<Object>>> parse();
private:
std::shared_ptr<Expr<Object>> expression();
std::shared_ptr<Expr<std::shared_ptr<Object>>> expression();
std::shared_ptr<Expr<std::shared_ptr<Object>>> equality();
std::shared_ptr<Expr<std::shared_ptr<Object>>> comparison();
std::shared_ptr<Expr<std::shared_ptr<Object>>> term();
std::shared_ptr<Expr<std::shared_ptr<Object>>> factor();
std::shared_ptr<Expr<std::shared_ptr<Object>>> unary();
std::shared_ptr<Expr<std::shared_ptr<Object>>> primary();
bool match(std::vector<TokenType> types);
bool check(TokenType type);
bool isAtEnd();
Token advance();
Token peek();
Token previous();
Token consume(TokenType type, std::string message);
void sync();
};

View File

@ -2,7 +2,9 @@
#include <string>
struct Object
{
virtual ~Object(){};
static int count;
Object();
virtual ~Object();
};
struct Number : public Object

View File

@ -1,16 +1 @@
bob.test
10
11.1
test = (11 + 2 "xs
hello
end")
//
//11.
12//11
11.
11.69 + 66.735293857293875 + 235982735987235.0 + 1
123a
10 + 10

View File

@ -4,40 +4,40 @@
#include "../headers/ASTPrinter.h"
std::string ASTPrinter::visitBinaryExpr(BinaryExpr<std::string>* expression){
std::shared_ptr<Object> ASTPrinter::visitBinaryExpr(BinaryExpr<std::shared_ptr<Object>>* expression){
std::cout << expression->left << std::endl;
return parenthesize(expression->oper.lexeme, std::vector<std::shared_ptr<Expr<std::string>>>{expression->left, expression->right});
return parenthesize(expression->oper.lexeme, std::vector<std::shared_ptr<Expr<std::shared_ptr<Object>>>>{expression->left, expression->right});
}
std::string ASTPrinter::visitGroupingExpr(GroupingExpr<std::string>* expression){
return parenthesize("group", std::vector<std::shared_ptr<Expr<std::string>>>{expression->expression});
std::shared_ptr<Object> ASTPrinter::visitGroupingExpr(GroupingExpr<std::shared_ptr<Object>>* expression){
return parenthesize("group", std::vector<std::shared_ptr<Expr<std::shared_ptr<Object>>>>{expression->expression});
}
std::string ASTPrinter::visitLiteralExpr(LiteralExpr<std::string>* expression){
return expression->value;
std::shared_ptr<Object> ASTPrinter::visitLiteralExpr(LiteralExpr<std::shared_ptr<Object>>* expression){
return std::make_shared<String>(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::shared_ptr<Object> ASTPrinter::visitUnaryExpr(UnaryExpr<std::shared_ptr<Object>>* expression){
return parenthesize(expression->oper.lexeme, std::vector<std::shared_ptr<Expr<std::shared_ptr<Object>>>>{expression->right});
}
std::string ASTPrinter::print(Expr<std::string> *expr) {
std::shared_ptr<Object> ASTPrinter::print(Expr<std::shared_ptr<Object>> *expr) {
return expr->accept(this);
}
std::string ASTPrinter::parenthesize(std::string name, std::vector<std::shared_ptr<Expr<std::string>>> exprs) {
std::shared_ptr<Object> ASTPrinter::parenthesize(std::string name, std::vector<std::shared_ptr<Expr<std::shared_ptr<Object>>>> exprs) {
std::string builder;
builder += "(" + name;
for(std::shared_ptr<Expr<std::string>> expr : exprs)
for(const std::shared_ptr<Expr<std::shared_ptr<Object>>>& expr : exprs)
{
std::cout << expr << std::endl;
builder += " ";
builder += expr->accept(this);
builder += std::dynamic_pointer_cast<String>(expr->accept(this))->value;
}
builder += ")";
return builder;
return std::make_shared<String>(builder);
}

View File

@ -130,7 +130,7 @@ std::vector<Token> Lexer::Tokenize(std::string source){
}
if(src.empty())
{
throw std::runtime_error("Unterminated string at line: " + std::to_string(this->line));
throw std::runtime_error("LEXER: Unterminated string at line: " + std::to_string(this->line));
}
else if(src[0] == '"')
{
@ -172,7 +172,7 @@ std::vector<Token> Lexer::Tokenize(std::string source){
}
else
{
throw std::runtime_error("malformed number at: " + std::to_string(this->line));
throw std::runtime_error("LEXER: malformed number at: " + std::to_string(this->line));
}
}
@ -205,14 +205,14 @@ std::vector<Token> Lexer::Tokenize(std::string source){
else
{
throw std::runtime_error("Unknown Token: '" + std::string(1, t) + "'");
throw std::runtime_error("LEXER: Unknown Token: '" + std::string(1, t) + "'");
}
}
}
tokens.push_back({END_OF_FILE, "eof", line});
return tokens;
}

View File

@ -3,6 +3,176 @@
//
#include "../headers/Parser.h"
std::shared_ptr<Expr<Object> > Parser::expression() {
// Precedence
// to all the morons on facebook who don't know what pemdas is, fuck you
///////////////////////////////////////////
std::shared_ptr<Expr<std::shared_ptr<Object>>> Parser::expression()
{
return equality();
}
std::shared_ptr<Expr<std::shared_ptr<Object>>> Parser::equality()
{
std::shared_ptr<Expr<std::shared_ptr<Object>>> expr = comparison();
while(match({BANG_EQUAL, DOUBLE_EQUAL}))
{
Token op = previous();
std::shared_ptr<Expr<std::shared_ptr<Object>>> right = comparison();
expr = std::make_shared<BinaryExpr<std::shared_ptr<Object>>>(expr, op, right);
}
return expr;
}
std::shared_ptr<Expr<std::shared_ptr<Object>>> Parser::comparison()
{
std::shared_ptr<Expr<std::shared_ptr<Object>>> expr = term();
while(match({GREATER, GREATER_EQUAL, LESS, LESS_EQUAL}))
{
Token op = previous();
std::shared_ptr<Expr<std::shared_ptr<Object>>> right = term();
expr = std::make_shared<BinaryExpr<std::shared_ptr<Object>>>(expr, op, right);
}
return expr;
}
std::shared_ptr<Expr<std::shared_ptr<Object>>> Parser::term()
{
std::shared_ptr<Expr<std::shared_ptr<Object>>> expr = factor();
while(match({MINUS, PLUS}))
{
std::cout << "Found comparison" << std::endl;
Token op = previous();
std::shared_ptr<Expr<std::shared_ptr<Object>>> right = factor();
expr = std::make_shared<BinaryExpr<std::shared_ptr<Object>>>(expr, op, right);
}
return expr;
}
std::shared_ptr<Expr<std::shared_ptr<Object>>> Parser::factor()
{
std::shared_ptr<Expr<std::shared_ptr<Object>>> expr = unary();
while(match({SLASH, STAR}))
{
Token op = previous();
std::shared_ptr<Expr<std::shared_ptr<Object>>> right = unary();
expr = std::make_shared<BinaryExpr<std::shared_ptr<Object>>>(expr, op, right);
}
return expr;
}
std::shared_ptr<Expr<std::shared_ptr<Object>>> Parser::unary()
{
if(match({BANG, MINUS}))
{
Token op = previous();
std::shared_ptr<Expr<std::shared_ptr<Object>>> right = unary();
return std::make_shared<UnaryExpr<std::shared_ptr<Object>>>(op, right);
}
return primary();
}
std::shared_ptr<Expr<std::shared_ptr<Object>>> Parser::primary()
{
if(match({FALSE})) return std::make_shared<LiteralExpr<std::shared_ptr<Object>>>("true", false);
if(match({TRUE})) return std::make_shared<LiteralExpr<std::shared_ptr<Object>>>("true", false);
if(match({NONE})) return std::make_shared<LiteralExpr<std::shared_ptr<Object>>>("none", false);
if(match({NUMBER})) return std::make_shared<LiteralExpr<std::shared_ptr<Object>>>(previous().lexeme, true);
if(match({STRING})) return std::make_shared<LiteralExpr<std::shared_ptr<Object>>>(previous().lexeme, false);
if(match({OPEN_PAREN}))
{
std::shared_ptr<Expr<std::shared_ptr<Object>>> expr = expression();
consume(CLOSE_PAREN, "Expected ')' after expression on line " + std::to_string(peek().line));
return std::make_shared<GroupingExpr<std::shared_ptr<Object>>>(expr);
}
throw std::runtime_error("Expression expected at: " + std::to_string(peek().line));
}
///////////////////////////////////////////
std::shared_ptr<Expr<std::shared_ptr<Object>>> Parser::parse() {
return expression();
}
bool Parser::match(std::vector<TokenType> types) {
for(TokenType t : types)
{
if(check(t))
{
advance();
return true;
}
}
return false;
}
bool Parser::check(TokenType type) {
if(isAtEnd()) return false;
return peek().type == type;
}
bool Parser::isAtEnd() {
return peek().type == END_OF_FILE;
}
Token Parser::advance() {
if(!isAtEnd()) current++;
return previous();
}
Token Parser::peek() {
return tokens[current];
}
Token Parser::previous() {
return tokens[current - 1];
}
Token Parser::consume(TokenType type, std::string message) {
if(check(type)) return advance();
throw std::runtime_error(peek().lexeme +": "+ message);
}
void Parser::sync()
{
advance();
while(!isAtEnd())
{
if(previous().type == SEMICOLON) return;
switch (peek().type) {
case CLASS:
case FUNCTION:
case VAR:
case FOR:
case IF:
case WHILE:
case RETURN:
return;
}
advance();
}
}

18
source/TypeWrapper.cpp Normal file
View File

@ -0,0 +1,18 @@
//
// Created by Bobby Lucero on 5/27/23.
//
#include "../headers/TypeWrapper.h"
#include <iostream>
int Object::count;
Object::Object() {
std::cout << "Inc"<<std::endl;
Object::count += 1;
}
Object::~Object() {
std::cout << "dec"<<std::endl;
Object::count -= 1;
}

View File

@ -1,4 +1,6 @@
#include "../headers/bob.h"
#include "../headers/Parser.h"
#include "../headers/ASTPrinter.h"
using namespace std;
void Bob::runFile(string path)
@ -45,11 +47,31 @@ void Bob::error(int line, string message)
void Bob::run(string source)
{
vector<Token> tokens = lexer.Tokenize(source);
try {
vector<Token> tokens = lexer.Tokenize(source);
Parser p(tokens);
shared_ptr<Expr<shared_ptr<Object>>> expr = p.parse();
ASTPrinter printer;
cout << dynamic_pointer_cast<String>(printer.print(expr.get()))->value << endl;
for(Token t : tokens){
//cout << "{type: " << t.type << ", value: " << t.lexeme << "}" << endl;
}
for(Token t : tokens){
cout << "{type: " << t.type << ", value: " << t.lexeme << "}" << endl;
}
catch(std::exception &e)
{
cout << "ERROR OCCURRED: " << e.what() << endl;
return;
}
cout << "Current object count: " << Object::count << endl;
}
void Bob::report(int line, string where, string message)

View File

@ -9,46 +9,47 @@
#include "../headers/ASTPrinter.h"
#include "../headers/TypeWrapper.h"
int main(){
Object::count = 0;
Bob bobLang;
//bobLang.runFile("source.bob");
bobLang.runPrompt();
ASTPrinter printer;
std::shared_ptr<Expr<std::string>> expression = std::make_shared<BinaryExpr<std::string> >(
std::make_shared<UnaryExpr<std::string>>(
Token{MINUS, "-", 1},
std::make_shared<LiteralExpr<std::string>>("123", true)
),
Token{MINUS, "-", 1},
std::make_shared<GroupingExpr<std::string>>(
std::make_shared<LiteralExpr<std::string>>("45.67", true)
)
);
// Expr<std::string>* e = new BinaryExpr<std::string>(
// new UnaryExpr<std::string>(Token{MINUS, "-", 0}, new LiteralExpr<std::string>("123")),
// Token{STAR, "*", 0},
// new UnaryExpr<std::string>(Token{PLUS, "+", 0}, new LiteralExpr<std::string>("535"))
//ASTPrinter printer;
//
// std::shared_ptr<Expr<std::shared_ptr<Object>>> expression = std::make_shared<BinaryExpr<std::shared_ptr<Object>> >(
// std::make_shared<UnaryExpr<std::shared_ptr<Object>>>(
// Token{MINUS, "-", 1},
// std::make_shared<LiteralExpr<std::shared_ptr<Object>>>("123", true)
// ),
// Token{MINUS, "-", 1},
// std::make_shared<GroupingExpr<std::shared_ptr<Object>>>(
// std::make_shared<LiteralExpr<std::shared_ptr<Object>>>("45.67", true)
// )
// );
LiteralExpr<std::string>* le = new LiteralExpr<std::string>("123", true);
std::cout << printer.print(expression.get());
std::cout << std::endl;
//
//// Expr<std::string>* e = new BinaryExpr<std::string>(
//// new UnaryExpr<std::string>(Token{MINUS, "-", 0}, new LiteralExpr<std::string>("123")),
//// Token{STAR, "*", 0},
//// new UnaryExpr<std::string>(Token{PLUS, "+", 0}, new LiteralExpr<std::string>("535"))
//// );
//
//
// std::cout << std::dynamic_pointer_cast<String>(printer.print(expression.get()))->value;
//
// std::cout << std::endl;
//bobLang.runPrompt();
std::shared_ptr<Object> object = std::make_shared<String>(String{"Hi"});
if(auto num = std::dynamic_pointer_cast<Number>(object))
{
std::cout << num->value << std::endl;
}else if(auto str = std::dynamic_pointer_cast<String>(object))
{
std::cout << str->value << std::endl;
}
// std::shared_ptr<Object> object = std::make_shared<String>(String{"Hi"});
//
// if(auto num = std::dynamic_pointer_cast<Number>(object))
// {
// std::cout << num->value << std::endl;
// }else if(auto str = std::dynamic_pointer_cast<String>(object))
// {
// std::cout << str->value << std::endl;
// }
return 0;
}