TINY部分源码分析报告.docx
- 文档编号:1392047
- 上传时间:2022-10-22
- 格式:DOCX
- 页数:25
- 大小:24.54KB
TINY部分源码分析报告.docx
《TINY部分源码分析报告.docx》由会员分享,可在线阅读,更多相关《TINY部分源码分析报告.docx(25页珍藏版)》请在冰豆网上搜索。
TINY部分源码分析报告
TINY 源码分析
一、文件概述
MAIN.C:
主函数
GLOBALS.H:
全局定义的文件
SCAN.C/SCAN.H:
词法分析
PARSE.C/PARSE.H:
语法分析
UTIL.C/UTIL.H:
构造树
SYMTAB.C/SYMTAB.H:
符号表
CGEN.C/CGEN.H:
生成"汇编代码"
CODE.C/CODE.H:
这个只是用来把分析过程输出到屏幕的.
二、各个文件的分析
1.MAIN.C:
主要有三个 FILE*句柄:
source--源代码文件。
listing--显示分析过程的文件,这里重定向到 stdout。
code--目标汇编代码文件。
从该文件中可知程序运行的流程:
检查参数正确否(tiny.exe filename)->构造语法树(调用 parse 函数)->根据语法树生成代码
(调用 codeGen 函数,该函数又调用 cGen 函数。
2.GLOBALS.H:
定义了关键字个数 8 个。
定义了关键字,运算符等内容的枚举值。
定义了语句类型的枚举值,这个决定树的结点。
定义了变量类型(也就三种,void, integer, boolean)。
定义了树的节点--这个最重要了!
!
其结构如下所示:
typedef struct treeNode
{
struct treeNode * child[MAXCHILDREN];
struct treeNode * sibling;
int lineno;
NodeKind nodekind;
union { StmtKind stmt; ExpKind exp;} kind;
union { TokenType op;
int val;
char * name; } attr;
ExpType type; /* for type checking of exps */
} TreeNode;
3.UTIL.C/UTIL.H
主要函数
TreeNode * newStmtNode(StmtKind kind)
此函数创建一个有关语法树的声明节点
TreeNode * newExpNode(ExpKind kind)
此函数创建一个有关语法树的表述节点
char * copyString(char * s)
此函数分配和创建一个新的已存在树的复制
void printTree( TreeNode * tree )
输出一个语法树
这两个文件主要是关于语法树的创建和输出
4.SCAN.c/SCAN.H
主要有这么几个函数:
static int getNextChar(void);
static void ungetNextChar(void);
static TokenType reservedLookup (char * s);
TokenType getToken(void);
reservedLookup 函数是查找关键字的,在符号表中找。
这里还定义了一个保存关键字的结
构:
static struct
{ char* str;
TokenType tok;
} 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)函数的思路,以下列出:
static int getNextChar(void)
{
if (!
(linepos < bufsize))
{
lineno++;
if (fgets(lineBuf,BUFLEN-1,source))
{
if (EchoSource) fprintf(listing,"%4d:
%s",lineno,lineBuf);
bufsize = strlen(lineBuf);
linepos = 0;
return lineBuf[linepos++];
}
else
{
EOF_flag = TRUE;
return EOF;
}
}
else return lineBuf[linepos++];
}
4.PARSE.C/PARSE.H
有这么几个函数:
TreeNode * parse(void)
static TreeNode * stmt_sequence(void);
static TreeNode * statement(void);
static TreeNode * if_stmt(void);
static TreeNode * repeat_stmt(void);
static TreeNode * assign_stmt(void);
static TreeNode * read_stmt(void);
static TreeNode * write_stmt(void);
static TreeNode * exp(void);
static TreeNode * simple_exp(void);
static TreeNode * term(void);
static TreeNode * factor(void);
最重要的是 parse 这个函数,就是用来构造整个程序的语法树的。
下面的一堆私有函数构
造相应语法的语法树,然后 parse 最后把它们这些子树整合成一个大树。
5.SYMTAB.C/SYMTAB.H
这个是符号表操作的,也就是词法分析的时候查找表,看该 token 是不是关键字。
如果不
是,就当作表识符添加进去。
在语法分析的时候也要用到,看变量有没有声明的时候用的。
三、实验心得:
通过这次实验,仔细地去查看和分析了 TINY 编译器的部分源码。
了解到了编译器的
运行:
检查参数正确否(tiny.exe filename)->构造语法树(调用 parse 函数)->根据语法树生
成代码(调用 codeGen 函数),同时熟悉了编译器是如何使用 prase 函数进行语法树的构建
以及语法树生成代码的转化,最主要的是进一步清晰了解到编译器的构造和运行原理,加
深了对课本知识的运用和拓展,感觉收获很大!
Main.c
/****************************************************/
/* File:
main.c*/
/* Main program for TINY compiler*/
/* Compiler Construction:
Principles and Practice*/
/* Kenneth C. Louden*/
/****************************************************/
#include "globals.h"
/* set NO_PARSE to TRUE to get a scanner-only compiler ,NO_PARSE 为 true 时创建一个
只扫描的编译器 */
#define NO_PARSE FALSE
/* set NO_ANALYZE to TRUE to get a parser-only compiler ,NO_ANALYZE 为 true 时创建
一个只分析和扫描的编译器*/
#define NO_ANALYZE FALSE
/* set NO_CODE to TRUE to get a compiler that does not
* generate code NO_CODE 为 true 时创建一个执行语义分析,但不生成代码的编译器
*/
#define NO_CODE FALSE
#include "util.h"
#if NO_PARSE
#include "scan.h" //如果 NO_PARSE 为 true,调用头文件 scan.h
#else
#include "parse.h" //否则调用头文件 prase.h
#if !
NO_ANALYZE
#include "analyze.h" //如果 NO_ANALYZE 为 true,调用头文件 analyze.h
#if !
NO_CODE
#include "cgen.h"//如果 NO_CODE 为 true,调用头文件 cgen.h
#endif
#endif
#endif//结束预处理语句符号
/* allocate global variables 分配全局变量*/
int lineno = 0;
FILE * source;//指针指向源代码文件地址
FILE * listing; //指针指向显示分析过程的文件的地址
FILE * code;//指针指向目标汇编代码文件的地址
/* allocate and set tracing flags 分配和设置跟踪标志*/
int EchoSource = FALSE;
int TraceScan = FALSE;
int TraceParse = FALSE;
int TraceAnalyze = FALSE;
int TraceCode = FALSE;
int Error = FALSE;//跟踪标志全部初始化为 false
main( int argc, char * argv[] )
{ TreeNode * syntaxTree;
char pgm[120]; /* source code file name */
if (argc !
= 2)
{ fprintf(stderr,"usage:
%s
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)
{ fprintf(stderr,"File %s not found\n",pgm);
exit
(1);//如果源代码文件为空,打印显示信息并退出
}
listing = stdout; /* send listing to screen 清单发送到屏幕*/
fprintf(listing,"\nTINY COMPILATION:
%s\n",pgm); //答应显示语句
#if NO_PARSE
while (getToken()!
=ENDFILE); //如果输入流没有结束就继续进行循环,直至结束
#else
syntaxTree = parse();//调用 prase()函数构造语法树
if (TraceParse) {
fprintf(listing,"\nSyntax tree:
\n");
printTree(synt
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- TINY 部分 源码 分析 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)