I have written a parser which reads in a text file with the text in the format of the following types:
a r3, r2, r1
ah r8, r5, r6, r7
ai r10, i10, r127
the number for r can change and the initial characters can change. Basically what the parser does is based on the initial characters (a, ah, etc..), it will define an opcode value and then parse the register numbers and convert those into binary. It will concatenate all these values together to create a 32-bit long binary instruction string and output this to a text file.
While testing it, i have ran into an error.
Here is my code:
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <vector>
#include <bitset>
using namespace std;
void main()
{
string instruction, input, OpCode;
int i = 0;
int format = 0;
vector<string> myString;
ifstream inFile;
inFile.open("myfile.txt");
//format 1 -> input: syntax/rt/ra/rb output -> opcode/rb/ra/rt
//format 2 -> input: syntax/rt/ra/rb/rc output -> opcode/rt/rb/ra/rc
//format 3 -> input: syntax/rt/ra output -> opcode/i7/ra/rt
//format 4 -> input: syntax/rt/ra output -> opcode/i10/ra/rt
//format 5 -> input: syntax/rt output -> opcode/i16/rt
if (inFile.is_open()){
cout << "test" << endl;
//Read until no more lines in text file to read
while (getline(inFile, input))
{
istringstream ss(input);
string token;
//Get the instruction token
getline(ss, token, ' ');
instruction = token;
//ADD WORD
if (instruction == "a"){
OpCode = "00011000000";
format = 1;
}
if (format == 1){
// Seperate the registers
//We have RA, RB, AND RT
//Convert the values into binary
string value;
while (getline(ss, token, ',')){
ss.ignore();
token.erase(0, 1); //Remove the "r" or "i" character from each string/register
myString.push_back(token);
}
for (int j = 0; j < myString.size(); j++)
{
cout << myString[j] << endl;
value = bitset<8>(myString[j]).to_string();
cout << value << endl;
OpCode = OpCode + value;
cout << OpCode << endl;
}
}
}
}
system("pause");
}
For the sake of simplicity, i have only put 1 if statement for the add word instruction. The input i am using for to test is the following:
a r3, r1, r2
What it should do is see the instruction is a
, so OpCode
gets set and it will proceed to parse r3, r2, r1
. It will remove the r
and convert 3, 2, and 1 into its binary value and place that into a string which is concatenated with OpCode to form a 32-bit long instruction. The issue i am having is with value = bitset<8>myString[j]).to_string();
. Visual studio throws the following error while debugging:
Unhandled exception at 0X7712C52F in Assembler_Parser.exe: Microsoft C++ exception: std::invalid_arguement at memory location 0x0039F110.
Im not sure what to make of this. It gives me the option to break or continue. If i continue, it will convert 3 into 00000000. On the next iteration, it properly convert 2 to 00000010, but then again it throws an exception for 1.
Im not sure why this is happening.
The string constructor of bitset
doesn't convert the value from its decimal (or hex) representation to binary. If any character it encounters is not 0
or 1
it throws an std::invalid_argument
exception. Try std::stoi
:
value = bitset<8>(std::stoi(myString[j])).to_string();