TINY部分源码分析报告Word文件下载.docx
- 文档编号:17079111
- 上传时间:2022-11-28
- 格式:DOCX
- 页数:25
- 大小:23.28KB
TINY部分源码分析报告Word文件下载.docx
《TINY部分源码分析报告Word文件下载.docx》由会员分享,可在线阅读,更多相关《TINY部分源码分析报告Word文件下载.docx(25页珍藏版)》请在冰豆网上搜索。
structtreeNode*child[MAXCHILDREN];
structtreeNode*sibling;
intlineno;
NodeKindnodekind;
union{StmtKindstmt;
ExpKindexp;
}kind;
union{TokenTypeop;
intval;
char*name;
}attr;
ExpTypetype;
/*fortypecheckingofexps*/
}TreeNode;
3.UTIL.C/UTIL.H
主要函数
TreeNode*newStmtNode(StmtKindkind)
此函数创建一个有关语法树的声明节点
TreeNode*newExpNode(ExpKindkind)
此函数创建一个有关语法树的表述节点
char*copyString(char*s)
此函数分配和创建一个新的已存在树的复制
voidprintTree(TreeNode*tree)
输出一个语法树
这两个文件主要是关于语法树的创建和输出
4.SCAN.c/SCAN.H
主要有这么几个函数:
staticintgetNextChar(void);
staticvoidungetNextChar(void);
staticTokenTypereservedLookup(char*s);
TokenTypegetToken(void);
reservedLookup函数是查找关键字的,在符号表中找。
这里还定义了一个保存关键字的结构:
staticstruct
{char*str;
TokenTypetok;
}reservedWords[MAXRESERVED]
=
{{"
if"
IF},{"
then"
THEN},{"
else"
ELSE},{"
end"
END},
{"
repeat"
REPEAT},{"
until"
UNTIL},{"
read"
READ},
write"
WRITE}};
最重要的是getToken(void)函数。
这个相当于lex的功能,进行词法分析。
也就是一个DFA,switch后面跟了一堆的case。
其中getNextChar(void)函数的思路,以下列出:
staticintgetNextChar(void)
if(!
(linepos<
bufsize))
lineno++;
if(fgets(lineBuf,BUFLEN-1,source))
if(EchoSource)fprintf(listing,"
%4d:
%s"
lineno,lineBuf);
bufsize=strlen(lineBuf);
linepos=0;
returnlineBuf[linepos++];
}
else
EOF_flag=TRUE;
returnEOF;
elsereturnlineBuf[linepos++];
4.PARSE.C/PARSE.H
有这么几个函数:
TreeNode*parse(void)
staticTreeNode*stmt_sequence(void);
staticTreeNode*statement(void);
staticTreeNode*if_stmt(void);
staticTreeNode*repeat_stmt(void);
staticTreeNode*assign_stmt(void);
staticTreeNode*read_stmt(void);
staticTreeNode*write_stmt(void);
staticTreeNode*exp(void);
staticTreeNode*simple_exp(void);
staticTreeNode*term(void);
staticTreeNode*factor(void);
最重要的是parse这个函数,就是用来构造整个程序的语法树的。
下面的一堆私有函数构造相应语法的语法树,然后parse最后把它们这些子树整合成一个大树。
5.SYMTAB.C/SYMTAB.H
这个是符号表操作的,也就是词法分析的时候查找表,看该token是不是关键字。
如果不是,就当作表识符添加进去。
在语法分析的时候也要用到,看变量有没有声明的时候用的。
三、实验心得:
通过这次实验,仔细地去查看和分析了TINY编译器的部分源码。
了解到了编译器的运行:
根据语法树生成代码(调用codeGen函数),同时熟悉了编译器是如何使用prase函数进行语法树的构建以及语法树生成代码的转化,最主要的是进一步清晰了解到编译器的构造和运行原理,加深了对课本知识的运用和拓展,感觉收获很大!
Main.c
/****************************************************/
/*File:
main.c*/
/*MainprogramforTINYcompiler*/
/*CompilerConstruction:
PrinciplesandPractice*/
/*KennethC.Louden*/
#include"
globals.h"
/*setNO_PARSEtoTRUEtogetascanner-onlycompiler,NO_PARSE为true时创建一个只扫描的编译器*/
#defineNO_PARSEFALSE
/*setNO_ANALYZEtoTRUEtogetaparser-onlycompiler,NO_ANALYZE为true时创建一个只分析和扫描的编译器*/
#defineNO_ANALYZEFALSE
/*setNO_CODEtoTRUEtogetacompilerthatdoesnot
*generatecodeNO_CODE为true时创建一个执行语义分析,但不生成代码的编译器
*/
#defineNO_CODEFALSE
util.h"
#ifNO_PARSE
scan.h"
//如果NO_PARSE为true,调用头文件scan.h
#else
parse.h"
//否则调用头文件prase.h
#if!
NO_ANALYZE
analyze.h"
//如果NO_ANALYZE为true,调用头文件analyze.h
NO_CODE
cgen.h"
//如果NO_CODE为true,调用头文件cgen.h
#endif
#endif
#endif//结束预处理语句符号
/*allocateglobalvariables分配全局变量*/
intlineno=0;
FILE*source;
//指针指向源代码文件地址
FILE*listing;
//指针指向显示分析过程的文件的地址
FILE*code;
//指针指向目标汇编代码文件的地址
/*allocateandsettracingflags分配和设置跟踪标志*/
intEchoSource=FALSE;
intTraceScan=FALSE;
intTraceParse=FALSE;
intTraceAnalyze=FALSE;
intTraceCode=FALSE;
intError=FALSE;
//跟踪标志全部初始化为false
main(intargc,char*argv[])
{TreeNode*syntaxTree;
charpgm[120];
/*sourcecodefilename*/
if(argc!
=2)
{fprintf(stderr,"
usage:
%s<
filename>
\n"
argv[0]);
exit
(1);
//如果argv不为2,打印显示信息并退出
}
strcpy(pgm,argv[1]);
//复制argv[1]地址以null为退出字符的存储器区块到另一个存储器区块品pgm内
if(strchr(pgm,'
.'
)==NULL)
strcat(pgm,"
.tny"
);
//把.tyn文件所指字符串添加到pgm结尾处并添加'
\0'
。
source=fopen(pgm,"
r"
//以只读的方式打开pgm文件,并将指向pgm文件的指针返回给source
if(source==NULL)
File%snotfound\n"
pgm);
exit
(1);
//如果源代码文件为空,打印显示信息并退出
listing=stdout;
/*sendlistingtoscreen清单发送到屏幕*/
fprintf(listing,"
\nTINYCOMPILATION:
%s\n"
//答应显示语句
#ifNO_PARSE
while(getToken()!
=ENDFILE);
//如果输入流没有结束就继续进行循环,直至结束
syntaxTree=parse();
//调用prase()函数构造语法树
if(TraceParse){
\nSyntaxtree:
printTree(syntaxTree);
//如果语法分析追踪标志为TRUE且没有语法错误,则将生成的语法树输出到屏幕
if(!
Error)
{if(TraceAnalyze)fprintf(listing,"
\nBuildingSymbolTable...\n"
buildSymtab(syntaxTree);
//输出含符号表信息的语法树
if(TraceAnalyze)fprintf(listing,"
\nCheckingTypes...\n"
typeCheck(syntaxTree);
//输出含类型检查的语法树
\nTypeCheckingFinished\n"
//打印结束信息
{char*codefile;
intfnlen=strcspn(pgm,"
."
codefile=(char*)calloc(fnlen+4,sizeof(char));
strncpy(codefile,pgm,fnlen);
strcat(codefile,"
.tm"
//将源文件名,去掉扩展名,添加扩展名.tm
code=fopen(codefile,"
w"
//以只写的方式打开目标汇编代码文件,并返回地址给codez指针
if(code==NULL)
{printf("
Unabletoopen%s\n"
codefile);
//如果code指针为空,打印显示信息并退出
codeGen(syntaxTree,codefile);
//目标代码生成
fclose(code);
#endif//结束之前对应的条件编译
fclose(source);
//关闭源代码文件
return0;
GLOBALS.H
globals.h*/
/*GlobaltypesandvarsforTINYcompiler*/
/*mustcomebeforeotherincludefiles*/
#ifndef_GLOBALS_H_
#define_GLOBALS_H_//宏定义
#include<
stdio.h>
stdlib.h>
ctype.h>
string.h>
//头文件引用
#ifndefFALSE
#defineFALSE0//定义FALSE为0
#ifndefTRUE
#defineTRUE1//定义TRUE为1
/*MAXRESERVED=thenumberofreservedwords*/
#defineMAXRESERVED8//定义了关键字个数8个
typedefenum
/*book-keepingtokens*/
{ENDFILE,ERROR,
/*reservedwords*/
IF,THEN,ELSE,END,REPEAT,UNTIL,READ,WRITE,
/*multicharactertokens*/
ID,NUM,
/*specialsymbols*/
ASSIGN,EQ,LT,PLUS,MINUS,TIMES,OVER,LPAREN,RPAREN,SEMI
}TokenType;
//定义了关键字,运算符等内容的枚举值
externFILE*source;
/*sourcecodetextfile源代码地址*/
externFILE*listing;
/*listingoutputtextfile显示分析过程的文件的地址*/
externFILE*code;
/*codetextfileforTMsimulator目标汇编代码文件的地址*/
externintlineno;
/*sourcelinenumberforlisting*/
/**************************************************/
/***********Syntaxtreeforparsing************/
typedefenum{StmtK,ExpK}NodeKind;
//定义了语句类型的枚举值,这个决定树的节点
typedefenum{IfK,RepeatK,AssignK,ReadK,WriteK}StmtKind;
typedefenum{OpK,ConstK,IdK}ExpKind;
/*ExpTypeisusedfortypechecking*/
typedefenum{Void,Integer,Boolean}ExpType;
//定义了变量类型
#defineMAXCHILDREN3//定义了最大子节点
typedefstructtreeNode//定义了树的节点
{structtreeNode*child[MAXCHILDREN];
structtreeNode*sibling;
intlineno;
NodeKindnodekind;
union{StmtKindstmt;
union{TokenTypeop;
intval;
char*name;
ExpTypetype;
}TreeNode;
/***********Flagsfortracing************/
/*EchoSource=TRUEcausesthesourceprogramto
*beechoedtothelistingfilewithlinenumbers
*duringparsing
externintEchoSource;
/*TraceScan=TRUEcausestokeninformationtobe
*printedtothelistingfileaseachtokenis
*recognizedbythescanner
externintTraceScan;
/*TraceParse=TRUEcausesthesyntaxtreetobe
*printedtothelistingfileinlinearizedform
*(usingindentsforchildren)
externintTraceParse;
/*TraceAnalyze=TRUEcausessymboltableinserts
*andlookupstobereportedtothelistingfile
externintTraceAnalyze;
/*TraceCode=TRUEcausescommentstobewritten
*totheTMcodefileascodeisgenerated
externintTraceCode;
/*Error=TRUEpreventsfurtherpassesifanerroroccurs*/
externintError;
SCAN.C
/*词法扫描程序*/
/*定义的状态*/
typedefenum
{
START,/*初始状态*/
INASSIGN,/*进入到赋值状态*/
INCOMMENT,/*进入到注释状态*/
INNUM,/*进入到数字状态*/
INID,/*进入到标志符状态*/
DONE/*状态结束*/
}StateType;
/*每当语法分析程序需要一个单词时,就调用该子程序,得到(类别码,单词的值)*/
/*语义标识符和保留字*/
chartokenString[MAXTOKENLEN+1];
/*BUFLEN=源代码的输入缓冲长度*/
#defineBUFLEN256
staticcharlineBuf[BUFLEN];
/*当前行*/
staticintlinepos=0;
/*在linebuf中的当前位置*/
staticintbufsize=0;
/*缓冲区的字符串当前大小*/
staticintEOF_flag=FALSE;
/*如果读入下一个字符出错,设置EOF_flag为假。
*/
/*从linebuffer中读取下一个非空白字符,如果读完,则读入新行。
{if(!
{lineno++;
if(fgets(lineBuf,BUFLEN-1,source))
{if(EchoSource)fprintf(listing,"
bufsize=strlen(lineBuf);
linepos=0;
returnlineBuf[linepos++];
else
{EOF_flag=TRUE;
returnEOF;
elsereturnlineBuf[linepos++];
/*如果读入下一个字符出错,在linebuf中回退一个字符。
staticvoidungetNextChar(void)
EOF_flag)linepos--;
/*保留字的查找表*/
{char*str;
TokenTypetok;
}reservedWords[MAXRESERVED]
={{"
{"
rea
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- TINY 部分 源码 分析 报告