首页 TINY部分源码分析报告书

TINY部分源码分析报告书

举报
开通vip

TINY部分源码分析报告书word格式文档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部分源码分析报告书
word格式文档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.exefilename)->构造语法树(调用parse函数)->根据语法树生成代码(调用codeGen函数,该函数又调用cGen函数。2.GLOBALS.H:定义了关键字个数8个。定义了关键字,运算符等内容的枚举值。定义了语句类型的枚举值,这个决定树的结点。专业整理word格式文档定义了变量类型(也就三种,void,integer,boolean)。定义了树的节点--这个最重要了!!其结构如下所示:typedefstructtreeNode{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主要有这么几个函数:专业整理word格式文档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构造语法树(调用parse函数)->根据语法树生成代码(调用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专业整理word格式文档/*setNO_CODEtoTRUEtogetacompilerthatdoesnot*generatecodeNO_CODE为true时创建一个执行语义分析,但不生成代码的编译器*/#defineNO_CODEFALSE#include"util.h"#ifNO_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//结束预处理语句符号/*allocateglobalvariables分配全局变量*/intlineno=0;FILE*source;//指针指向源代码文件地址FILE*listing;//指针指向显示分析过程的文件的地址FILE*code;//指针指向目标汇编代码文件的地址/*allocateandsettracingflags分配和设置跟踪标志*/intEchoSource=FALSE;intTraceScan=FALSE;intTraceParse=FALSE;intTraceAnalyze=FALSE;intTraceCode=FALSE;intError=FALSE;//跟踪标志全部初始化为falsemain(intargc,char*argv[]){TreeNode*syntaxTree;charpgm[120];/*sourcecodefilename*/if(argc!=2){fprintf(stderr,"usage:%s\n",argv[0]);exit(1);//如果argv不为2,打印显示信息并退出}strcpy(pgm,argv[1]);//复制argv[1]地址以null为退出字符的存储器区块到另一个存储器区块品pgm内if(strchr(pgm,'.')==NULL)专业整理word格式文档strcat(pgm,".tny");//把.tyn文件所指字符串添加到pgm结尾处并添加'\0'。source=fopen(pgm,"r");//以只读的方式打开pgm文件,并将指向pgm文件的指针返回给sourceif(source==NULL){fprintf(stderr,"File%snotfound\n",pgm);exit(1);//如果源代码文件为空,打印显示信息并退出}listing=stdout;/*sendlistingtoscreen清单发送到屏幕*/fprintf(listing,"\nTINYCOMPILATION:%s\n",pgm);//答应显示语句#ifNO_PARSEwhile(getToken()!=ENDFILE);//如果输入流没有结束就继续进行循环,直至结束#elsesyntaxTree=parse();//调用prase()函数构造语法树if(TraceParse){fprintf(listing,"\nSyntaxtree:\n");printTree(syntaxTree);//如果语法分析追踪标志为TRUE且没有语法错误,则将生成的语法树输出到屏幕}#if!NO_ANALYZEif(!Error){if(TraceAnalyze)fprintf(listing,"\nBuildingSymbolTable...\n");buildSymtab(syntaxTree);//输出含符号表信息的语法树if(TraceAnalyze)fprintf(listing,"\nCheckingTypes...\n");typeCheck(syntaxTree);//输出含类型检查的语法树if(TraceAnalyze)fprintf(listing,"\nTypeCheckingFinished\n");//打印结束信息}#if!NO_CODEif(!Error){char*codefile;intfnlen=strcspn(pgm,".");codefile=(char*)calloc(fnlen+4,sizeof(char));strncpy(codefile,pgm,fnlen);strcat(codefile,".tm");//将源文件名,去掉扩展名,添加扩展名.tmcode=fopen(codefile,"w");//以只写的方式打开目标汇编代码文件,并返回地址给codez指针if(code==NULL){printf("Unabletoopen%s\n",codefile);exit(1);//如果code指针为空,打印显示信息并退出}codeGen(syntaxTree,codefile);//目标代码生成fclose(code);}#endif专业整理word格式文档#endif#endif//结束之前对应的条件编译fclose(source);//关闭源代码文件return0;}GLOBALS.H/****************************************************//*File:globals.h*//*GlobaltypesandvarsforTINYcompiler*//*mustcomebeforeotherincludefiles*//*CompilerConstruction:PrinciplesandPractice*//*KennethC.Louden*//****************************************************/#ifndef_GLOBALS_H_#define_GLOBALS_H_//宏定义#include#include#include#include//头文件引用#ifndefFALSE#defineFALSE0//定义FALSE为0#endif#ifndefTRUE#defineTRUE1//定义TRUE为1#endif/*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专业整理word格式文档}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;ExpKindexp;}kind;union{TokenTypeop;intval;char*name;}attr;ExpTypetype;/*fortypecheckingofexps*/}TreeNode;/**************************************************//***********Flagsfortracing************//**************************************************//*EchoSource=TRUEcausesthesourceprogramtobeechoedtothelistingfilewithlinenumbersduringparsing*/externintEchoSource;/*TraceScan=TRUEcausestokeninformationtobe专业整理word格式文档printedtothelistingfileaseachtokenisrecognizedbythescanner*/externintTraceScan;/*TraceParse=TRUEcausesthesyntaxtreetobeprintedtothelistingfileinlinearizedform(usingindentsforchildren)*/externintTraceParse;/*TraceAnalyze=TRUEcausessymboltableinserts*andlookupstobereportedtothelistingfile*/externintTraceAnalyze;/*TraceCode=TRUEcausescommentstobewrittentotheTMcodefileascodeisgenerated*/externintTraceCode;/*Error=TRUEpreventsfurtherpassesifanerroroccurs*/externintError;#endifSCAN.C/*词法扫描程序*/#include"globals.h"#include"util.h"#include"scan.h"/*定义的状态*/typedefenum{START,/*初始状态*/INASSIGN,/*进入到赋值状态*/INCOMMENT,/*进入到注释状态*/INNUM,/*进入到数字状态*/INID,/*进入到标志符状态*/DONE/*状态结束*/}StateType;/*每当语法分析程序需要一个单词时,就调用该子程序,得到(类别码,单词的值)*//*语义标识符和保留字*/chartokenString[MAXTOKENLEN+1];专业整理word格式文档/*BUFLEN=源代码的输入缓冲长度*/#defineBUFLEN256staticcharlineBuf[BUFLEN];/*当前行*/staticintlinepos=0;/*在linebuf中的当前位置*/staticintbufsize=0;/*缓冲区的字符串当前大小*/staticintEOF_flag=FALSE;/*如果读入下一个字符出错,设置EOF_flag为假。*//*从linebuffer中读取下一个非空白字符,如果读完,则读入新行。*/staticintgetNextChar(void){if(!(lineposchild[i]=NULL;t->sibling=NULL;t->nodekind=StmtK;t->kind.stmt=kind;t->lineno=lineno;}returnt;}/*FunctionnewExpNodecreatesanewexpressionnodeforsyntaxtreeconstruction*/TreeNode*newExpNode(ExpKindkind)//此函数创建一个有关此法树的表述节点{TreeNode*t=(TreeNode*)malloc(sizeof(TreeNode));inti;if(t==NULL)fprintf(listing,"Outofmemoryerroratline%d\n",lineno);else{for(i=0;ichild[i]=NULL;t->sibling=NULL;t->nodekind=ExpK;t->kind.exp=kind;t->lineno=lineno;t->type=Void;}returnt;}/*FunctioncopyStringallocatesandmakesanew*copyofanexistingstring*/char*copyString(char*s)//此函数分配和创建一个新的已存在树的复制{intn;char*t;专业整理word格式文档if(s==NULL)returnNULL;n=strlen(s)+1;t=malloc(n);if(t==NULL)fprintf(listing,"Outofmemoryerroratline%d\n",lineno);elsestrcpy(t,s);returnt;}/*VariableindentnoisusedbyprintTreetostorecurrentnumberofspacestoindent*/staticindentno=0;//此变量被函数printTree用来存储要缩进的空格个数/*macrostoincrease/decreaseindentation*/#defineINDENTindentno+=2//这个宏增加缩进空格个数#defineUNINDENTindentno-=2//这个宏减少缩进空格个数/*printSpacesindentsbyprintingspaces*/staticvoidprintSpaces(void)//此函数通过打印空格缩进{inti;for(i=0;inodekind==StmtK){switch(tree->kind.stmt){caseIfK:fprintf(listing,"If\n");break;caseRepeatK:fprintf(listing,"Repeat\n");break;caseAssignK:fprintf(listing,"Assignto:%s\n",tree->attr.name);break;专业整理word格式文档caseReadK:fprintf(listing,"Read:%s\n",tree->attr.name);break;caseWriteK:fprintf(listing,"Write\n");break;default:fprintf(listing,"UnknownExpNodekind\n");break;}}elseif(tree->nodekind==ExpK){switch(tree->kind.exp){caseOpK:fprintf(listing,"Op:");printToken(tree->attr.op,"\0");break;caseConstK:fprintf(listing,"Const:%d\n",tree->attr.val);break;caseIdK:fprintf(listing,"Id:%s\n",tree->attr.name);break;default:fprintf(listing,"UnknownExpNodekind\n");break;}}elsefprintf(listing,"Unknownnodekind\n");for(i=0;ichild[i]);tree=tree->sibling;}UNINDENT;}专业整理
本文档为【TINY部分源码分析报告书】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
个人认证用户
is_916672
暂无简介~
格式:doc
大小:190KB
软件:Word
页数:0
分类:
上传时间:2021-09-26
浏览量:1