语义分析实验报告.doc
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验三语法分析
20080810309 科3 李君林
一.实验目的:
通过使用、剖析和扩充TINY语言的语义分析程序,掌握编译器的语义分析程序的构造方法。
二.实验内容
(一)运行TINY的语义分析程序
(二)扩充TINY的语法分析程序
提示:
考虑作用域(如:函数)和数组时可能需要修改符号表。
三.实验步骤
1.先读懂TINY语义程序(相关联的文件:MAIN.C ANALYZE.C ANALYZE.H)
(1)buildSymtab(syntaxTree); //根据语法树建立符号表
通过递归调用traverse(syntaxTree,insertNode,nullProc);
进行static void insertNode( TreeNode * t),这样将遇到与ID有关的Node信息通过void st_insert( char * name, int lineno, int loc,int len )加入到hashTable[h]数据结构中。
(2)接着调用typeCheck(syntaxTree);进行类型检测
通过递归调用traverse(syntaxTree,nullProc,checkNode);将语法树遍历,然后调用static void checkNode(TreeNode * t)对节点进行类型检测
2.扩充TINY的语法分析程序
本次实验我首先将源程序实现的功能改成符合C_MINUS的符号表与类型检测然后加入没申明调用与数组调用错误即数组没申明而调用数组类型。
四.实验结果
1.正确的测试程序
/**/
int gcd (int u,int v[])
{
if(v==0)
return u;
else
return gcd(v,u);
}
void main(void)
{
int x;int y;
read x;
x=y=2;
while(x>0)
y=y-1;
write y;
return (gcd(x,y));
}
/**/
运行结果:
经检验测试程序代码无语义错误2.错误测试程序
/**/
int gcd (int u,int v[])
{
if(v==0)
return u;
else
return gcd(v,u);
}
void main(void)
{
int x;int y;
read x;
t=1;
x=y=2;
x[2]=2;
while(x>0)
y=y-1;
write y;
return (gcd(x,y));
}
/**/
实验结果:
检测到13行t没有申明
检测到15行x不是一个数组
五.实验心得
通过本次实验学会了使用、剖析和扩充TINY语言的语义分析程序,掌握编译器的语义分析程序的构造方法。加深了对书本语义分析的理解,感受到学以致用的快感,增强对本课程的兴趣。实验中遇到的最大问题:如何查询符号表判断数组,后面在其数据结构中增加了一个属性Len,如果不是数组将其赋为-1.
六.关键程序代码(ANALYZE.C)
/****************************************************/
/* File: analyze.c */
/* Semantic analyzer implementation */
/* for the TINY compiler */
/* Compiler Construction: Principles and Practice */
/* Kenneth C. Louden */
/****************************************************/
#include "globals.h"
#include "symtab.h"
#include "analyze.h"
/* counter for variable memory locations */
static int location = 0;
/* Procedure traverse is a generic recursive
* syntax tree traversal routine:
* it applies preProc in preorder and postProc
* in postorder to tree pointed to by t
*/
static void traverse( TreeNode * t,
void (* preProc) (TreeNode *),
void (* postProc) (TreeNode *) )
{ if (t != NULL)
{ preProc(t);
{ int i;
for (i=0; i < MAXCHILDREN; i++)
traverse(t->child[i],preProc,postProc);
}
postProc(t);
traverse(t->sibling,preProc,postProc);
}
}
/* nullProc is a do-nothing procedure to
* generate preorder-only or postorder-only
* traversals from traverse
*/
static void nullProc(TreeNode * t)
{ if (t==NULL) return;
else return;
}
static void typeError(TreeNode * t, char * message)
{ fprintf(listing,"Type error at line %d: %s\n",t->lineno,message);
Error = TRUE;
}
static void unDecError(TreeNode * t)
{ fprintf(listing,"Type error at line %d: the %s doesn't declaration\n",t->lineno,t->); Error = TRUE;
}
static void notArrayError(TreeNode * t)
{ fprintf(listing,"Type error at line %d: the ID %s isn't a Array\n",t->lineno,t->); Error = TRUE;
}
/* Procedure insertNode inserts
* identifiers stored in t into
* the symbol table
*/
static void insertNode( TreeNode * t)
{ switch (t->nodekind)
{ case StmtK:
switch (t->kind.stmt)
{
default:
break;
}
break;
case ExpK:
switch (t->kind.exp)
{ case IdK:
if (st_lookup(t->) == -1)