Я пытаюсь прочитать строки из SIC / XE-программы, используя написанную мною программу на C (она должна действовать как pass один из ассемблера SICASM). Однако программа «зависнет» (не завершит выполнение), если последняя строка кода SIC / XE не имеет операнда после мнемоники. Хотелось бы просто избавиться от зависания, оттуда последует сборка.
Вот часть моей программы, которая получает ввод:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#define SIZE 51
#define LABEL_SIZE 9
#define MNEUMONIC_SIZE 8
#define OPERAND_SIZE 10
void getData(FILE* fpIn);
int hashFunc(char label[]);
unsigned long hex2int(char *a, unsigned int len);
bool checkMneumonic(char* mneumonic, int* bytes);
int main(int argc, char* argv[])
{
FILE* fpIn = fopen(argv[1], "r");
if(fpIn != NULL)
printf("\nFile open.");
else
{
printf("\nError: Main needs an input file.\n");
exit(EXIT_FAILURE);
}
getData(fpIn);
fclose(fpIn);
printf("\nFileClosed");
printf("\n\n");
return 0;
}
void getData(FILE* fpIn)
{
//debug printf("\nIn \"getData\" ");
char label[LABEL_SIZE];
char mneumonic[MNEUMONIC_SIZE];
char operand[OPERAND_SIZE];
int startAddr, currentAddr, PC = 0;
bool gotValidMneu = true;
int bytes;
//open file for writing
FILE* fpOut = fopen("output", "w");
if(fpOut != NULL)
printf("\n Ready to write.");
fprintf(fpOut,"\n\tHash\tLabel\tAddress");
char string1[10];
char string2[10];
int size;
while( fscanf(fpIn, "%s", string1) != EOF)
{
gotValidMneu = true;
if(strcmp(string1, "LTORG") == 0)
strcpy(string2, " ");
else if(strcmp(string1, "RSUB") == 0)
strcpy(string2, " ");
else if(!feof(fpIn) && fgetc(fpIn) != '\n')
fscanf(fpIn,"%s", string2);
if(checkMneumonic(string1, &size) && !feof(fpIn))
{
strcpy(mneumonic, string1);
strcpy(operand, string2);
strcpy(label, " ");
}
else if(checkMneumonic(string2, &size) && !feof(fpIn))
{
strcpy(label, string1);
strcpy(mneumonic, string2);
fscanf(fpIn, "%s[\n]", operand);
}
else if( string1[0] == '.')
{
char junk[80];
fgets(junk, 80, fpIn);
gotValidMneu = false;
}
else
{
printf("\nError: got invalid mneumonic");
gotValidMneu = false;
}
if(gotValidMneu)
{
//adjust the current address
currentAddr = PC;
//get the starting address
if(strcmp(mneumonic, "START") == 0)
{
startAddr = hex2int(operand, strlen(operand) );
PC = startAddr;
}
//mneumonic is "BASE"
else if(strcmp(mneumonic, "BASE") == 0);
//mneumonic is "RESW"
else if(strcmp(mneumonic, "RESW") == 0)
{
PC += (3 * atoi(operand) );
}
//mneumonic is "BYTE"
else if(strcmp(mneumonic, "BYTE") == 0 )
{
PC += atoi(operand);
}
//mneumonic is "END"
else if(strcmp(mneumonic, "END") == 0);
//check if the mneumonic is valid
else if(checkMneumonic(mneumonic, &bytes) )
{
PC += bytes;
}
//got a bad mneumonic
else
{
gotValidMneu = false;
printf("\nError: \"%s\" is not a valid mneumonic.", mneumonic);
fprintf(fpOut,"\nError: \"%s\" is not a valid mneumonic.",
mneumonic);
}
if(gotValidMneu)
{
if(strcmp(label, " ") != 0 )
fprintf(fpOut,"\n\t%d\t%s\t%x", hashFunc(label), label,
currentAddr);
printf("\n%x\t%s\t%s\t%s", currentAddr, label, mneumonic, operand);
}
}
if(gotValidMneu)
//flush the comments, if any
while( '\n' != getc(fpIn) )
getc(fpIn);
} //end while
fprintf(fpOut,"\n");
fclose(fpOut);
printf("\n Symbol table sent to file: \"output\".");
}
int hashFunc(char label[])
{
int i, sum, hashVal;
sum = 0;
for(i = 0; i < strlen(label); i++)
sum += label[i];
hashVal = sum % SIZE;
// printf("\nHashed Index: %d", hashVal);
return hashVal;
}
unsigned long hex2int(char *a, unsigned int len)
{
int i;
unsigned long val = 0;
for(i=0;i<len;i++)
if(a[i] <= 57)
val += (a[i]-48)*(1<<(4*(len-1-i)));
else
val += (a[i]-55)*(1<<(4*(len-1-i)));
return val;
}
bool checkMneumonic(char mneumonic[], int* bytes)
{
bool valid = false;
char validMneumonic[MNEUMONIC_SIZE];
FILE* fpIn = fopen("sicOps", "r");
while( (fscanf(fpIn, "%s %d", validMneumonic, bytes) != EOF) )
{
if(strcmp(mneumonic, validMneumonic) == 0 )
{
valid = true;
break;
}
}
fclose(fpIn);
return valid;
}
А вот файл, который я использую для его проверки:
ADDRES START 100
. tests pc forward addressing
. tests base addressing
. tests pc backward addressing
NOW +LDB #BEGIN load base register
XXX BASE BEGIN tell assembler
YYY LDA BE A <- (m..m+2)
EN RESW 4
BE WORD 2
BEGIN RESW 1
JUNK RESW 2200
THERE RESW 1
ZZZ LDA JUNK
MMM STA THERE
END
РЕДАКТИРОВАТЬ: есть много нового кода. Я урезал оригинальную программу, скомпилировал и протестировал ее, и она зависает.