Skip to content

Commit

Permalink
add intermediate code generator for array
Browse files Browse the repository at this point in the history
  • Loading branch information
AveryQi115 committed May 15, 2021
1 parent 6f6fb55 commit 89d24e7
Show file tree
Hide file tree
Showing 14 changed files with 1,062 additions and 560 deletions.
20 changes: 20 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(lldb) 启动",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/MyCompiler",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "lldb"
}
]
}
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"files.associations": {
"typeinfo": "cpp"
}
}
4 changes: 3 additions & 1 deletion Common.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ typedef enum //枚举类型,保存词素类型
/* 行注释 段注释 */
LCOMMENT, PCOMMENT,
/*换行符*/
NEXTLINE
NEXTLINE,
/* [ ] */
LBRACKET, RBRACKET
} LexicalType;

typedef pair<LexicalType, string> Token;
Expand Down
10 changes: 9 additions & 1 deletion LexicalAnalyser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ string token_to_string(Token t) {
"SEMI", // ;
"COMMA", // ,
"LCOMMENT", // //
"PCOMMENT" // /* */
"PCOMMENT", // /* */
"LBRACKET", // [
"RBRACKET" // ]
};

string res;
Expand Down Expand Up @@ -148,6 +150,12 @@ Token LexicalAnalyser::getNextToken() {
return Token(ERROR, string("词法分析第")+to_string(lineCount)+string("行:未识别的符号!"));
}
break;
case '[':
return Token(LBRACKET,"[");
break;
case ']':
return Token(RBRACKET,"]");
break;
case '/':
//行注释
if (src.peek() == '/') {
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
CC = g++
CXX_FLAGS = -std=c++11 -w
CXX_FLAGS = -std=c++11 -w -g

BIN = MyCompiler

Expand Down
94 changes: 81 additions & 13 deletions ParserAndSemanticAnalyser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ ArrayDeclare::ArrayDeclare(const Symbol& sym) : Symbol(sym) {}

ArrayDeclareList::ArrayDeclareList(const Symbol& sym) : Symbol(sym) {}

Array::Array(const Symbol& sym) : Symbol(sym) {}

IndexList::IndexList(const Symbol& sym) : Symbol(sym) {}

SentenceBlock::SentenceBlock(const Symbol& sym) : Symbol(sym) {}

SentenceList::SentenceList(const Symbol& sym) : Symbol(sym) {}
Expand Down Expand Up @@ -93,7 +97,7 @@ bool isVT(string s) {
if (s == "+" || s == "-" || s == "*" || s == "/" || s == "=" || s == "==" || s == ">" || s == "<" || s == "!=" || s == ">=" || s == "<=") {
return true;
}
if (s == ";" || s == "," || s == "(" || s == ")" || s == "{" || s == "}" || s == "ID" || s == "NUM") {
if (s == ";" || s == "," || s == "(" || s == ")" || s == "{" || s == "}" || s == "ID" || s == "[" || s == "]" || s == "NUM") {
return true;
}
return false;
Expand Down Expand Up @@ -1045,13 +1049,11 @@ void ParserAndSemanticAnalyser::analyse(list<Token>&words, ostream& out) {
ArrayDeclareList* array_declare_list = (ArrayDeclareList*)popSymbol();
Id* ID = (Id*)popSymbol();
Symbol* _int = popSymbol();
if (array_declare_list->size <= 0)
if (array_declare_list->total_size <= 0)
outputError(string("语法错误:第") + to_string(lineCount) + "行,数组" + ID->name + "容量不合法");

for(int i=0;i<array_declare_list->size;i++){
string name = ID->name+"_"+to_string(i);
varTable.push_back(Var{ name,D_INT,nowLevel });
}
string name = ID->name;
varTable.push_back(Var{ name,D_INT_ARRAY,nowLevel,array_declare_list->size});
pushSymbol(new Symbol(reductPro.left));
break;
}
Expand All @@ -1060,7 +1062,9 @@ void ParserAndSemanticAnalyser::analyse(list<Token>&words, ostream& out) {
ArrayDeclareList* array_declare_list = (ArrayDeclareList*)popSymbol();
ArrayDeclare* array_declare = (ArrayDeclare*)popSymbol();
ArrayDeclareList* total_list = new ArrayDeclareList(reductPro.left);
total_list->size = array_declare->size * array_declare_list->size;
total_list->size = vector<int>(array_declare_list->size);
total_list->size.insert(total_list->size.begin(),array_declare->size);
total_list->total_size = array_declare->size * array_declare_list->total_size;
pushSymbol(total_list);
break;
}
Expand All @@ -1069,7 +1073,9 @@ void ParserAndSemanticAnalyser::analyse(list<Token>&words, ostream& out) {
Symbol* semi = popSymbol();
ArrayDeclare* array_declare = (ArrayDeclare*)popSymbol();
ArrayDeclareList* total_list = new ArrayDeclareList(reductPro.left);
total_list->size = array_declare->size;
total_list->size = vector<int>();
total_list->size.push_back(array_declare->size);
total_list->total_size = array_declare->size;
pushSymbol(total_list);
break;
}
Expand All @@ -1085,25 +1091,87 @@ void ParserAndSemanticAnalyser::analyse(list<Token>&words, ostream& out) {
}
case 56://assign_sentence ::= array = expression ;
{
Symbol* comma = popSymbol();
Symbol* semi = popSymbol();
Expression* expression = (Expression*)popSymbol();
Symbol* assign = popSymbol();
Id* ID = (Id*)popSymbol();
Array* array = (Array*)popSymbol();
Symbol* assign_sentence = new Symbol(reductPro.left);
code.emit("=", expression->name, "_", ID->name);
code.emit("[]=", expression->name, "_", array->name);
pushSymbol(assign_sentence);
break;
}
case 57://factor ::= array
{
Array* array = (Array*)popSymbol();
Factor* factor = new Factor(reductPro.left);
factor->name = array->name;
pushSymbol(factor);
break;
}
case 58://array ::= ID index_list
{
IndexList* index_list = (IndexList*)popSymbol();
Id* ID = (Id*)popSymbol();
Var* v = lookUpVar(ID->name);
if (v == NULL || v->type!=D_INT_ARRAY)
outputError(string("语法错误:第") + to_string(lineCount) + "行,数组"+ID->name+"不存在");
if (index_list->index.size()>v->size.size())
outputError(string("语法错误:第") + to_string(lineCount) + "行,数组"+ID->name+"索引不合法");

// 解析index_list
Nomial* total_index = new Nomial(Symbol());
if(v->size.size()==1)
total_index->name = index_list->index.at(0);
else{
total_index->name = "0";
int former_size = 1;

for(int i=v->size.size()-1;i>=0;i--){
string cur_index = "0";
string new_base = "0";
if (i < index_list->index.size()){
cur_index = index_list->index.at(i);
// new_base = cur_index * former_size
if (cur_index != "0"){
new_base = nt.newTemp();
code.emit("*",cur_index,to_string(former_size),new_base);
}

// total_index = new_base + total_index
if(total_index->name!="0" && new_base!="0")
code.emit("+",total_index->name,new_base,total_index->name);
else if(total_index->name=="0")
total_index->name = new_base;
}
former_size *= v->size.at(i);
}
}
Array* array = new Array(reductPro.left);
array->name = ID->name+"["+total_index->name+"]";
pushSymbol(array);
break;
}
case 58://array ::= ID [ expression ]
case 59://index_list ::= [ expression ] index_list
{
IndexList* old_index_list = (IndexList*)popSymbol();
Symbol* rbracket = popSymbol();
Expression* ex = (Expression*)popSymbol();
Symbol* lbracket = popSymbol();
IndexList* new_index_list = new IndexList(reductPro.left);
new_index_list->index = vector<string>(old_index_list->index);
new_index_list->index.insert(new_index_list->index.begin(),ex->name);
pushSymbol(new_index_list);
break;
}
case 59://array ::= array [ expression ]
case 60://index_list ::= [ expression ]
{
Symbol* rbracket = popSymbol();
Expression* ex = (Expression*)popSymbol();
Symbol* lbracket = popSymbol();
IndexList* new_index_list = new IndexList(reductPro.left);
new_index_list->index = vector<string>();
new_index_list->index.push_back(ex->name);
pushSymbol(new_index_list);
break;
}
default:
Expand Down
18 changes: 16 additions & 2 deletions ParserAndSemanticAnalyser.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@ enum DecType {
};

//数据类型(int/void)
enum DType { D_VOID, D_INT };
enum DType { D_VOID, D_INT, D_INT_ARRAY };


struct Var {
string name;
DType type;
int level;
vector<int>size;
};

struct Func {
Expand Down Expand Up @@ -75,10 +76,23 @@ class ArrayDeclare :public Symbol {

class ArrayDeclareList :public Symbol {
public:
int size;
vector<int> size;
int total_size;
ArrayDeclareList(const Symbol& sym);
};

class Array :public Symbol {
public:
string name;
Array(const Symbol& sym);
};

class IndexList :public Symbol {
public:
vector<string> index;
IndexList(const Symbol& sym);
};

class SentenceBlock :public Symbol {
public:
list<int>nextList;
Expand Down
21 changes: 11 additions & 10 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,27 @@
******************************/
int main() {
// test.txt中存放需要解析的代码
LexicalAnalyser lexicalAnalyser("test.txt");
LexicalAnalyser lexicalAnalyser("test_with_array.txt");
lexicalAnalyser.analyse();

//productions.txt中存放语法规则
ParserAndSemanticAnalyser parserAndSemanticAnalyser("productions.txt");
parserAndSemanticAnalyser.outputDFA("result/DFA.txt");

//根据移进规约表分析词法结果并将分析结果输出到SLR1_analyse.txt
parserAndSemanticAnalyser.analyse(lexicalAnalyser.getResult(), "result/SLR1_analyse.txt");
parserAndSemanticAnalyser.outputIntermediateCode("result/Intermediate.txt");

IntermediateCode* code = parserAndSemanticAnalyser.getIntermediateCode();
code->divideBlocks(parserAndSemanticAnalyser.getFuncEnter());
code->outputBlocks("result/funBlocks.txt");
// IntermediateCode* code = parserAndSemanticAnalyser.getIntermediateCode();
// code->divideBlocks(parserAndSemanticAnalyser.getFuncEnter());
// code->outputBlocks("result/funBlocks.txt");

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

return 0;
}
7 changes: 4 additions & 3 deletions productions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,10 @@ argument_list ::= expression
argument_list ::= expression , argument_list
declare ::= int ID array_declare_list
array_declare_list ::= array_declare array_declare_list
array_declare_list ::= array_declare
array_declare_list ::= array_declare ;
array_declare ::= [ NUM ]
assign_sentence ::= array = expression ;
factor ::= array
array ::= ID [ expression ]
array ::= array [ expression ]
array ::= ID index_list
index_list ::= [ expression ] index_list
index_list ::= [ expression ]
5 changes: 3 additions & 2 deletions productions_with_explanation.txt
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,9 @@ factor ::= ID ( argument_list )
factor ::= ID
factor ::= array

array ::= ID [ expression ]
array ::= array [ expression ]
array ::= ID index_list
index_list ::= [ expression ] index_list
index_list ::= [ expression ]

// 实参
argument_list ::=
Expand Down
Loading

0 comments on commit 89d24e7

Please sign in to comment.