저는 lex를 사용하여 스캐너를 구현하고 있습니다. 나는 파싱하는 동안 심볼 테이블을 만들고 싶다. 두 개의 구조체, SymbolEntry 및 SymbolTable (아래) 있습니다. 대부분의 경우, 심볼을 삽입하는 함수 (registerID, 아래 참조)를 호출 할 때 항목에 대한 모든 정보가 있습니다. 그러나 상수가있을 때도 값을 얻고 싶지만 처음 엔 항목을 만들 때 바로 사용할 수 없습니다. 나중에 코드에서 항목 값을 변경하려고하면 해당 항목에서 사용하는 전체 메모리 블록이 무효화되고 이름과 값이 가비지를 인쇄합니다. 여기 구조체 문자열 변경
두 구조체이다 :typedef struct{
char* type;
char* name;
char* value;
} SymbolEntry;
typedef struct{
SymbolEntry *entries;
size_t size;
size_t capacity;
} SymbolTable;
이것이 {id}
가 일치 할 때 호출 registerID 함수이다. yytext
에는 ID가 들어 있습니다.
int registerID(char* type){
//create a new symbol entry with the specified type and name and a default value
SymbolEntry e;
e.type = type;
e.name = (char *)calloc(yyleng+1, sizeof(char));
strcpy(e.name, yytext);
e.value = "";
prevSym = insertSymbol(&table, e);
return prevSym;
}
이것은 insertSymbol(SymbolTable* st, SymbolEntry entry)
에 대한 관련 코드입니다. pos
은 항상 삽입 할 때 배열의 마지막 요소입니다 (그렇지 않으면 항목이 고유하지 않고 pos
이 반환됩니다). 렉스 프레임 워크는 즉시 상수 이름을 다음과 같은 값을 일치 한 후
st->entries[pos].name = (char *)calloc(strlen(entry.name)+1, sizeof(char));
st->entries[pos].type = (char *)calloc(strlen(entry.type)+1, sizeof(char));
st->entries[pos].value = (char *)calloc(strlen(entry.value)+1, sizeof(char));
strcpy(st->entries[pos].name, entry.name);
strcpy(st->entries[pos].type, entry.type);
strcpy(st->entries[pos].value, entry.value);
나중에이 코드는
table.entries[prevSym].value = (char *)calloc(yyleng+1, sizeof(char));
strcpy(table.entries[prevSym].value, yytext);
왜이에하여 SymbolEntry을 무효화 않습니다 (직접 <CONSTANT_VAL>{number}
에 대한 규칙에서) 수행 배열의이 위치와 어떻게 안전하게 value
의 내용을 바꿀 수 있습니까?
편집 : 이것은 정수에서만 발생하는 것이 아닙니다. 처음 두 SymbolEntry
은 항상 쓰레기입니다. 나는 아마 그들 모두가 그렇다는 것을 의미한다고 가정하고 있지만 다른 것들은 단지 덮어 쓰지 않았다.
또한 이후에 registerID
을 호출하면 데이터가 손상 될 수 있습니다. 단 9 개의 기호로 처음 두 개는 쓰레기이고 34 개는 처음입니다. 변수없이 구문 분석 할 텍스트를 더 추가해도 아무런 문제가 없습니다.
SOLVED 글쎄, 우연히 길을 따라 어딘가에 선을 실수로 삭제했다는 것이 밝혀졌습니다. 실수로 전화가 initSymbolTable
으로 지워졌습니다. chux가 테이블을 초기화하는 방법을 묻는 것에 감사드립니다. 미안합니다.
을 고려 당신은 어떻게 ST-> 항목 [POS]를 할당하는거야? 한 가지 가능성은 할당 된 메모리를 초과하여 쓰는 것입니다. – KayakDave
크기는 16으로 시작하지만'size == capacity' 인 경우에는 크기를 두 배로 재 할당합니다. 이 점검은 모든 삽입 작업 후에 수행됩니다. – Jaws212
또한 SymbolEntry 배열을 1024에 할당하려고했지만 여전히 유효하지 않습니다. – Jaws212