-
Notifications
You must be signed in to change notification settings - Fork 0
/
parser.cpp
107 lines (101 loc) · 4.79 KB
/
parser.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include <regex>
#include <QRegExp>
#include <QTextStream>
#include <QMap>
#include <QDebug>
#include "parser.h"
using namespace std;
QVector<Instruction> Parser::parse(QFile& file){
QVector<Instruction> instructions;
Instruction current;
QMap<QString, InstType> mnem;
mnem.insert("ADD", ADD); mnem.insert("XOR", XOR); mnem.insert("SLT", SLT); mnem.insert("OR", OR);
mnem.insert("ADDI", ADDI); mnem.insert("SUBI", SUBI); mnem.insert("BEQ", BEQ); mnem.insert("BLE", BLE);
mnem.insert("LW", LW); mnem.insert("SW", SW);
mnem.insert("J", J); mnem.insert("JAL", JAL); mnem.insert("JR", JR);
QRegExp whitespace("^(\\s*)?$");
QRegExp ops_3("\\s*(ADD|XOR|SLT|OR|ADDI|SUBI|BEQ|BLE)\\s+\\$(\\d+)\\s*,\\s*\\$(\\d+)\\s*,\\s*(\\$?\\d+)\\s*");
QRegExp ops_2("\\s*(LW|SW)\\s+\\$(\\d+)\\s*,\\s*(\\d+)\\s*\\(\\s*\\$(\\d+)\\s*\\)\\s*");
QRegExp ops_1("\\s*(J|JAL|JR)\\s+(\\$?\\d+)\\s*");
QString error = "Error: Specify the file to be compiled first";
if(!file.open(QFile::ReadOnly)) throw(error);
QTextStream stream(&file);
QString row;
unsigned int counter=1;
while(!stream.atEnd()){
row = stream.readLine();
if(ops_3.indexIn(row) != -1){ //3 operand instructions
current.RawInst = row;
current.Mnemonic = mnem[ops_3.cap(1)];
if(current.Mnemonic == ADD || current.Mnemonic == XOR || current.Mnemonic == SLT || current.Mnemonic == OR){
if(ops_3.cap(4).at(0) != '$') throw("Error: Problem at instruction " + QString::number(counter));
current.rs = atoi(ops_3.cap(3).toStdString().c_str());
current.rt = atoi(ops_3.cap(4).toStdString().substr(1).c_str());
current.rd = atoi(ops_3.cap(2).toStdString().c_str());
current.imm = 0;
current.jaddr = 0;
try{
isvalid_reg(current.rs, counter); isvalid_reg(current.rt, counter); isvalid_reg(current.rd, counter);
}catch(QString error){throw error;}
}
else{
if(ops_3.cap(4).at(0) == '$') throw("Error: Problem at instruction " + QString::number(counter));
current.rs = atoi(ops_3.cap(3).toStdString().c_str());
current.rt = atoi(ops_3.cap(2).toStdString().c_str());
if(current.Mnemonic == BEQ || current.Mnemonic == BLE) swap(current.rs, current.rt);
current.rd = 0;
current.imm = atoi(ops_3.cap(4).toStdString().c_str());
current.jaddr = 0;
try{
isvalid_reg(current.rs, counter); isvalid_reg(current.rt, counter);
}catch(QString error){throw error;}
}
}
else if(ops_2.indexIn(row) != -1){ //2 operand instructions
current.RawInst = row;
current.Mnemonic = mnem[ops_2.cap(1)];
current.rs = atoi(ops_2.cap(4).toStdString().c_str());
current.rt = atoi(ops_2.cap(2).toStdString().c_str());
current.rd = 0;
current.imm = atoi(ops_2.cap(3).toStdString().c_str());
current.jaddr = 0;
try{
isvalid_reg(current.rs, counter); isvalid_reg(current.rt, counter);
}catch(QString error){throw error;}
}
else if(ops_1.indexIn(row) != -1){ //1 operand instrutions
current.RawInst = row;
current.Mnemonic = mnem[ops_1.cap(1)];
if(current.Mnemonic == JR){
if(ops_1.cap(2).at(0) != '$') throw("Error: Problem at instruction " + QString::number(counter));
current.rs = atoi(ops_1.cap(2).toStdString().substr(1).c_str());
current.rt = 0;
current.rd = 0;
current.imm = 0;
current.jaddr = 0;
try{
isvalid_reg(current.rs, counter);
}catch(QString error){throw error;}
}
else{
if(ops_1.cap(2).at(0) == '$') throw("Error: Problem at instruction " + QString::number(counter));
current.rs = 0;
current.rt = 0;
current.rd = 0;
current.imm = 0;
current.jaddr = atoi(ops_1.cap(2).toStdString().c_str());
try{
isvalid_reg(current.jaddr, counter);
}catch(QString error){throw error;}
}
}
else if(whitespace.indexIn(row) != -1) continue;
else throw("Error: Problem at instruction " + QString::number(counter));
instructions.push_back(current);
counter++;
}
return instructions;
}
void Parser::isvalid_reg(int val, int counter){
if(val<0 || val>=RegisterFile::RegisterCount) throw("Error: Register address out of range at instruction " + QString::number(counter));
}