Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* DV1465 / DV1505 / DV1511 Lab-task example code.
- (C) Dr Andrew Moss, Erik Bergenholtz 2016, 2017
- This code is released into the public domain.
- You are free to use this code as a base for your second assignment after
- the lab sessions (it is not required that you do so).
- */
- #include <list>
- #include <set>
- #include <initializer_list>
- #include <string>
- #include <iostream>
- #include <fstream>
- #include <regex>
- #include <vector>
- #include "binary.tab.hh"
- #include "node.h"
- extern FILE* yyin;
- extern Node root;
- using namespace std;
- //to compile: g++ -std=c++11 your_file.cpp -o your_program
- /*--------------------START OF CREATION THREEADD--------------------------*/
- /************* Three Address Instructions *************/
- class ThreeAd
- {
- public:
- string name,lhs,rhs;
- char op;
- ThreeAd(string name, char op, string lhs, string rhs) :
- name(name), op(op), lhs(lhs), rhs(rhs)
- {
- }
- void dump()
- {
- cout << name << " <- ";
- cout << lhs << " " << op << " " << rhs << endl;
- }
- /*
- void toAssembly(std::ofstream &afile)//converter from threewayaddress -> assembly
- {
- //afile << "TABB";
- switch(op) //check operator to know what kind of operation to be done
- {
- case'+':
- if (afile.is_open())
- {
- if (std::regex_match (lhs, std::regex("[0-9]+")) && std::regex_match (rhs, std::regex("[0-9]+"))) //numbers
- {
- cout << "movq $" << lhs << ", " << "%%rax\n\t";
- cout << "movq $" << rhs << ", " << "%%rbx\n\t";
- }
- else if(std::regex_match (lhs, std::regex("[0-9]+")) && std::regex_match (rhs, std::regex("[A-Za-z]*"))) //number + letter
- {
- cout << "movq $" << lhs << ", " << "%%rax\n\t";
- cout << "movq $" << "%%[" << rhs << " ], " << "%%rbx\n\t";
- }
- else if(std::regex_match (lhs, std::regex("[A-Za-z]*")) && std::regex_match (rhs, std::regex("[0-9]+"))) //letter + number
- {
- cout << "movq $" << "%%[" << lhs << " ], " << "%%rbx\n\t";
- cout << "movq $" << rhs << ", " << "%%rbx\n\t";
- }
- else //letters
- {
- cout << "movq $" << "%%[" << lhs << " ], " << "%%rbx\n\t";
- cout << "movq $" << "%%[" << rhs << " ], " << "%%rbx\n\t";
- }
- cout << "addq " << "%%rbx" << ", " << "%%rax\n\t";
- cout << "movq " << "%%rax" << ", " << "%%["<< name << "]\n\t";
- }
- break;
- case'-':
- break;
- case'*':
- break;
- case'=':
- break;
- default:
- cout<<"still things to do m8!";
- break;
- }
- }
- */
- };
- /* Basic Blocks */
- class BBlock
- {
- private:
- static int nCounter;
- public:
- list<ThreeAd> instructions;
- BBlock *tExit, *fExit;
- string name;
- /*
- void getList(std::ofstream &afile) // function to get list of instructions and send to assemblyConverter, called in dumpCFG
- {
- for(auto i : instructions)
- i.toAssembly(afile); //in threeAd
- }
- */
- BBlock() :
- tExit(NULL), fExit(NULL), name("blk" + to_string(nCounter++))
- {
- }
- void dump() // called on in dumpCFG
- {
- cout << "BBlock @ " << this << endl;
- cout << name << endl;
- for(auto i : instructions)
- i.dump(); //calls on dump in ThreeAd
- cout << "True: " << tExit << endl;
- cout << "False: " << fExit << endl;
- }
- };
- int BBlock::nCounter = 0;
- /******************** Expressions ********************/
- class Expression
- {
- public:
- string name;
- static int uniqeID;
- Expression() : name("")
- {
- }
- virtual string makeNames()
- {
- return "_t" + to_string(uniqeID++);
- // Lecture 8 / slide 11.
- // Virtual (but not pure) to allow overriding in the leaves.
- }
- virtual string convert(BBlock*) = 0; // Lecture 8 / slide 12.
- virtual void print() = 0;
- };
- int Expression::uniqeID = 0; //set unique Id for name in expression for each threeaddress function
- class Add : public Expression
- {
- public:
- Expression *lhs, *rhs;
- Add(Expression* lhs, Expression* rhs) :
- lhs(lhs), rhs(rhs)
- {
- }
- string convert(BBlock* out) // out = output current block
- {
- print();
- string tempName = makeNames();
- out->instructions.push_back(ThreeAd(tempName, '+', lhs->convert(out), rhs->convert(out)));
- return tempName;
- //recursive add three-address-instruction to block
- }
- void print()
- {
- cout << "ClassAdd"<<endl;
- lhs->print();
- rhs->print();
- }
- };
- class Mult : public Expression
- {
- public:
- Expression *lhs, *rhs;
- Mult(Expression* lhs, Expression* rhs) :
- lhs(lhs), rhs(rhs)
- {
- }
- string convert(BBlock* out)
- {
- print();
- string tempName = makeNames();
- out->instructions.push_back(ThreeAd(tempName, '*', lhs->convert(out), rhs->convert(out)));
- return tempName;
- //recursive add three-address-instruction to block
- }
- void print()
- {
- cout << "ClassMult: "<<lhs->name<<" "<<rhs->name<<endl;
- }
- };
- class Div : public Expression
- {
- public:
- Expression *lhs, *rhs;
- Div(Expression* lhs, Expression* rhs) :
- lhs(lhs), rhs(rhs)
- {
- }
- string convert(BBlock* out)
- {
- print();
- string tempName = makeNames();
- out->instructions.push_back(ThreeAd(tempName, '/', lhs->convert(out), rhs->convert(out)));
- return tempName;
- //recursive add three-address-instruction to block
- }
- void print()
- {
- cout << "ClassDiv: "<<lhs->name<<" "<<rhs->name<<endl;
- }
- };
- class Sub : public Expression
- {
- public:
- Expression *lhs, *rhs;
- Sub(Expression* lhs, Expression* rhs) :
- lhs(lhs), rhs(rhs)
- {
- }
- string convert(BBlock* out)
- {
- print();
- string tempName = makeNames();
- out->instructions.push_back(ThreeAd(tempName, '-', lhs->convert(out), rhs->convert(out)));
- return tempName;
- //recursive add three-address-instruction to block
- }
- void print()
- {
- cout << "ClassSub: "<<lhs->name<<" "<<rhs->name<<endl;
- }
- };
- class Equality : public Expression
- {
- public:
- Expression *lhs, *rhs;
- Equality(Expression* lhs, Expression* rhs) :
- lhs(lhs), rhs(rhs)
- {
- }
- string convert(BBlock* out)
- {
- print();
- string tempName = makeNames();
- out->instructions.push_back(ThreeAd(tempName, 'E', lhs->convert(out), rhs->convert(out)));
- return tempName;
- //recursive add three-address-instruction to block
- }
- void print()
- {
- cout << "ClassEQ: "<<lhs->name<<" "<<rhs->name<<endl;
- }
- };
- class Variable : public Expression
- {
- public:
- string aName;
- Variable()
- {
- aName = "";
- }
- Variable(string aName)
- {
- name = aName;
- }
- string convert(BBlock* out)
- {
- print();
- return name;
- }
- void print()
- {
- cout << "ClassVariable: "<<aName<<endl;
- }
- };
- class Quote : public Expression
- {
- public:
- string aQuote;
- Quote()
- {
- aQuote= "\"\"";
- }
- Quote(string aQuote)
- {
- name = aQuote;
- }
- string convert(BBlock* out)
- {
- print();
- return name;
- }
- void print()
- {
- cout << "ClassString :"<<aQuote<<endl;
- }
- };
- class Constant : public Expression
- {
- public:
- int aValue;
- Constant(int number)
- {
- aValue = number;
- name = to_string(aValue);
- }
- string convert(BBlock* out)
- {
- print();
- return name;
- }
- void print()
- {
- cout << "ClassNumber: "<<aValue<<endl;
- }
- };
- /******************** Statements ********************/
- class Statement
- {
- public:
- string name;
- Statement()
- {
- }
- virtual void convert(BBlock **) = 0;
- };
- class Assignment : public Statement //FEL I DENNA VID creation three add constant fel för rhs?
- {
- public:
- Variable *lhs;
- Expression *rhs;
- /* Assignment(string lhs, Expression *rhs) :
- lhs(new Variable(lhs)), rhs(rhs)
- {
- }*/
- Assignment(Variable* lhs, Expression *rhs) :
- lhs(lhs), rhs(rhs)
- {
- //rhs->name = lhs->makeNames();
- //name = lhs->makeNames();
- }
- void convert(BBlock **out)
- {
- cout<<"In assignmentClass"<<endl;
- //string tempName = rhs->convert(*out);
- lhs->print();
- //rhs->print();
- //(*out)->instructions.push_back(ThreeAd(lhs->convert(*out), '=', tempName, tempName));
- }
- };
- class Seq : public Statement
- {
- public:
- list<Statement*> aList;
- /* Seq(list<Statement*> listOfStatements)
- {
- aList = listOfStatements;
- }*/
- Seq()
- {
- }
- void convert(BBlock **out)
- {
- for(auto i : aList) // number of statements in testcase
- {
- cout << "in SequenceClass/convert"<<endl<<endl;
- i->convert(out);
- }
- }
- };
- class If : public Statement
- {
- public:
- Statement * case1;
- Statement * case2;
- Expression * compare;
- If(Expression *compare, Statement *case1, Statement * case2) :
- compare(compare), case1(case1), case2(case2)
- { // this->compare = other.compare
- }
- void convert(BBlock **out)
- {
- BBlock *blockTrue = new BBlock();
- BBlock *blockFalse = new BBlock();
- BBlock *blockJoin = new BBlock();
- compare->convert(*out); // compare set to cre for current block
- (*out)->tExit = blockTrue; //first block true exit and false exit to different blocks
- (*out)->fExit = blockFalse;
- case1->convert(&blockTrue); //case1 reference of blocktrue
- blockTrue->tExit = blockJoin; //true/false block undepending on case go to joining block
- blockTrue->fExit = blockJoin;
- case2->convert(&blockFalse); //case2 reference of blockfalse
- blockFalse->tExit = blockJoin;
- blockFalse->fExit = blockJoin;
- (*out) = blockJoin; // move pointer to joinblock exit
- }
- };
- /*--------------------END OF CREATION THREEADD--------------------------*/
- /*Statement *test = new Seq({
- new Assignment(
- "x", new Add( new Variable("x"),
- new Constant(1)
- )
- )
- , new Assignment(
- "y", new Add( new Variable("y"),
- new Constant(1)
- )
- )
- , new If(
- new Equality(
- new Variable("x"),
- new Constant(0)
- )
- , new If(
- new Equality(
- new Variable("y"),
- new Constant(0)
- )
- , new Assignment(
- "x", new Constant(1)
- )
- , new Assignment(
- "y", new Constant(2)
- )
- )
- , new Assignment(
- "x", new Constant(1)
- )
- )
- });*/
- /*
- * Iterate over each basic block that can be reached from the entry point
- * exactly once, so that we can dump out the entire graph.
- */
- void dumpCFG(BBlock *start, std::ofstream &afile)
- {
- set<BBlock *> done, todo;
- todo.insert(start);
- while(todo.size()>0)
- {
- // Pop an arbitrary element from todo set
- auto first = todo.begin();
- BBlock *next = *first;
- todo.erase(first);
- next->dump();
- //next->getList(afile); // new dump function to output assembly
- done.insert(next);
- if(next->tExit!=NULL && done.find(next->tExit)==done.end())
- todo.insert(next->tExit);
- if(next->fExit!=NULL && done.find(next->fExit)==done.end())
- todo.insert(next->fExit);
- }
- }
- Expression *convertExpression(Node &translateNode); //declarations
- Statement *convertStatement(Node &translateNode);
- /****************Expressions to convert from Parse-tree******************/
- Variable *convertVar(Node &translateNode) //get value from node and add to pointer
- {
- cout << "in convertVar:"<<endl<< translateNode.value <<endl;
- return new Variable(translateNode.value);
- }
- Constant *convertConst(Node &translateNode) //get value from node and add to pointer
- {
- cout <<"in convertConst:"<<endl;
- cout <<"e "<< translateNode.value<<endl<<endl;
- return new Constant(stoi(translateNode.value));
- }
- Quote *convertQuote(Node &translateNode) //get value from node and add to pointer
- {
- cout <<"in convertQuote:"<<endl<<endl;
- return new Quote(translateNode.value);
- }
- Add *convertAdd(Node &translateNode)
- {
- cout <<"in convertAdd:"<<endl;
- cout <<translateNode.value<<endl<<endl;
- cout << translateNode.children.front().value<<" WIIIIIEIIEIIE "<<endl;
- cout << translateNode.children.back().value<<" WIIIIIEIIEIIE "<<endl;
- Add * hejsan = new Add(convertExpression(translateNode.children.front()),convertExpression(translateNode.children.back()));
- return hejsan;
- }
- Mult *convertMult(Node &translateNode)
- {
- return new Mult(convertExpression(translateNode.children.front()),convertExpression(translateNode.children.back()));
- }
- Div *convertDiv(Node &translateNode)
- {
- return new Div(convertExpression(translateNode.children.front()),convertExpression(translateNode.children.back()));
- }
- Sub *convertSub(Node &translateNode)
- {
- return new Sub(convertExpression(translateNode.children.front()),convertExpression(translateNode.children.back()));
- }
- Equality *convertEquality(Node &translateNode)
- {
- return new Equality(convertExpression(translateNode.children.front()),convertExpression(translateNode.children.back()));
- }
- Expression *convertExpression(Node &translateNode) //call upon and decide which expression to use
- {
- cout << "in convertExpression:"<<endl;
- cout << translateNode.tag<<endl;
- cout << translateNode.value<<endl;
- Expression *pointer;
- if(translateNode.tag == "OP" )
- {
- if(translateNode.value == "ADD")
- {
- pointer = convertAdd(translateNode);
- }
- else if(translateNode.value == "SUB")
- {
- pointer = convertSub(translateNode);
- }
- else if(translateNode.value == "MUL")
- {
- pointer = convertMult(translateNode);
- }
- else if(translateNode.value == "DIV")
- {
- pointer = convertDiv(translateNode);
- }
- else if(translateNode.value == "EQ")
- {
- pointer = convertEquality(translateNode);
- }
- }
- else if(translateNode.tag == "var")
- {
- cout <<"--var"<<endl;
- convertVar(translateNode);
- }
- else if(translateNode.tag == "number")
- {
- cout<<"--number"<<endl;
- convertConst(translateNode);
- }
- else if(translateNode.tag == "string")
- {
- cout<<"--string"<<endl;
- convertQuote(translateNode);
- }
- return pointer;
- }
- /***********************************************************************/
- /****************Statements to convert from Parse-tree******************/
- Assignment * convertAssign(Node &translateNode) //get value from an assignment
- {
- cout << "in covertAssign:"<<endl;
- //cout << translateNode.tag << endl; //assignment node
- Node& var = translateNode.children.front();
- Node& exp = translateNode.children.back();
- //cout << var.tag << endl; //assignment node
- //cout << exp.tag << endl; //assignment node
- return new Assignment(convertVar(var),convertExpression(exp));
- }
- Statement *convertStatement(Node &translateNode) //call upon and decide which expression to use
- {
- Statement *pointer;
- //cout << translateNode.children.front().tag;
- pointer = convertAssign(translateNode);
- return pointer;
- }
- /***********************************************************************/
- Seq *convertSeq(Node &translateNode) //creating new sequence of statements, and loop through all statment children.
- {
- Seq *pointer;
- pointer = new Seq();
- Node &statement = translateNode.children.front(); //current node statement
- for(auto i : statement.children) //loop through all statements
- {
- pointer->aList.push_back(convertStatement(i));
- //cout << pointer->aList.front()<<endl;
- //cout << pointer->aList.back()<<endl;
- }
- return pointer;
- }
- /*
- output example:
- 1[label ="chunk "];
- 2[label ="chunk1 "];
- 3[label ="stat "];
- 4[label ="varlist "];
- 5[label ="var "];
- 6[label ="TEXT list"];
- --------------------------------------------
- Blocks:
- block0 [label="t1 <- x + y\nt2 <- t1 = 0\n...", shape="rect"];
- block1 [label="...", shape="rect"];
- block2 [label="...", shape="rect"];
- Arrows:
- block0 -> block1 [label="true"];
- block1 -> block0;
- block0 -> block2 [label="false"];
- */
- void yy::parser::error(std::string const&err)
- {
- std::cout << "ERROR " << err << std::endl;
- }
- int main(int argc, char **argv)
- {
- yyin = fopen(argv[1], "r");
- yy::parser parser;
- if(!parser.parse())
- {
- std::cout << "[Parse-tree:]" << std::endl;
- root.dump(); //print regular parseing
- }
- cout << "--------------------------------------\n[Translate:]\n";
- statement * newList;
- BBlock* b = new BBlock();
- BBlock* theRoot = b;
- newList = convertSeq(root.children.front()); //new List "chunk"
- cout << "--------------------------------------\n[Create:]\n";
- newList->convert(&b);
- /*
- std::ofstream afile;
- afile.open("cfg.dot");
- if (afile.is_open())
- {
- dumpCFG(theRoot, afile); //calls blocks of instructions
- //afile << "digraph {\n\t";
- //afile << flowGraph();
- //afile << "}";
- //BBlock* b = new BBlock();
- //BBlock* theRoot = b;
- //"statement"->convert(&b);
- afile << "digraph {\n\t";
- //afile << root.graph();
- afile << root.graph();
- afile << "}";
- //test->convert(&b);
- //dumpCFG(theRoot, afile); //calls blocks of instructions
- afile.close();
- }
- */
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement