Reputation: 9
the works fine for the starting few lines then stops working.
while(!feof(fp)){
char cc=fgetc(fp);fputc(cc,o);putchar(cc);
if(cc==EOF)break;
if(cc=='\n'){
char aa=fgetc(fp);
fseek(fp,-1,SEEK_CUR);
if(aa==' '){
fscanf(fp,"%s",&mne);
fprintf(o,"\t%s\t",mne);
printf("\t%s\t",mne);
if(!strcmp(mne,"RSUB")){strcat(objectCode[count].n,get_opcode(mne));
printf("%s\n",objectCode[count].n);count++;
continue;}
fscanf(fp,"%s",&var);
fprintf(o,"%s",var);
printf("%s\t",var);
char buff[10];
strcat(objectCode[count].n,get_opcode(mne));
sprintf(buff,"%0X",get_add(var));
strcat(objectCode[count].n,buff);
fprintf(o,"%s\n",objectCode[count].n);
printf("%s\n",objectCode[count].n);
count++;
continue;
}
cout<<"\nno tabs\n";
**fscanf(fp,"%s%s%s",&a,&mne,&var);**
fprintf(o,"%s\t%s\t%s",a,mne,var);
printf("%s\t%s\t%s\t",a,mne,var);
if(!strcmp(mne,"BYTE"))
{
char buff[4];
for(int i=2;i<(strlen(var)-1);i++)
{
sprintf(buff,"%0X",(int)var[i]);
strcat(objectCode[count].n,buff);
}
fprintf(o,"%s\n",objectCode[count].n);
printf("%s\n",objectCode[count].n);
count++;
continue;
}
else if(!strcmp(mne,"WORD"))
{
char buff[10];
sprintf(buff,"%d",get_add(var));
strcat(objectCode[count].n,buff);
fprintf(o,"%s\n",objectCode[count].n);
printf("%s\n",objectCode[count].n);
count++; continue;
}
else if(!strcmp(mne,"RESW"))
{
strcat(objectCode[count].n,"------");
fprintf(o,"%s\n",objectCode[count].n);
printf("%s\n",objectCode[count].n);
}
else if(!strcmp(mne,"RESB"))
{
strcat(objectCode[count].n,"------");
fprintf(o,"\t%s\n",objectCode[count].n);
printf("%s\n",objectCode[count].n);
}
else
{
char buff[10];
strcat(objectCode[count].n,get_opcode(mne));
sprintf(buff,"%0X",get_add(var));
strcat(objectCode[count].n,buff);
fprintf(o,"%s\n",objectCode[count].n);
printf("%s\n",objectCode[count].n);
}
count++;
}
}
i am trying to read the following content from a file and generate the opcode.
COPY START 1000
FIRST STL RETADR
CLOOP JSUB RDREC
LDA LENGTH
COMP ZERO
JEQ ENDFIL
JSUB WRREC
J CLOOP
ENDFIL LDA EOF
STA BUFFER
LDA THREE
STA LENGTH
JSUB WRREC
LDL RETADR
RSUB
EOF BYTE C'EOF'
THREE WORD 3
ZERO WORD 0
RETADR RESW 1
LENGTH RESW 1
BUFFER RESB 4096
RDREC LDX ZERO
LDA ZERO
RLOOP TD INPUT
JEQ RLOOP
RD INPUT
COMP ZERO
JEQ EXIT
STCH BUFFER,X
TIX MAXLEN
JLT RLOOP
EXIT STX LENGTH
RSUB
INPUT BYTE X'F1'
MAXLEN WORD 4096
WRREC LDX ZERO
WLOOP TD OUTPUT
JEQ WLOOP
LDCH BUFFER,X
WD OUTPUT
TIX LENGTH
JLT WLOOP
RSUB
OUTPUT BYTE X'05'
END FIRST
works fine till this line:
EOF BYTE C'EOF'
i tried indicators, it does enter the loop after this line but does not work from the fscanf line: fscanf(fp,"%s%s%s",&a,&mne,&var);
then goes into a deadlock. the fscanf stops working. please help.what might be the issue?
Upvotes: 0
Views: 130
Reputation: 57728
One issue that is a thorn is the optional label.
Most lines are of the format:
<optional-label> <instruction> <operands>
Since each instruction is on a separate line, reading the file line by line and parsing the line seem to be the best issue here (as opposed to a more free form language like C++).
So we start with the fundamental program:
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
void Process_Text_Line(const std::string& text_line)
{
std::cout << text_line << "\n";
}
int main()
{
std::ifstream program_file("my_program.asm");
std::string text_line;
while (std::getline(program_file, text_line);
{
// For now, echo the instruction
Process_Text(text_line);
}
return EXIT_SUCCESS;
}
Get this working.
Next step, add more content to the Process_Text_Line
method, such as recognition of labels, instructions and operands:
#include <vector>
void Process_Text_Line(const std::string& text_line)
{
std::vector<std::string> instructions =
{
"STL", "JSUB",
//...
};
// Extract the first "word".
std::istringstream instruction_stream(text_line);
std::string word;
instruction_stream >> word;
// If the word is not an instruction, consider it a label.
std::string label;
std::string opcode;
if (std::find(instructions.begin(), instructions.end(), word) != instructons.end())
{
label = word;
instruction_stream >> opcode;
}
else
{
opcode = word;
}
// Extract the operand
std::string operand;
instruction_stream >> operand;
// Now print them:
std::cout << "Label: " << label;
std::cout << ", opcode: " << opcode;
std::cout << ", operand: " << operand << "\n";
}
Once the label, opcode and operand are extracted, processing them is straight forward. There may be exceptions, where an opcode has more than one operand or zero operands.
One nice issue about using C++ streams and strings is that variable length records can be handled simply. For example, if an opcode has no operand, the extraction will generate an error, but processing continues. No worrying about whether or not to supply one, two or three format specifiers or arguments to scanf
.
Upvotes: 1