Finish assignment 3
This commit is contained in:
parent
f098f91455
commit
2ef9dd73cc
9
Makefile
9
Makefile
@ -3,11 +3,14 @@ all: parse
|
|||||||
parser.cpp parser.hpp: parser.y
|
parser.cpp parser.hpp: parser.y
|
||||||
bison -d -o parser.cpp parser.y
|
bison -d -o parser.cpp parser.y
|
||||||
|
|
||||||
|
tree.o: tree.cpp
|
||||||
|
g++ -g -c -o tree.o tree.cpp
|
||||||
|
|
||||||
scanner.cpp: scanner.l
|
scanner.cpp: scanner.l
|
||||||
flex -o scanner.cpp scanner.l
|
flex -o scanner.cpp scanner.l
|
||||||
|
|
||||||
parse: main.cpp parser.cpp scanner.cpp
|
parse: main.cpp parser.cpp scanner.cpp tree.o
|
||||||
g++ main.cpp parser.cpp scanner.cpp -o parse
|
g++ -g main.cpp parser.cpp scanner.cpp tree.o -o parse
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f parse scanner.cpp parser.cpp parser.hpp
|
rm -f parse scanner.cpp parser.cpp parser.hpp tree.o
|
||||||
|
7
main.cpp
7
main.cpp
@ -9,6 +9,13 @@ extern stmt_ptr target_program;
|
|||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
if (!yylex()) {
|
if (!yylex()) {
|
||||||
|
std::vector<std::string> dest;
|
||||||
|
target_program->print_dot(dest, "start");
|
||||||
|
std::cout << "digraph G {" << std::endl;
|
||||||
|
for(auto& line : dest) {
|
||||||
|
std::cout << line << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << "}" << std::endl;
|
||||||
delete target_program;
|
delete target_program;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
parser.y
2
parser.y
@ -134,7 +134,7 @@ condition
|
|||||||
;
|
;
|
||||||
|
|
||||||
if_statement
|
if_statement
|
||||||
: IF condition COLON NEWLINE block elif_blocks else_block { $$ = new stmt_if($2, $6, $7); delete $6; }
|
: IF condition COLON NEWLINE block elif_blocks else_block { $$ = new stmt_if($2, $5, $7); delete $6; }
|
||||||
;
|
;
|
||||||
|
|
||||||
elif_blocks
|
elif_blocks
|
||||||
|
146
tree.cpp
Normal file
146
tree.cpp
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
#include "tree.hpp"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::string label(T v) {
|
||||||
|
return std::to_string(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
std::string label<std::string>(std::string v) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
std::string label<const char*>(const char* v) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
std::string label<binop>(binop op) {
|
||||||
|
switch(op) {
|
||||||
|
case binop::plus:
|
||||||
|
return "+";
|
||||||
|
case binop::minus:
|
||||||
|
return "-";
|
||||||
|
case binop::times:
|
||||||
|
return "*";
|
||||||
|
case binop::divide:
|
||||||
|
return "/";
|
||||||
|
case binop::land:
|
||||||
|
return "&&";
|
||||||
|
case binop::lor:
|
||||||
|
return "||";
|
||||||
|
case binop::eq:
|
||||||
|
return "==";
|
||||||
|
case binop::neq:
|
||||||
|
return "!=";
|
||||||
|
case binop::lt:
|
||||||
|
return "<";
|
||||||
|
case binop::lte:
|
||||||
|
return "<=";
|
||||||
|
case binop::gt:
|
||||||
|
return ">";
|
||||||
|
case binop::gte:
|
||||||
|
return ">=";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
std::string label<unop>(unop op) {
|
||||||
|
switch(op) {
|
||||||
|
case unop::lnot:
|
||||||
|
return "!";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::string wrap_label(T v) {
|
||||||
|
return std::string(" [label=\"") + label(v) + "\"]";
|
||||||
|
}
|
||||||
|
|
||||||
|
void expr_id::print_dot(dot& into, std::string prefix) {
|
||||||
|
into.push_back(prefix + wrap_label(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
void expr_int::print_dot(dot& into, std::string prefix) {
|
||||||
|
into.push_back(prefix + wrap_label(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
void expr_float::print_dot(dot& into, std::string prefix) {
|
||||||
|
into.push_back(prefix + wrap_label(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
void expr_binop::print_dot(dot& into, std::string prefix) {
|
||||||
|
into.push_back(prefix + wrap_label(op));
|
||||||
|
std::string lp = prefix + "_left";
|
||||||
|
std::string rp = prefix + "_right";
|
||||||
|
left->print_dot(into, lp);
|
||||||
|
right->print_dot(into, rp);
|
||||||
|
into.push_back(prefix + "->" + lp);
|
||||||
|
into.push_back(prefix + "->" + rp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void expr_unop::print_dot(dot& into, std::string prefix) {
|
||||||
|
into.push_back(prefix + wrap_label(op));
|
||||||
|
std::string cp = prefix + "_child";
|
||||||
|
child->print_dot(into, cp);
|
||||||
|
into.push_back(prefix + "->" + cp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void expr_assign::print_dot(dot& into, std::string prefix) {
|
||||||
|
into.push_back(prefix + wrap_label(var + "="));
|
||||||
|
std::string cp = prefix + "_child";
|
||||||
|
child->print_dot(into, cp);
|
||||||
|
into.push_back(prefix + "->" + cp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void stmt_block::print_dot(dot& into, std::string prefix) {
|
||||||
|
into.push_back(prefix + wrap_label("block"));
|
||||||
|
int index = 0;
|
||||||
|
for(auto& child : children) {
|
||||||
|
std::string cp = prefix + "_" + std::to_string(index);
|
||||||
|
child->print_dot(into, cp);
|
||||||
|
into.push_back(prefix + "->" + cp);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void stmt_if::print_dot(dot& into, std::string prefix) {
|
||||||
|
into.push_back(prefix + wrap_label("if"));
|
||||||
|
std::string cp = prefix + "_cond";
|
||||||
|
std::string tp = prefix + "_then";
|
||||||
|
std::string ep = prefix + "_else";
|
||||||
|
|
||||||
|
cond->print_dot(into, cp);
|
||||||
|
then->print_dot(into, tp);
|
||||||
|
if(els) els->print_dot(into, ep);
|
||||||
|
|
||||||
|
into.push_back(prefix + "->" + cp);
|
||||||
|
into.push_back(prefix + "->" + tp);
|
||||||
|
if(els) into.push_back(prefix + "->" + ep);
|
||||||
|
}
|
||||||
|
|
||||||
|
void stmt_while::print_dot(dot& into, std::string prefix) {
|
||||||
|
into.push_back(prefix + wrap_label("while"));
|
||||||
|
std::string cp = prefix + "_cond";
|
||||||
|
std::string bp = prefix + "_body";
|
||||||
|
|
||||||
|
cond->print_dot(into, cp);
|
||||||
|
body->print_dot(into, bp);
|
||||||
|
|
||||||
|
into.push_back(prefix + "->" + cp);
|
||||||
|
into.push_back(prefix + "->" + bp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void stmt_break::print_dot(dot& into, std::string prefix) {
|
||||||
|
into.push_back(prefix + wrap_label("break"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void stmt_expr::print_dot(dot& into, std::string prefix) {
|
||||||
|
child->print_dot(into, prefix);
|
||||||
|
}
|
28
tree.hpp
28
tree.hpp
@ -2,6 +2,8 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
typedef std::vector<std::string> dot;
|
||||||
|
|
||||||
enum class binop {
|
enum class binop {
|
||||||
plus,
|
plus,
|
||||||
minus,
|
minus,
|
||||||
@ -23,6 +25,8 @@ enum class unop {
|
|||||||
|
|
||||||
struct expr {
|
struct expr {
|
||||||
virtual ~expr() = default;
|
virtual ~expr() = default;
|
||||||
|
|
||||||
|
virtual void print_dot(dot& into, std::string prefix) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef expr* expr_ptr;
|
typedef expr* expr_ptr;
|
||||||
@ -32,18 +36,24 @@ struct expr_id : expr {
|
|||||||
|
|
||||||
expr_id(std::string i) :
|
expr_id(std::string i) :
|
||||||
id(std::move(i)) {}
|
id(std::move(i)) {}
|
||||||
|
|
||||||
|
virtual void print_dot(dot& into, std::string prefix);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct expr_int : expr {
|
struct expr_int : expr {
|
||||||
int val;
|
int val;
|
||||||
|
|
||||||
expr_int(int i) : val(i) {}
|
expr_int(int i) : val(i) {}
|
||||||
|
|
||||||
|
virtual void print_dot(dot& into, std::string prefix);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct expr_float : expr {
|
struct expr_float : expr {
|
||||||
double val;
|
double val;
|
||||||
|
|
||||||
expr_float(double f) : val(f) {}
|
expr_float(double f) : val(f) {}
|
||||||
|
|
||||||
|
virtual void print_dot(dot& into, std::string prefix);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct expr_binop : expr {
|
struct expr_binop : expr {
|
||||||
@ -53,6 +63,8 @@ struct expr_binop : expr {
|
|||||||
|
|
||||||
expr_binop(binop nop, expr_ptr l, expr_ptr r) :
|
expr_binop(binop nop, expr_ptr l, expr_ptr r) :
|
||||||
op(nop), left(std::move(l)), right(std::move(r)) {}
|
op(nop), left(std::move(l)), right(std::move(r)) {}
|
||||||
|
|
||||||
|
virtual void print_dot(dot& into, std::string prefix);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct expr_unop : expr {
|
struct expr_unop : expr {
|
||||||
@ -61,6 +73,8 @@ struct expr_unop : expr {
|
|||||||
|
|
||||||
expr_unop(unop nop, expr_ptr c) :
|
expr_unop(unop nop, expr_ptr c) :
|
||||||
op(nop), child(std::move(c)) {}
|
op(nop), child(std::move(c)) {}
|
||||||
|
|
||||||
|
virtual void print_dot(dot& into, std::string prefix);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct expr_assign : expr {
|
struct expr_assign : expr {
|
||||||
@ -69,6 +83,8 @@ struct expr_assign : expr {
|
|||||||
|
|
||||||
expr_assign(std::string v, expr_ptr c) :
|
expr_assign(std::string v, expr_ptr c) :
|
||||||
var(std::move(v)), child(std::move(c)) {}
|
var(std::move(v)), child(std::move(c)) {}
|
||||||
|
|
||||||
|
virtual void print_dot(dot& into, std::string prefix);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename ... Ts>
|
template <typename T, typename ... Ts>
|
||||||
@ -78,12 +94,16 @@ expr_ptr make_expr(Ts&& ... ts) {
|
|||||||
|
|
||||||
struct stmt {
|
struct stmt {
|
||||||
virtual ~stmt() = default;
|
virtual ~stmt() = default;
|
||||||
|
|
||||||
|
virtual void print_dot(dot& into, std::string prefix) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef stmt* stmt_ptr;
|
typedef stmt* stmt_ptr;
|
||||||
|
|
||||||
struct stmt_block : stmt {
|
struct stmt_block : stmt {
|
||||||
std::vector<stmt_ptr> children;
|
std::vector<stmt_ptr> children;
|
||||||
|
|
||||||
|
virtual void print_dot(dot& into, std::string prefix);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct stmt_if : stmt {
|
struct stmt_if : stmt {
|
||||||
@ -93,6 +113,8 @@ struct stmt_if : stmt {
|
|||||||
|
|
||||||
stmt_if(expr_ptr c, stmt_ptr t, stmt_ptr e = nullptr) :
|
stmt_if(expr_ptr c, stmt_ptr t, stmt_ptr e = nullptr) :
|
||||||
cond(std::move(c)), then(std::move(t)), els(std::move(e)) {}
|
cond(std::move(c)), then(std::move(t)), els(std::move(e)) {}
|
||||||
|
|
||||||
|
virtual void print_dot(dot& into, std::string prefix);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct stmt_while : stmt {
|
struct stmt_while : stmt {
|
||||||
@ -101,10 +123,12 @@ struct stmt_while : stmt {
|
|||||||
|
|
||||||
stmt_while(expr_ptr c, stmt_ptr b) :
|
stmt_while(expr_ptr c, stmt_ptr b) :
|
||||||
cond(std::move(c)), body(std::move(b)) {}
|
cond(std::move(c)), body(std::move(b)) {}
|
||||||
|
|
||||||
|
virtual void print_dot(dot& into, std::string prefix);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct stmt_break : stmt {
|
struct stmt_break : stmt {
|
||||||
|
virtual void print_dot(dot& into, std::string prefix);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct stmt_expr : stmt {
|
struct stmt_expr : stmt {
|
||||||
@ -112,6 +136,8 @@ struct stmt_expr : stmt {
|
|||||||
|
|
||||||
stmt_expr(expr_ptr c) :
|
stmt_expr(expr_ptr c) :
|
||||||
child(std::move(c)) {}
|
child(std::move(c)) {}
|
||||||
|
|
||||||
|
virtual void print_dot(dot& into, std::string prefix);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename ... Ts>
|
template <typename T, typename ... Ts>
|
||||||
|
Loading…
Reference in New Issue
Block a user