Я написал код для сканера на C++, но продолжаю получать ошибку сегментации. Странная вещь заключается в том, что ошибка сегментации происходит при завершении кода. Я думаю, что это связано с моей функцией сканирования и использованием в ней file.get()
, но не может ли это вызвать ошибку сегментации в этой строке кода? У меня есть простой main.cpp, который вызывает функцию at в инструкции cout, а ошибка сегментации происходит после оператора return. Когда я запускал GDB и backtrace, я получил:Причина сбоя сегментации?
Запрограммированный сигнал SIGSEGV, ошибка сегментации.
0x00011260 в __do_global_dtors_aux()
(GDB)
(GDB) трассировку
# 0 0x00011260 в __do_global_dtors_aux()
# 1 0x00012504 в _fini()
# 2 0xfefc3120 в _exithandle() из/Библиотека/Libc .so.1
# 3 0xfefb10e0 в выходе() из /lib/libc.so.1
# 4 0x00011218 в _start()
Вот простой main.cpp:
int main(int argc, char *argv[]) {
tokenType * token, * testtk;
string filename;
if(argc == 2){
filename = argv[1];
filename.append(".lan");
}
scan(filename);
cout << endl;
cout << "WHAT?!" << endl;
return 0;
}
И вот только часть функции сканера:
void scan(string filename){
char current;
char look;
int currentline = 1;
Type test;
tokenType * testtk;
std::ifstream file(filename.c_str()); // open file
/***scanner creation***/
while (file.good()) // loop while extraction from file file possible
{
int state = 0;
int lookstate = 0;
int type = 0;
int i = 0;
int nextstate;
look = file.peek();
/*** check for comments ***/
if(assignType(look)==5){
current = file.get(); //"current = look" at this point
current = file.get(); //current moves to next character
while(current != 24) {
current = file.get();
}
}
initializeToken(testtk);
while(state >= 0) {
current = file.get(); // get character from file
look = file.peek();
lookstate = state;
if(assignType(current)!=24){ //keeps newlines from printing
testtk->str[i] = current; //put current scanned char into string
}
testtk->tokenId = (tokenIdType) state;
nextstate = table[state][assignType(current)];
state = nextstate;
if(assignType(current)==24) { //keeps track of '\n'
currentline++;
}
if(i<STRSIZ) i++;
}
testtk->line=currentline;
printToken(testtk);
}
file.close();
}
Любая помощь относительно того, что является причиной этой ошибки сегментации будет оценен,
отредактировал
Здесь наиболее моего токена.h:
typedef enum
{ EOFtk, IDtk, NOTtk, DOTtk, NUMtk, COMMENTtk, ASSIGNtk, EQUALtk, LESSEQtk,
GREATEQtk, PLUStk, MINUStk, MULTtk, DIVtk, MODtk, PARENLtk,
PARENRtk, COMMAtk, CURLYLtk, CURLYRtk, SEMItk, BRACKLtk, BRACKRtk, COLONtk,
LESStk, GREATtk, STARTtk, STOPtk, THENtk, IFtk, IFFtk, WHILEtk, VARtk, INTtk,
FLOATtk, DOtk, READtk, WRITEtk, VOIDtk, RETURNtk, DUMMYtk, PROGRAMtk
} tokenIdType;
typedef enum
{ WS, LETTER, NUMBER, AMBER, NOT, PLUS, MINUS, MULT, DIV,
MOD, EQUAL, LESS, GREATER, UNDERSC, DOT, PARENL,
PARENR, COMMA, CURLYL, CURLYR, SEMI, BRACKL, BRACKR, COLON,
NEWLINE, NONALPHA, EOF
} Type;
typedef struct
{ char str[STRSIZ];
tokenIdType tokenId;
int line;
} tokenType;
и вот некоторые из других функций в моем scanner.cpp:
Type assignType(unsigned char current) {
Type temp;
if((current <= 122 && current >=97) || (current <= 90 && current >=65)){
temp = LETTER;
return temp;
}
if(current <= 57 && current >=48) {
temp = NUMBER;
return temp;
}
if(current == 10) {
temp = NEWLINE;
return temp;
}
switch (current) {
case ' ':
temp = WS;
break;
case '&':
temp = AMBER;
break;
case '!':
temp = NOT;
break;
case '+':
temp = PLUS;
break;
case '-':
temp = MINUS;
break;
case '*':
temp = MULT;
break;
case '/':
temp = DIV;
break;
case '%':
temp = MOD;
break;
case '=':
temp = EQUAL;
break;
case '<':
temp = LESS;
break;
case '>':
temp = GREATER;
break;
case '_':
temp = UNDERSC;
break;
case '.':
temp = DOT;
break;
case '(':
temp = PARENL;
break;
case ')':
temp = PARENR;
break;
case ',':
temp = COMMA;
break;
case '{':
temp = CURLYL;
break;
case '}':
temp = CURLYR;
break;
case ';':
temp = SEMI;
break;
case '[':
temp = BRACKL;
break;
case ']':
temp = BRACKR;
break;
case ':':
temp = COLON;
break;
default :
temp = NONALPHA;
break;
}
return temp;
}
void initializeToken(tokenType *token){
for(int i=0;i<STRSIZ;i++){ //initialize tokenType str
token->str[i]=0;
}
}
void printToken(tokenType *token){
if(token->tokenId != COMMENTtk && token->tokenId != EOFtk) { //ignore comments
cout<<"Line:";
cout.width(3);
cout<<token->line;
cout.flush();
cout<<" TokenID:";
cout.width(3);
cout<<token->tokenId;
cout.flush();
cout<<" String: ";
printf("%s\n", token->str);
}
}
bool isToken(int state, int look){
if(table[state][assignType(look)] >=0)
return false;
else return true;
}
bool compareStr(char x[], char y[]){
int score;
for(int i=0;i<STRSIZ;i++) {
if(x[i] != y[i])
score++;
}
if(score == 0)
return true;
else
return false;
}
К сожалению, в исходном коде использовалось file.close(); до конца функции. Я отредактировал свой вопрос, чтобы отразить это (а также добавить окончательный вариант)). – Evytyn
Вы можете показать объявление и реализацию класса tokenType? Просто конструкторы и деструкторы сделают –
Я добавил другие функции из своего сканера и код из моего token.h. Еще раз спасибо за любую помощь, которую вы можете предоставить. – Evytyn