我正在使用 lex 来实现扫描仪。我想在解析时建立一个符号表。我有两个结构,SymbolEntry 和 SymbolTable(如下)。大多数时候,当我调用用于插入符号的函数(registerID,也在下方)时,我拥有该条目的所有信息。但是,当我有一个常量时,我也想获得它的值,但是当我第一次创建条目时,它不会立即可用。当我稍后尝试在代码中更改条目值时,我正在使该条目使用的整个内存块无效,并且名称和值正在打印垃圾。
这是两个结构:
typedef struct{
char* type;
char* name;
char* value;
} SymbolEntry;
typedef struct{
SymbolEntry *entries;
size_t size;
size_t capacity;
} SymbolTable;
这是 registerID 函数,在{id}
匹配 an 时调用。yytext
包含标识。
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 框架匹配紧跟在 CONSTANTs 名称后面的值后,执行此代码(直接在规则中<CONSTANT_VAL>{number}
)
table.entries[prevSym].value = (char *)calloc(yyleng+1, sizeof(char));
strcpy(table.entries[prevSym].value, yytext);
为什么这会使数组中此位置的 SymbolEntry 无效,我怎样才能安全地更改 的内容value
?
编辑:
它不仅发生在常量上。前两个SymbolEntry
总是垃圾。我假设这可能意味着它们都是,但其他的只是没有被覆盖。
此外,后续调用似乎registerID
导致数据损坏。只有 9 个符号,只有前两个是垃圾,有 34 个是前 7 个。添加更多文本以解析没有变量不会导致任何问题。
解决
了原来我只是不小心删除了沿途某处的一行,这就是引入错误的原因。我不小心删除了对initSymbolTable
. 感谢 chux 询问我是如何初始化表格的。对于那个很抱歉。