lex を使用してスキャナーを実装しています。解析中にシンボル テーブルを作成したい。SymbolEntry と SymbolTable (以下) の 2 つの構造体があります。ほとんどの場合、シンボルを挿入するために関数 (registerID、以下も参照) を呼び出すと、エントリのすべての情報が得られます。ただし、定数がある場合はその値も取得したいのですが、最初にエントリを作成したときにすぐには利用できません。コードの後半でエントリの値を変更しようとすると、そのエントリで使用されているメモリ ブロック全体が無効になり、名前と値がガベージとして出力されます。
以下に 2 つの構造体を示します。
typedef struct{
char* type;
char* name;
char* value;
} SymbolEntry;
typedef struct{
SymbolEntry *entries;
size_t size;
size_t capacity;
} SymbolTable;
{id}
これは、 anが一致したときに呼び出される 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);
その後、lex フレームワークが CONSTANT 名の直後の値と一致した後、このコードが実行されます ( のルールで直接<CONSTANT_VAL>{number}
) 。
table.entries[prevSym].value = (char *)calloc(yyleng+1, sizeof(char));
strcpy(table.entries[prevSym].value, yytext);
これにより、配列内のこの位置にある SymbolEntry が無効になるのはなぜですか? また、その内容を安全に変更するにはどうすればよいvalue
ですか?
編集:
定数だけで発生するわけではありません。最初の 2 つSymbolEntry
の s は常にガベージです。おそらくそれらはすべて上書きされていることを意味すると思いますが、他のものは上書きされていません。
また、後続の への呼び出しregisterID
が原因でデータが破損しているようです。シンボルが 9 つしかない場合、最初の 2 つだけがゴミで、34 の場合は最初の 7 つです。変数を使用せずに解析するテキストを追加しても、問題は発生しませんでした。
解決済み
さて、途中で誤って行を削除したことが判明し、それがバグを引き起こしました。への通話を誤って消去してしまいましたinitSymbolTable
。テーブルの初期化方法を尋ねてくれたchuxに感謝します。申し訳ありません。