下面我有一个FileParser程序,它逐行浏览汇编语言源代码文件,并将该行分为标记(标签,操作码,操作数,注释)。
它跟踪标签指针,直到它到达标签的末尾,标签指针值被传递到下一个令牌开始指针(opcode_start),该指针沿着操作码一直到达结束,然后通过指向operand_start的指针值,依此类推。把它想象成传递地址。
labelstart = x;
copies label value into string var; labelstart++
labelend = labelstart;
skips whitespace
opcodestart = labelend;
copies opcdoe value into str var , opcodestart++ ;
opcodeend = opcodestart
我一直在调试分段错误,这些错误主要发生在我将指针复制到字符串的位置,并将指针变量传递给下一个/
_label[i] = label_start[i];
_opcode[x] = opcode_ptr[x];
等...
我的上一次调试运行以第210行的分段错误结束
_operand[q] = operand_start[q];
我能做些什么来确保两个地址
void file_parser::read_file() {
ifstream wholefile;
string line;
int row_num = 1; // starting on first row
vector<string> rowlist; // data structure containing rows
int has_label = 0; //booleans
int has_opcode = 0;
int has_operand = 0;
int has_comment = 0;
char* label_start; //marks startpoint of token
char* label_end; // marks endpoint
char* opcode_start; // likewise\/\/\/
char* opcode_end;
char* operand_start;
char* operand_end;
char* comment_start;
// file_parser fileparse = new file_parser; //I don't think we actually need this.
struct row tokens[BUFFER]; // array of row objects, with label, opcode, operand, comment fields
row *tokens_ptr = &tokens[0]; // for when we want to delete
wholefile.open(filename.c_str()); // opens file
//open_file();
int c = 0; // keeps track of current char
int result;
while( (wholefile.rdstate() & std::ifstream::failbit) != 0 ) {
has_label, has_opcode, has_operand, has_comment = 0; // reset flags
// tokens[row_num] = new row(); // create new row object in tokens array
//////// deciding on wether to use vector<rowlist> or array of rows??????
getline(wholefile, line); // takes line out of file and saves to 'line'
if(line[c] == '*') {
while(line[c] == '*'){
getline(wholefile,line);
row_num++;
}
}
//////////////////IF LINE STARTS WITH LABEL/////////////////////
if(isalpha(line[c]) || isdigit(line[c])) // if first char on line is alpha or num
{
string _label; // its a label
int i;
for(i = 0; line[i] != ':'; i++) // label goes up until ' : '
{ if(i == 0)
{ label_start = &line[0]; // pointer to first char of label
}
// loop quits once label ends (reaches colon)
if(i == 8) // if 8 characters have been put in
{ _label[i] = '\0';
label_end = &label_start[i];
}
_label[i] = label_start[i]; // copy the string as a token
}
if( i < 8 )
_label[i] = '\0';
label_end = &label_start[i];
has_label = 1; // mark line as having label
tokens[row_num].label = _label;
tokens[row_num].has_label = 1;
}
///////////////OPCODE//////////////////////
////IF LINE STARTS WITH OPCODE/////
if(has_label == 0) // if first char on line isnt letter or number
{
tokens[row_num].has_label = 0;
tokens[row_num].label = "";
int i=0; // first token on this line is opcode
while(line[i] == ' '){
i++;
}
opcode_start = &line[i]; // ptr to first char of opcode token
string _opcode;
string opcode_ptr;
int x;
for(x = 0; opcode_ptr[x] != ' '; x++) // stops at whitespace, should clear leading blanks later
{
_opcode[x] = opcode_ptr[x]; // copy text into string
}
_opcode[++x] = '\0'; // null terminate opcode string
tokens[row_num].opcode = _opcode; // set row properties
tokens[row_num].has_opcode = 1;
has_opcode = 1; // local variable
}
//////////OPCODE CASE 2///////////////////
////IF LINE STARTS WITH LABEL////
else if(has_label == 1) // if line has label, pointer currently at end of label (on ':' char), get it to opcode//
{ label_end++; // move ptr to whitespace
string _opcode;
while(*label_end == ' ') {
label_end++;
}
////when loop exits, ptr has reached next column for processing////
if(isalnum(*label_end)) // **COULD POSSIBLY DELETE || or even use isalnum?
{
int i; // if its a number or char//
opcode_start = label_end; // we've reached the opcode area///
for(i = 0; opcode_start[i] != ' '; i++) {
_opcode[i] = opcode_start[i];
}
opcode_end = &opcode_start[i]; // opcode_end is on leading blank
_opcode[++i] = '\0'; // null terminate string value
tokens[row_num].opcode = _opcode;
tokens[row_num].has_opcode = 1;
has_opcode = 1;
}
////////////OPERANDS/////////////////
} // LINE = LABEL---OPCODE---OPERAND
if(has_label == 1 && has_opcode == 1) // begin saving operand
{
int i = 0;
string _operand;
while(opcode_end[i] == ' ') {
i++;
} // reached operands after loop
if( isalpha(opcode_end[i]) || isdigit(opcode_end[i]) )
{
operand_start = &opcode_end[i]; // save location
} ////now that we've reached operand, decide if quoted or not
//////// if QUOTED OPERAND/////////
if((*operand_start = '\'')) // if it is
{
int x = 0;
operand_start++; // move the ptr to the first char
while(operand_start[x] != '\'') {
_operand[x] = operand_start[x]; // and keep copying // them until ' is reached'
x++;
}
// until the next quote is reached
_operand[++x] = '\0';
operand_end = &operand_start[x]; // operand_end on space
// after ' char
tokens[row_num].operand = _operand;
tokens[row_num].has_operand = 1;
has_operand = 1;
} else
{ int x = 0;
while(operand_start[x] != ' ') {
_operand[x] = operand_start[x];
x++;
}
_operand[x] = '\0';
operand_end = &operand_start[x]; // operand_end on space // after operand
tokens[row_num].operand = _operand;
tokens[row_num].has_operand = 1;
has_operand = 1;
}
////////////if an operand after a first opcode//////////
/// LINE = xxxxx OPCODE OPERAND
} else if(has_label == 0 && has_opcode == 1) {
int q = 0;
string _operand;
while(operand_start[q] != ' ' || operand_start[q] != ';' || operand_start[q] != '*') {
_operand[q] = operand_start[q]; // keeps copying until it reaches space or beginning of comment
q++;
}
if(operand_start[q] == ';' || operand_start[q] == '*') {
comment_start = operand_start; // mark location of comment beginning
}
else{
_operand[q] = '\0';
operand_end = &operand_start[q];
tokens[row_num].operand = _operand;
tokens[row_num].has_operand = 1;
has_operand = 1;
}
} /////////OPERAN
/////////////////check for comments///////////////
if(has_label == 1 && has_opcode == 1 && has_operand == 1) {
int x = 0;
string _comment;
while(operand_end[x] != '\n' || operand_end[x] != ';' || operand_end[x] != '*') {
x++; // keep going until you reach a comment beginning or the next line
}
if(operand_end[x] == ';' || operand_end[x] == '*') { //if theres a comment
comment_start = &operand_end[x]; // mark its start point
while(comment_start[x] != '\n') { // and copy it in, until the line ends
_comment[x] = comment_start[x];
x++;
}
_comment[x] = '\0'; //null term once youve copied it completly
tokens[row_num].comment = _comment; // set the object data value
tokens[row_num].has_comment = 1; // and the objects boolean
has_comment = 1; // and the local variable
} else { // otherwise there is no comment, youve reached the end of the line
if(*operand_end == '\n') {
_comment = ""; // no comment value
tokens[row_num].comment = _comment; //set object vals accordingly
tokens[row_num].has_comment = 0;
has_comment = 0;
break;
}
} //if the line started with no opcode, follow the same algorithm as above...
} else if(has_label == 0 && has_opcode == 1 && has_operand == 1) {
int x = 0;
string _comment;
while(operand_end[x] != '\n' || operand_end[x] != ';' || operand_end[x] != '*') {
x++;
}
if(operand_end[x] == ';' || operand_end[x] == '*') {
comment_start = &operand_end[x];
while(comment_start[x] != '\n') {
_comment[x] = comment_start[x];
x++;
}
_comment[x] = '\0';
tokens[row_num].comment = _comment;
tokens[row_num].has_comment = 1;
has_comment = 1;
} else {
if(*operand_end == '\n') {
_comment = "";
tokens[row_num].comment = _comment;
tokens[row_num].has_comment = 0;
has_comment = 0;
break;
}
}
}
// c++; probably dont need to increment this every line...
row_num++; // but definitley increment this
rowlist.push_back(line); // and pushes 'line' to back of vector
}
// int i;
// for ( i = 0; i < tokens.size(); ++i)
// { delete tokens_ptr[i]; //Once EOF has been reached, go through //every
// } // element of array and delete them
delete[] tokens; // before finally deleting the array as a whole
//deallocation of memory helps ensure no memory management issues at runtime
};