Semantic Analysis
Tiny+语义分析
目录
Tiny+语义分析... 1
一. 说明... 2
二. SYMTAB.C说明... 2
1. 对符号表的修改... 2
2. 添加了de_insert函数... 2
3. 修改了st-insert函数... 3
4. 添加了type_lookup函数... 3
5. 修改了符号表输出函数... 4
三. ANALYZE.C说明... 4
1. 把location变成整个程序全局的静态变量... 4
2. 改了插入节点insertNode的函数... 4
3. 对类型检查的修改... 4
四. 运行界面截图... 4
1. 正常运行界面... 4
2. 变量使用前未被声明... 5
3. 同一变量名被多次声明... 5
4. 检查变量类型错误... 6
一. 说明
Tiny+的语义分析部分主要在SYMTAB.C,SYMTAB.H,ANALYZE.C,ANALYZE.H中定义和实现。
二. SYMTAB.C说明
1. 对符号表的修改
符号表的项BucketList内多加了1个ExpType类型(Integer,Boolean或者String),用来储存id类型。
2. 添加了de_insert函数
函数头为de_insert( char * name, int loc , ExpType type),其作用是当id被声明时,将id的储存位置插入到符号表中。Loc为存储位置,type为id的类型(Integer,Boolean,String),id只有在第一次的时候才插入,否则就出错。实现代码如下:
void de_insert( char * name, int loc , ExpType type)
{ int h = hash(name);
BucketList l = hashTable[h];
while ((l != NULL) && (strcmp(name,l->name) != 0))
l = l->next;
if (l == NULL){ /* variable not yet in table */
l = (BucketList) malloc(sizeof(struct BucketListRec));
l->name = name;
l->lines = NULL;
l->memloc = loc;
l->next = hashTable[h];
l->type = type;
hashTable[h] = l;
}
else{
printf("Line %d: %s is declared more than once!\n", lineno, name);
Error = TRUE;
}
}/*de_insert*/
3. 修改了st-insert函数
改为st_insert( char * name, int lineno),其作用是当id被使用时,将id的出现行数插入符号表中。Lineno为行数,id只有在被声明后才能插入,即才能在表中被发现,否则就出错。实现代码如下:
void st_insert( char * name, int lineno)
{ int h = hash(name);
BucketList l = hashTable[h];
while ((l != NULL) && (strcmp(name,l->name) != 0))
l = l->next;
if (l == NULL) /* variable not yet in table */
{
printf("Line %d: %s is used before the declaration of it!\n",lineno, name);
Error = TRUE;
}
else /* found in table, so just add line number */
{ LineList t = l->lines;
while (t != NULL && t->next != NULL) t = t->next;
if(t == NULL){
l->lines = (LineList) malloc(sizeof(struct LineListRec));
l->lines->lineno = lineno;
l->lines->next= NULL;
}
else{
t->next = (LineList) malloc(sizeof(struct LineListRec));
t->next->lineno = lineno;
t->next->next = NULL;
}
}
} /* st_insert */
4. 添加了type_lookup函数
函数头为type_lookup ( char * name ),其作用是当一个变量没有被发现时返回这个变量的类型或返回为空。实现代码为:
ExpType type_lookup ( char * name )
{ int h = hash(name);
BucketList l = hashTable[h];
while ((l != NULL) && (strcmp(name,l->name) != 0))
l = l->next;
if (l == NULL) return Void;
else return l->type;
}
5. 修改了符号表输出函数
输出符号表的函数printSymtab里面多加了id类型的输出。
三. ANALYZE.C说明
1. 把location变成整个程序全局的静态变量
这是是为了后来生成代码时可以把string存到内存中。
2. 改了插入节点insertNode的函数
变量声明时调用de_insert插入id名称,并分配内存地址。
使用变量时调用st_insert插入id的出现行数。
3. 对类型检查的修改
在checkNode中修改了部分类型检查的代码,添加了Tiny+新加入的一些类型以及比较符等。
四. 运行界面截图
1. 正常运行界面
测试代码:
string str;
int x, fact;
str:= 'sample program' ;
read x;
if x>0 and x<100 then {don't compute if x<=0}
fact:=1;
while x>0 do
fact:=fact*x;
x:=x-1
end;
write fact
end
2. 变量使用前未被声明
测试代码:
int x, fact;
str:= 'sample program' ; //(str在使用前未被声明)
read x;
if x>0 and x<100 then {don't compute if x<=0}
fact:=1;
while x>0 do
fact:=fact*x;
x:=x-1
end;
write fact
end
3. 同一变量名被多次声明
测试代码:
string str;
int x, fact;
string x; //(x被重复声明,且不同类型)
int fact; //(fact被重复声明,且同类型)
str:= 'sample program' ;
read x;
if x>0 and x<100 then {don't compute if x<=0}
fact:=1;
while x>0 do
fact:=fact*x;
x:=x-1
end;
write fact
end
4. 检查变量类型错误
测试代码:
string str;
int x, fact;
str:= 'sample program' ;
x := 'error test' ; //(把一个string 赋值给x)
if x>0 and x<100 then {don't compute if x<=0}
fact:=1;
while x>0 do
fact:=fact*x;
x:=x-1
end;
write fact
end
代码和文档可以在下一篇文章中下载~~