Skip to content

Commit

Permalink
sync
Browse files Browse the repository at this point in the history
  • Loading branch information
qihaoyu committed May 19, 2021
1 parent 9459f91 commit 410c1c8
Show file tree
Hide file tree
Showing 13 changed files with 330 additions and 51 deletions.
Binary file modified Common.o
Binary file not shown.
Binary file modified IntermediateCode.o
Binary file not shown.
Binary file modified LexicalAnalyser.o
Binary file not shown.
Binary file modified MyCompiler
Binary file not shown.
217 changes: 189 additions & 28 deletions ObjectCodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,35 @@ bool isArrItem(string name) {
return name.find("[")!=string::npos;
}

string getArrName(string name) {
cout << name.substr(0,name.find('[')) << endl;
return name.substr(0,name.find('['));
string ObjectCodeGenerator::getArrName(string name) {
string arrName = name.substr(0,name.find('['));
if (arrays.find(arrName)==arrays.end()){
outputError("数组"+arrName+": 不存在!");
return "";
}
return arrName;
}

int ObjectCodeGenerator::getArrIndex(string name, string& index) {
string arrName = name.substr(0,name.find('['));
if (arrays.find(arrName)==arrays.end()){
outputError("数组"+arrName+": 不存在!");
return -1;
}

if(isNum(name.substr(name.find('[')+1,name.find(']')))){
int offset = atoi(name.substr(name.find('[')+1,name.find(']')).c_str());
int size = arrays.find(arrName)->second.length;
if(offset<0 || offset >= size){
outputError("数组"+arrName+": index "+to_string(offset)+" out of range.("+to_string(size)+");");
return -1;
}
return offset;
}
else{
index = name.substr(name.find('[')+1,name.find(']'));
return -1;
}
}

VarInfomation::VarInfomation(int next, bool active) {
Expand Down Expand Up @@ -72,15 +98,30 @@ ObjectCodeGenerator::ObjectCodeGenerator() {
}

void ObjectCodeGenerator::storeVar(string reg, string var) {
if (varOffset.find(var) != varOffset.end()) {//如果已经为*iter分配好了存储空间
objectCodes.push_back(string("sw ") + reg + " " + to_string(varOffset[var]) + "($sp)");
if(!isArrItem(var)){
if (varOffset.find(var) != varOffset.end()) {//如果已经为*iter分配好了存储空间
objectCodes.push_back(string("sw ") + reg + " " + to_string(varOffset[var]) + "($sp)");
}
else {
varOffset[var] = top;
top += 4;
objectCodes.push_back(string("sw ") + reg + " " + to_string(varOffset[var]) + "($sp)");
}
Avalue[var].insert(var);
}
else {
varOffset[var] = top;
top += 4;
objectCodes.push_back(string("sw ") + reg + " " + to_string(varOffset[var]) + "($sp)");
else{
string arrName = getArrName(var);
string index;
int offset = getArrIndex(var,index);
if(offset!=-1)
objectCodes.push_back(string("sw ") + reg + " " + arrName + "+" + to_string(4*offset));
else{
string indexPos = allocateReg(index);
objectCodes.push_back(string("sw ") + reg + " " + arrName + "(" + indexPos + ")");
}

Avalue[var].insert(var);
}
Avalue[var].insert(var);
}

void ObjectCodeGenerator::releaseVar(string var) {
Expand Down Expand Up @@ -189,8 +230,16 @@ string ObjectCodeGenerator::allocateReg() {
//为引用变量分配寄存器
string ObjectCodeGenerator::allocateReg(string var) {
if (isNum(var)) {
for (set<string>::iterator iter = Avalue[var].begin(); iter != Avalue[var].end(); iter++) {
if ((*iter)[0] == '$') {//如果变量已经保存在某个寄存器中
return *iter;//直接返回该寄存器
}
}

string ret = allocateReg();
objectCodes.push_back(string("addi ") + ret + " $zero " + var);
Avalue[var].insert(ret);
Rvalue[ret].insert(var);
return ret;
}

Expand All @@ -202,8 +251,18 @@ string ObjectCodeGenerator::allocateReg(string var) {

//如果该变量没有在某个寄存器中
string ret = allocateReg();

// 数组元素
if (isArrItem(var)){

string arrName = getArrName(var);
string index;
int offset = getArrIndex(var,index);
if(offset!=-1)
objectCodes.push_back(string("lw ") + ret + " " + arrName + "+" + to_string(4*offset));
else{
string indexPos = allocateReg(index);
objectCodes.push_back(string("lw ") + ret + " " + arrName + "(" + indexPos + ")");
}
}
else{
objectCodes.push_back(string("lw ") + ret + " " + to_string(varOffset[var]) + "($sp)");
Expand Down Expand Up @@ -237,8 +296,6 @@ string ObjectCodeGenerator::getReg() {
}
}

//为目标变量分配可能不正确
//return allocateReg(nowQuatenary->q.des);
string ret = allocateReg();
Avalue[nowQuatenary->q.des].insert(ret);
Rvalue[ret].insert(nowQuatenary->q.des);
Expand Down Expand Up @@ -266,12 +323,29 @@ void ObjectCodeGenerator::analyseBlock(map<string, vector<Block> >*funcBlocks) {
//pass
}
else if (citer->op[0] == 'j') {//j>= j<=,j==,j!=,j>,j<
if (isVar(citer->src1) && def.count(citer->src1) == 0) {//如果源操作数1还没有被定值
if (isVar(citer->src1) && !isArrItem(citer->src1) && def.count(citer->src1) == 0) {//如果源操作数1还没有被定值
use.insert(citer->src1);
}
if (isVar(citer->src2) && def.count(citer->src2) == 0) {//如果源操作数2还没有被定值
if (isArrItem(citer->src1)) {
if (def.count(getArrName(citer->src1)) == 0)
use.insert(getArrName(citer->src1));
string index;
int offset = getArrIndex(citer->src1,index);
if(offset==-1 && def.count(index)==0)
use.insert(index);
}

if (isVar(citer->src2) && !isArrItem(citer->src2) && def.count(citer->src2) == 0) {//如果源操作数2还没有被定值
use.insert(citer->src2);
}
if (isArrItem(citer->src2)) {
if (def.count(getArrName(citer->src2)) == 0)
use.insert(getArrName(citer->src2));
string index;
int offset = getArrIndex(citer->src2,index);
if(offset==-1 && def.count(index)==0)
use.insert(index);
}
}
// TODO:arr[index]目前的设计是整个数组会被加入到def和use中
// TODO:arr_declare目前的设计是arr名会被加入到def中
Expand All @@ -284,19 +358,34 @@ void ObjectCodeGenerator::analyseBlock(map<string, vector<Block> >*funcBlocks) {
if (length<=0){
outputError(citer->des+"数组容量不合法");
}
for(int i=0;i<length;i++){
def.insert(citer->des+"["+to_string(i)+"]");
}
arrays.push_back(ArrInfo{citer->des,atoi(citer->src1.c_str()),false});
def.insert(citer->des);
arrays.insert(pair<string,ArrInfo>(citer->des,ArrInfo{atoi(citer->src1.c_str()),false}));
}
}
else {
if (isVar(citer->src1) && def.count(citer->src1) == 0) {//如果源操作数1还没有被定值
if (isVar(citer->src1) && !isArrItem(citer->src1) && def.count(citer->src1) == 0) {//如果源操作数1还没有被定值
use.insert(citer->src1);
}
if (isVar(citer->src2) && def.count(citer->src2) == 0) {//如果源操作数2还没有被定值
if (isArrItem(citer->src1)) {
if (def.count(getArrName(citer->src1)) == 0)
use.insert(getArrName(citer->src1));
string index;
int offset = getArrIndex(citer->src1,index);
if(offset==-1 && def.count(index)==0)
use.insert(index);
}

if (isVar(citer->src2) && !isArrItem(citer->src2) && def.count(citer->src2) == 0) {//如果源操作数2还没有被定值
use.insert(citer->src2);
}
if (isArrItem(citer->src2)) {
if (def.count(getArrName(citer->src2)) == 0)
use.insert(getArrName(citer->src2));
string index;
int offset = getArrIndex(citer->src2,index);
if(offset==-1 && def.count(index)==0)
use.insert(index);
}
if (isVar(citer->des) && use.count(citer->des) == 0) {//如果目的操作数还没有被引用
def.insert(citer->des);
}
Expand Down Expand Up @@ -412,24 +501,59 @@ void ObjectCodeGenerator::analyseBlock(map<string, vector<Block> >*funcBlocks) {
if (isVar(citer->q.src1)) {
citer->info1 = symTables[blockIndex][citer->q.src1];
symTables[blockIndex][citer->q.src1] = VarInfomation{ codeIndex,true };
if (isArrItem(citer->q.src1)){
string index;
int offset = getArrIndex(citer->q.src1,index);
if(offset==-1){
symTables[blockIndex][index] = VarInfomation{ codeIndex,true };
}
}
}
if (isVar(citer->q.src2)) {
citer->info2 = symTables[blockIndex][citer->q.src2];
symTables[blockIndex][citer->q.src2] = VarInfomation{ codeIndex,true };
if (isArrItem(citer->q.src2)){
string index;
int offset = getArrIndex(citer->q.src2,index);
if(offset==-1){
symTables[blockIndex][index] = VarInfomation{ codeIndex,true };
}
}
}
}
else {
if (isVar(citer->q.src1)) {
citer->info1 = symTables[blockIndex][citer->q.src1];
symTables[blockIndex][citer->q.src1] = VarInfomation{ codeIndex,true };
if (isArrItem(citer->q.src1)){
string index;
int offset = getArrIndex(citer->q.src1,index);
if(offset==-1){
symTables[blockIndex][index] = VarInfomation{ codeIndex,true };
}
}
}
if (isVar(citer->q.src2)) {
citer->info2 = symTables[blockIndex][citer->q.src2];
symTables[blockIndex][citer->q.src2] = VarInfomation{ codeIndex,true };
if (isArrItem(citer->q.src2)){
string index;
int offset = getArrIndex(citer->q.src2,index);
if(offset==-1){
symTables[blockIndex][index] = VarInfomation{ codeIndex,true };
}
}
}
if (isVar(citer->q.des)) {
citer->info3 = symTables[blockIndex][citer->q.des];
symTables[blockIndex][citer->q.des] = VarInfomation{ -1,false };
if (isArrItem(citer->q.des)){
string index;
int offset = getArrIndex(citer->q.des,index);
if(offset==-1){
symTables[blockIndex][index] = VarInfomation{ codeIndex,true };
}
}
}
}
}
Expand Down Expand Up @@ -515,13 +639,20 @@ void ObjectCodeGenerator::storeOutLiveVar(set<string>&outl) {
}

void ObjectCodeGenerator::generateCodeForQuatenary(int nowBaseBlockIndex, int &arg_num, int &par_num, list<pair<string, bool> > &par_list) {
if (nowQuatenary->q.op[0] != 'j'&&nowQuatenary->q.op != "call") {
if (isVar(nowQuatenary->q.src1) && Avalue[nowQuatenary->q.src1].empty()) {
if (nowQuatenary->q.op[0] != 'j' && nowQuatenary->q.op != "call" && nowQuatenary->q.op != "array_declare") {
if (isVar(nowQuatenary->q.src1) && !isArrItem(nowQuatenary->q.src1) && Avalue[nowQuatenary->q.src1].empty()) {
outputError(string("变量") + nowQuatenary->q.src1 + "在引用前未赋值");
}
if (isVar(nowQuatenary->q.src2) && Avalue[nowQuatenary->q.src2].empty()) {
if (isArrItem(nowQuatenary->q.src1)){
Avalue[nowQuatenary->q.src1].insert(nowQuatenary->q.src1);
}

if (isVar(nowQuatenary->q.src2) && !isArrItem(nowQuatenary->q.src2) && Avalue[nowQuatenary->q.src2].empty()) {
outputError(string("变量") + nowQuatenary->q.src2 + "在引用前未赋值");
}
if (isArrItem(nowQuatenary->q.src2)){
Avalue[nowQuatenary->q.src2].insert(nowQuatenary->q.src2);
}
}


Expand Down Expand Up @@ -578,7 +709,7 @@ void ObjectCodeGenerator::generateCodeForQuatenary(int nowBaseBlockIndex, int &a
if (isNum(nowQuatenary->q.src1)) {//返回值为数字
objectCodes.push_back("addi $v0 $zero " + nowQuatenary->q.src1);
}
else if (isVar(nowQuatenary->q.src1)) {//返回值为变量
else if (isVar(nowQuatenary->q.src1) && !isArrItem(nowQuatenary->q.src1)) {//返回值为变量
set<string>::iterator piter = Avalue[nowQuatenary->q.src1].begin();
if ((*piter)[0] == '$') {
objectCodes.push_back(string("add $v0 $zero ") + *piter);
Expand All @@ -587,6 +718,19 @@ void ObjectCodeGenerator::generateCodeForQuatenary(int nowBaseBlockIndex, int &a
objectCodes.push_back(string("lw $v0 ") + to_string(varOffset[*piter]) + "($sp)");
}
}
else if(isArrItem(nowQuatenary->q.src1)) {// 返回值为数组元素
string var = nowQuatenary->q.src1;
string arrName = getArrName(var);
string index;
int offset = getArrIndex(var,index);
if(offset!=-1)
objectCodes.push_back(string("lw $v0 ") + arrName + "+" + to_string(4*offset));
else{
string indexPos = allocateReg(index);
objectCodes.push_back(string("lw $v0 ") + arrName + "(" + indexPos + ")");
}
}

if (nowFunc == "main") {
objectCodes.push_back("j end");
}
Expand All @@ -613,11 +757,28 @@ void ObjectCodeGenerator::generateCodeForQuatenary(int nowBaseBlockIndex, int &a
Rvalue[src1Pos].insert(nowQuatenary->q.des);
Avalue[nowQuatenary->q.des].insert(src1Pos);
}
else if (nowQuatenary->q.op == "array_declare"){

else if (nowQuatenary->q.op == "array_declare"){// array_declare, size, _, arrName
for(int i=0;i<atoi(nowQuatenary->q.src1.c_str());i++){
Avalue[nowQuatenary->q.src1+"["+to_string(i)+"]"].insert(nowQuatenary->q.src1+"["+to_string(i)+"]");
}
}
else if (nowQuatenary->q.op == "[]="){//[]= src _ arr[index]
string src1Pos = allocateReg(nowQuatenary->q.src1);
string var = nowQuatenary->q.des;
string arrName = getArrName(var);
string index;
int offset = getArrIndex(var,index);
if(offset!=-1)
objectCodes.push_back(string("sw ") + src1Pos + " " + arrName + "+" + to_string(4*offset));
else{
string indexPos = allocateReg(index);
objectCodes.push_back(string("sw ") + src1Pos + " " + arrName + "(" + indexPos + ")");
}
Avalue[var].insert(src1Pos);

if (!nowQuatenary->info3.active) {
releaseVar(var);
}
}
else {// + - * /
string src1Pos = allocateReg(nowQuatenary->q.src1);
Expand Down Expand Up @@ -716,7 +877,7 @@ void ObjectCodeGenerator::generateDataSegment() {

objectCodes.push_back(".data");
for(auto iter = arrays.begin();iter!=arrays.end();iter++){
objectCodes.push_back(iter->name + ": .space "+to_string(iter->length * 4));
objectCodes.push_back(iter->first + ": .space "+to_string(iter->second.length * 4));
}
}

Expand Down
6 changes: 4 additions & 2 deletions ObjectCodeGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ struct IBlock {

// 数组相关信息
struct ArrInfo {
string name; // 数组名,寻址基址
int length; // 数组长度(本项目中只存在int和void型所以数组元素大小为4)
bool active; // 在当前context中是否活跃
};
Expand All @@ -54,7 +53,10 @@ class ObjectCodeGenerator {
vector<IBlock>::iterator nowIBlock;//当前分析的基本块
vector<QuaternaryWithInfo>::iterator nowQuatenary;//当前分析的四元式
vector<string>objectCodes;
vector<ArrInfo>arrays;
map<string, ArrInfo>arrays;

string getArrName(string name);
int getArrIndex(string name, string& index);

void outputIBlocks(ostream& out);
void outputObjectCode(ostream& out);
Expand Down
Binary file modified ObjectCodeGenerator.o
Binary file not shown.
Binary file modified Optimizer.o
Binary file not shown.
Binary file modified ParserAndSemanticAnalyser.o
Binary file not shown.
5 changes: 2 additions & 3 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,9 @@ int main() {

ObjectCodeGenerator objectCodeGenerator;
objectCodeGenerator.analyseBlock(code->getFuncBlock());
objectCodeGenerator.outputIBlocks();
objectCodeGenerator.outputIBlocks("result/IBlocks.txt");
objectCodeGenerator.generateCode();
// objectCodeGenerator.outputObjectCode();
// objectCodeGenerator.outputObjectCode("result/program.asm");
objectCodeGenerator.outputObjectCode("result/program.asm");

return 0;
}
Binary file modified main.o
Binary file not shown.
Loading

0 comments on commit 410c1c8

Please sign in to comment.